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}