Metrics
Directional consistency index (DCI)
- _dci.dci(self) float
Directional consistency index (DCI)
Returns
- dc_indexfloat
Directional consistency index (DCI) of the given interaction matrix (rounded to 4 decimal places)
Notes
It is the proportion of occurrences of a behaviour from high frequency to low frequency (H -> L) for all pairs in a group. It is averaged out using (H-L)/(H+L)=DCI. The domain is 0 to 1 meaning no directional asymmetry to complete unidirectional respectively.
References
Van Hooff JARAM, Wensing JAB. 1987. Dominance and its behavioural measures in a captive wolf pack. In: Frank HW,
editor. Man and Wolf. Dordrecht, Olanda (Netherlands): Junk Publishers pp.219-252.
Example:
1mat = np.array([[0, 6, 1, 4, 6, 8, 5],
2 [5, 0, 5, 0, 0, 2, 1],
3 [0, 0, 0, 0, 0, 0, 0],
4 [0, 0, 0, 0, 0, 0, 0],
5 [2, 0, 0, 2, 0, 1, 0],
6 [1, 15, 1, 0, 11, 0, 1],
7 [4, 2, 0, 0, 0, 0, 0]], dtype='float32')
8
9hier_mat = Hierarchia(mat, np.arange(0, mat.shape[0]))
10dci = hier_mat.dci()
11print(dci)
Result:
0.6145
Landau h & h’
- _landau_h.landau_h(self, improved: bool = True, n_random: int = 10000) dict
Function to calculate Landau h, improved Landau h (h’) and statistical tests of linearity
Parameters
- param improved:
bool The improved version of the Landau h (h’). Form ore details see de Vries (1998).
- param n_random:
int If improved version is calculated, it is the parameter to determine number of random matrices to calculate h’ and corresponding p-values.
Returns
- resultsdict
The result dictionary depends on the argument <improved>, the original version (improved=False) return a dictionary with single key named ‘Landau_h’. If the improved version is asked (improved=True), the improved version of the Landau h (h’) is returned with right and left p-values.
References
Landau, H. G. 1951a. On dominance relations and the structure of animal societies. I: effect of inherent
characteristics. Bull. Math. Biophys., 13, 1-19 * de Vries, H.1995. An improved test of linearity in dominance hierarchies containing unknown or tied relationships. Animal Behaviour, 50,1375e1389.
Example:
1mat = np.array([[0, 3, 10],
2 [2, 0, 1],
3 [0, 1, 0]], dtype='float32')
4
5hier_mat = Hierarchia(mat, np.arange(0, mat.shape[0]))
6landau_h = hier_mat.landau_h(improved=False)
7print(landau_h)
Result:
{'Landau_h': 0.75}
Example:
1mat = np.array([[0, 6, 1, 4, 6, 8, 5],
2 [5, 0, 5, 0, 0, 2, 1],
3 [0, 0, 0, 0, 0, 0, 0],
4 [0, 0, 0, 0, 0, 0, 0],
5 [2, 0, 0, 2, 0, 1, 0],
6 [1, 15, 1, 0, 11, 0, 1],
7 [4, 2, 0, 0, 0, 0, 0]], dtype='float32')
8
9hier_mat = Hierarchia(mat, np.arange(0, mat.shape[0]))
10improved_landau_h = hier_mat.landau_h(improved=True, n_random=10000)
11print(improved_landau_h)
Result:
{'Improved_Landau_h': 0.7138,
'p_value_r': 0.0582,
'p_value_l': 0.9418}
Circular dyads (d) & Kendall K
- _kendall_k.kendall_k(self, odd_K: bool = False) dict
Function to calculate of circular dyads (d), Kendall K (coefficient K) and statistical tests of linearity
Parameters
- param odd_K:
bool Parameter to use odd N formula irrespective of the actual number of animals. For details see notes. (False)
Returns
- resultsdict
The result dictionary depends on the number of individuals in the group. For N < 10, the Chi-square estimation cannot be used so that ECDF is calculated. The result dictionary contains unbiased d, unbiased p-value (ECDF),
coefficient K and unbiased coefficient K. If N >= 10 then the result dictionary contains chi-square statistic, degree of freedom and p-value (chi-square) else these are equal to None. (rounded to 4 decimal places)
See also
https://en.wikipedia.org/wiki/Empirical_distribution_function https://en.wikipedia.org/wiki/Chi-squared_test https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.chi2.html
Notes
1) de Vries (1995) argues that “However, evidently, Kendall’s K (for N odd) is identical to Landau’s h; therefore one could just as well say that, if ties are admitted the formula of Kendall’s K (for N odd) should be used in all cases, irrespective of the number of individuals.” (de Vries, 1995) 2) Appleby (1983) provided a table of selected values of d adapted from (Kendall 1962) yet, the table is not complete for N < 10 which makes it difficult to test the linearity for small groups. We calculate empirical CDF for estimate the p-value for groups N < 10. The estimates are tested against the provided table in the paper and found to be very accurate.
References
Appleby, Michael C. 1983. “The Probability of Linearity in Hierarchies.” Animal Behaviour 31: 600–608. https:
doi.org/10.1016/S0003-3472(83)80084-0. * de Vries, H.1995. An improved test of linearity in dominance hierarchies containing unknown or tied relationships. Animal Behaviour, 50,1375e1389.
Example:
1mat = np.array([[0, 6, 1, 4, 6, 8, 5],
2 [5, 0, 5, 0, 0, 2, 1],
3 [0, 0, 0, 0, 0, 0, 0],
4 [0, 0, 0, 0, 0, 0, 0],
5 [2, 0, 0, 2, 0, 1, 0],
6 [1, 15, 1, 0, 11, 0, 1],
7 [4, 2, 0, 0, 0, 0, 0]], dtype='float32')
8
9hier_mat = Hierarchia(mat, np.arange(0, mat.shape[0]))
10kendall_k = hier_mat.kendall_k(odd_K=False)
11print(kendall_k)
Result:
Computing, 256 possible matrices for unknown relationships...
{'d': 6.0,
'ecdf_p_value': 0.196,
'chi_sq': None,
'df': None,
'chi_sq_p_value': None,
'unbiased_d': 4.0,
'unbiased_p_ecdf': 0.0948,
'K': 0.5714,
'unbiased_K': 0.7143}
Steepness measure
- _steepness.get_steepness(self, method: str = 'Dij') float
Function to get steepness measure from the dominance matrix
Parameters
- param method:
str Valid arguments are ‘Dij’ and ‘Pij’. The method stands for the initial matrix state, the ‘Dij’ method use the corrected version for chance for dyadic dominance index (ref. de Vries (2006)). The ‘Pij’ method use the proportion of wins to compute David’s Scores (Dij)
Returns
- steepnessfloat
Steepness measure from the dominance matrix (rounded to 4 decimal places)
See also
https://numpy.org/doc/stable/reference/generated/numpy.linalg.lstsq.html
Notes
When the animals, ranked from the highest rank 1 to the lowest rank N in the rank order found by NormDS, are put on the X axis, and are given the normalized DS values on the Y axis, ordinary least-squares linear regression can be used to find the best-fitting straight line. We propose to use the absolute value of the slope of this line as a measure of steepness of the dominance hierarchy. In general, the steepness can vary between 0 and 1 when the normalized DS is used. When there is perfect linearity in the set of dominance relationships and when all proportions of wins Pij are 1, the slope equals -1, and steepness is thus at its maximum 1. (de Vries, 2006)
References
David, H. A. 1987. Ranking from unbalanced paired-comparison data. Biometrika, 74, 432–436.
de Vries H, Stevens JMG, Vervaecke H (2006). “Measuring and testing the steepness of dominance hierarchies.” Animal Behaviour, 71, 585-592. doi: 10.1016/j.anbehav.2005.05.015.
Example:
1mat = np.array([[0, 58, 50, 61, 32, 37, 29, 39, 25],
2 [8, 0, 22, 22, 9, 27, 20, 10, 48],
3 [3, 3, 0, 19, 29, 12, 13, 19, 8],
4 [5, 8, 9, 0, 33, 38, 35, 32, 57],
5 [4, 7, 9, 1, 0, 28, 26, 16, 23],
6 [4, 3, 0, 0, 6, 0, 7, 6, 12],
7 [2, 0, 4, 1, 4, 4, 0, 5, 3],
8 [0, 2, 1, 1, 5, 8, 3, 0, 10],
9 [3, 1, 3, 0, 0, 4, 1, 2, 0]])
10name_arr = np.array(["V", "VS", "B", "FJ", "PR", "VB", "TOR", "MU", "ZV"])
11hier_mat = Hierarchia(mat, name_arr)
12steep_dij = hier_mat.get_steepness(method='Dij')
13print(steep_dij)
Result:
0.7421
Steepness test
- _steepness.steepness_test(self, method: str = 'Dij', n: int = 2000) dict
Function to test steepness measure from randomized dominance matrices
Parameters
- param method:
str Valid arguments are ‘Dij’ and ‘Pij’. The method stands for the initial matrix state, the ‘Dij’ method use the corrected version for chance for dyadic dominance index (ref. de Vries (2006)). The ‘Pij’ method use the proportion of wins to compute David’s Scores (Dij)
- param n:
int Parameter to adjust number of random matrices to use in the test. Higher numbers result in more stable test results. The maximum number is 1,000,000 while as low as 2,000 is good for robust test results. (2000)
Returns
- steepness_test_dictdict
Summary dictionary of test measures calculated from the randomized process (all rounded to 4 decimal places)
See also
https://numpy.org/doc/stable/reference/generated/numpy.tile.html https://numpy.org/doc/stable/reference/generated/numpy.linalg.lstsq.html https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.describe.html
Notes
The original R implementation is ‘steepness’ package. Our implementation is marginally slower (2.8 times) but it is still less than 5 seconds to get results with n = 1,000,000. If n <= 100,000 the calculations are expected to be less than a second in a modern hardware.
To test whether the observed steepness differs significantly from the steepness to be expected under the null hypothesis of random win chances for all pairs of individuals we can use the following randomization test procedure. Generate for each and every dyad (i,j ) a random number of wins r for individual i by randomly drawing a number from the integers 0, 1, 2 … nij. Then nij - r will be the number of losses by i from j. Calculate the steepness for the resulting random win–loss matrix. (de Vries, 2006)
References
David, H. A. 1987. Ranking from unbalanced paired-comparison data. Biometrika, 74, 432–436.
de Vries H, Stevens JMG, Vervaecke H (2006). “Measuring and testing the steepness of dominance hierarchies.” Animal Behaviour, 71, 585-592. doi: 10.1016/j.anbehav.2005.05.015.
Example:
1mat = np.array([[0, 58, 50, 61, 32, 37, 29, 39, 25],
2 [8, 0, 22, 22, 9, 27, 20, 10, 48],
3 [3, 3, 0, 19, 29, 12, 13, 19, 8],
4 [5, 8, 9, 0, 33, 38, 35, 32, 57],
5 [4, 7, 9, 1, 0, 28, 26, 16, 23],
6 [4, 3, 0, 0, 6, 0, 7, 6, 12],
7 [2, 0, 4, 1, 4, 4, 0, 5, 3],
8 [0, 2, 1, 1, 5, 8, 3, 0, 10],
9 [3, 1, 3, 0, 0, 4, 1, 2, 0]])
10name_arr = np.array(["V", "VS", "B", "FJ", "PR", "VB", "TOR", "MU", "ZV"])
11hier_mat = Hierarchia(mat, name_arr)
12steep_test = hier_mat.steepness_test(method='Dij', n=9999)
13print(steep_test)
Result:
{'steepness': 0.7421,
'p_value_r': 0.0,
'p_value_l': 1.0,
'mean': 0.2943,
'std_dev': 0.0712,
'variance': 0.0051,
'min': 0.0661,
'max': 0.5756,
'percentile_25': 0.2444,
'percentile_50': 0.2919,
'percentile_75': 0.3416,
'count': 9999}