From b557a4e4d3c03ebcdba5594bb7a071b3926c8610 Mon Sep 17 00:00:00 2001 From: Gleb Levitski <36483986+glevv@users.noreply.github.com> Date: Sat, 16 Dec 2023 09:29:30 +0200 Subject: [PATCH] added l-skew, l-kurt, changed l-cv, added range coefficient, xi corr refactoring --- CITATION.cff | 2 +- README.md | 2 + pyproject.toml | 2 +- src/obscure_stats/association/__init__.py | 6 +- src/obscure_stats/association/association.py | 39 +++++++++--- .../central_tendency/__init__.py | 6 +- .../central_tendency/central_tendency.py | 10 ++-- src/obscure_stats/dispersion/__init__.py | 6 +- src/obscure_stats/dispersion/dispersion.py | 53 +++++++++++++---- src/obscure_stats/kurtosis/__init__.py | 2 + src/obscure_stats/kurtosis/kurtosis.py | 47 +++++++++++++-- src/obscure_stats/skewness/__init__.py | 6 +- src/obscure_stats/skewness/skewness.py | 59 +++++++++++++++---- tests/test_association.py | 4 +- tests/test_central_tendency.py | 6 +- tests/test_dispersion.py | 17 ++++-- tests/test_kurtosis.py | 14 +++-- tests/test_skewness.py | 15 +++-- tests/test_variation.py | 8 +-- 19 files changed, 229 insertions(+), 75 deletions(-) diff --git a/CITATION.cff b/CITATION.cff index 2a0d0b3..af03f6d 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -18,5 +18,5 @@ repository-code: 'https://github.com/glevv/obscure_stats' repository-artifact: 'https://pypi.org/project/obscure_stats' abstract: Collection of lesser-known statistical measures license: MIT -version: 0.1.6 +version: 0.1.7 date-released: '2023-10-21' \ No newline at end of file diff --git a/README.md b/README.md index 4bef7cf..7aa54a9 100644 --- a/README.md +++ b/README.md @@ -40,11 +40,13 @@ * Groeneveld Skewness Coefficient; * Hossain-Adnan Skewness Coefficient; * Kelly Skewness Coefficient; + * L-Skewness; * Medeen Skewness Coefficient; * Pearson Median Skewness Coefficient; * Pearson Mode Skewness Coefficient. - Collection of measures of kurtosis - `obscure_stats/kurtosis`: * Crow-Siddiqui Kurtosis; + * L-Kurtosis; * Hogg Kurtosis; * Moors Kurtosis; * Moors Octile Kurtosis; diff --git a/pyproject.toml b/pyproject.toml index 200173f..e698837 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "obscure_stats" -version = "0.1.6" +version = "0.1.7" description = "Collection of lesser-known statistical functions" authors = ["Gleb Levitski"] readme = "README.md" diff --git a/src/obscure_stats/association/__init__.py b/src/obscure_stats/association/__init__.py index e095417..6deb2a9 100644 --- a/src/obscure_stats/association/__init__.py +++ b/src/obscure_stats/association/__init__.py @@ -10,10 +10,10 @@ ) __all__ = [ + "chatterjeexi", "concordance_corrcoef", "concordance_rate", - "chatterjeexi", - "zhangi", - "tanimoto_similarity", "symmetric_chatterjeexi", + "tanimoto_similarity", + "zhangi", ] diff --git a/src/obscure_stats/association/association.py b/src/obscure_stats/association/association.py index 6cf78d8..3233735 100644 --- a/src/obscure_stats/association/association.py +++ b/src/obscure_stats/association/association.py @@ -95,14 +95,15 @@ def chatterjeexi(x: np.ndarray, y: np.ndarray) -> float: if _check_arrays(x, y): return np.nan x, y = _prep_arrays(x, y) + # heavily inspired by https://github.com/czbiohub-sf/xicor/issues/17#issue-965635013 n = len(x) - x_ranked = stats.rankdata(x, method="ordinal") - y_forward_ranked = stats.rankdata(y, method="max") - y_backward_ranked = stats.rankdata(-y, method="max") - y_forward_ranked_ordered = y_forward_ranked[np.argsort(x_ranked)] - nom = np.sum(np.abs(np.diff(y_forward_ranked_ordered))) - denom = np.sum(y_backward_ranked * (n - y_backward_ranked)) / n**3 - return 1.0 - nom / (2 * n**2 * denom) + y_forward_ordered = y[np.argsort(x)] + _, y_unique_indexes, y_counts = np.unique( + y_forward_ordered, return_inverse=True, return_counts=True + ) + right = np.cumsum(y_counts)[y_unique_indexes] + left = np.cumsum(y_counts[::-1])[len(y_counts) - y_unique_indexes - 1] + return 1.0 - 0.5 * np.sum(np.abs(np.diff(right))) / np.mean(left * (n - left)) def concordance_corrcoef(x: np.ndarray, y: np.ndarray) -> float: @@ -231,7 +232,29 @@ def symmetric_chatterjeexi(x: np.ndarray, y: np.ndarray) -> float: -------- obscure_stats.associaton.chatterjeexi - Chatterjee Xi coefficient. """ - return max(chatterjeexi(x, y), chatterjeexi(y, x)) + if _check_arrays(x, y): + return np.nan + x, y = _prep_arrays(x, y) + n = len(x) + # y ~ f(x) + y_forward_ordered = y[np.argsort(x)] + _, y_unique_indexes, y_counts = np.unique( + y_forward_ordered, return_inverse=True, return_counts=True + ) + right_xy = np.cumsum(y_counts)[y_unique_indexes] + left_xy = np.cumsum(y_counts[::-1])[len(y_counts) - y_unique_indexes - 1] + # x ~ f(y) + x_forward_ordered = x[np.argsort(y)] + _, x_unique_indexes, x_counts = np.unique( + x_forward_ordered, return_inverse=True, return_counts=True + ) + right_yx = np.cumsum(x_counts)[x_unique_indexes] + left_yx = np.cumsum(x_counts[::-1])[len(x_counts) - x_unique_indexes - 1] + # choose the highest from the two + return 1.0 - min( + 0.5 * np.sum(np.abs(np.diff(right_xy))) / np.mean(left_xy * (n - left_xy)), + 0.5 * np.sum(np.abs(np.diff(right_yx))) / np.mean(left_yx * (n - left_yx)), + ) def zhangi(x: np.ndarray, y: np.ndarray) -> float: diff --git a/src/obscure_stats/central_tendency/__init__.py b/src/obscure_stats/central_tendency/__init__.py index cacb22d..52334fc 100644 --- a/src/obscure_stats/central_tendency/__init__.py +++ b/src/obscure_stats/central_tendency/__init__.py @@ -13,11 +13,11 @@ __all__ = [ "contraharmonic_mean", + "half_sample_mode", + "hodges_lehmann_sen_location", "midhinge", "midmean", "midrange", - "trimean", - "hodges_lehmann_sen_location", "standard_trimmed_harrell_davis_quantile", - "half_sample_mode", + "trimean", ] diff --git a/src/obscure_stats/central_tendency/central_tendency.py b/src/obscure_stats/central_tendency/central_tendency.py index 1cd29f0..b40eed3 100644 --- a/src/obscure_stats/central_tendency/central_tendency.py +++ b/src/obscure_stats/central_tendency/central_tendency.py @@ -18,7 +18,7 @@ def midrange(x: np.ndarray) -> float: Returns ------- - mr : float or array_like. + mr : float The value of the midrange. References @@ -44,7 +44,7 @@ def midhinge(x: np.ndarray) -> float: Returns ------- - mh : float or array_like. + mh : float The value of the midhinge. References @@ -69,7 +69,7 @@ def trimean(x: np.ndarray) -> float: Returns ------- - tm : float or array_like. + tm : float The value of the trimean. References @@ -96,7 +96,7 @@ def contraharmonic_mean(x: np.ndarray) -> float: Returns ------- - chm : float or array_like. + chm : float The value of the contraharmonic mean. References @@ -120,7 +120,7 @@ def midmean(x: np.ndarray) -> float: Returns ------- - iqm : float or array_like. + iqm : float The value of the interquartile mean. References diff --git a/src/obscure_stats/dispersion/__init__.py b/src/obscure_stats/dispersion/__init__.py index 6eb2476..7be4369 100644 --- a/src/obscure_stats/dispersion/__init__.py +++ b/src/obscure_stats/dispersion/__init__.py @@ -2,6 +2,7 @@ from .dispersion import ( coefficient_of_lvariation, + coefficient_of_range, coefficient_of_variation, dispersion_ratio, lloyds_index, @@ -15,13 +16,14 @@ __all__ = [ "coefficient_of_lvariation", + "coefficient_of_range", "coefficient_of_variation", "dispersion_ratio", "lloyds_index", "morisita_index", "quartile_coefficient_of_dispersion", - "standard_quantile_absolute_deviation", - "studentized_range", "robust_coefficient_of_variation", "shamos_estimator", + "standard_quantile_absolute_deviation", + "studentized_range", ] diff --git a/src/obscure_stats/dispersion/dispersion.py b/src/obscure_stats/dispersion/dispersion.py index fd9df6e..c81891c 100644 --- a/src/obscure_stats/dispersion/dispersion.py +++ b/src/obscure_stats/dispersion/dispersion.py @@ -3,7 +3,7 @@ import warnings import numpy as np -from scipy import stats # type: ignore[import-untyped] +from scipy import special, stats # type: ignore[import-untyped] EPS = 1e-6 @@ -18,7 +18,7 @@ def studentized_range(x: np.ndarray) -> float: Returns ------- - sr : float or array_like. + sr : float The value of the studentized range. References @@ -46,7 +46,7 @@ def coefficient_of_lvariation(x: np.ndarray) -> float: Returns ------- - lcv : float or array_like. + lcv : float The value of the linear coefficient of variation. References @@ -60,7 +60,11 @@ def coefficient_of_lvariation(x: np.ndarray) -> float: if abs(l1) <= EPS: warnings.warn("Mean is close to 0. Statistic is undefined.", stacklevel=2) return np.inf - l2 = np.nanmean(np.abs(x - l1)) * 0.5 + n = len(x) + _x = np.sort(x) + common = 1 / special.comb(n - 1, 1) / n + beta_1 = common * np.nansum(special.comb(np.arange(1, n), 1) * _x[1:]) + l2 = 2 * beta_1 - l1 return l2 / l1 @@ -74,7 +78,7 @@ def coefficient_of_variation(x: np.ndarray) -> float: Returns ------- - cv : float or array_like. + cv : float The value of the coefficient of variation. References @@ -103,7 +107,7 @@ def robust_coefficient_of_variation(x: np.ndarray) -> float: Returns ------- - rcv : float or array_like. + rcv : float The value of the robust coefficient of variation. References @@ -130,7 +134,7 @@ def quartile_coefficient_of_dispersion(x: np.ndarray) -> float: Returns ------- - qcd : float or array_like. + qcd : float The value of the quartile coefficient of dispersion. References @@ -161,7 +165,7 @@ def dispersion_ratio(x: np.ndarray) -> float: Returns ------- - dr : float or array_like. + dr : float The value of the dispersion ratio. References @@ -189,7 +193,7 @@ def lloyds_index(x: np.ndarray) -> float: Returns ------- - li : float or array_like. + li : float The value of the Lloyd's index. References @@ -216,7 +220,7 @@ def morisita_index(x: np.ndarray) -> float: Returns ------- - mi : float or array_like. + mi : float The value of the Morisita's index. References @@ -242,7 +246,7 @@ def standard_quantile_absolute_deviation(x: np.ndarray) -> float: Returns ------- - sqad : float or array_like. + sqad : float The value of the SQAD. References @@ -294,3 +298,30 @@ def shamos_estimator(x: np.ndarray) -> float: # whole matrix, which is equvalent. product = np.meshgrid(x, x, sparse=True) return np.nanmedian(np.abs(product[0] - product[1])) + + +def coefficient_of_range(x: np.ndarray) -> float: + """Calculate coefficient of range (Range / Midrange). + + Parameters + ---------- + x : array_like + Input array. + + Returns + ------- + cr : float + The value of the linear coefficient of variation. + + References + ---------- + Yadav, S. K., Singh, S., & Gupta, R. (2019). + Measures of Dispersion. + In Biomedical Statistics (pp. 59-70). Springer, Singapore + """ + min_ = np.nanmin(x) + max_ = np.nanmax(x) + if abs(min_ + max_) <= EPS: + warnings.warn("Midrange is close to 0. Statistic is undefined.", stacklevel=2) + return np.inf + return (max_ - min_) / (max_ + min_) diff --git a/src/obscure_stats/kurtosis/__init__.py b/src/obscure_stats/kurtosis/__init__.py index 0df7b5d..c60fbe4 100644 --- a/src/obscure_stats/kurtosis/__init__.py +++ b/src/obscure_stats/kurtosis/__init__.py @@ -3,6 +3,7 @@ from .kurtosis import ( crow_siddiqui_kurt, hogg_kurt, + l_kurt, moors_kurt, moors_octile_kurt, reza_ma_kurt, @@ -14,4 +15,5 @@ "moors_kurt", "moors_octile_kurt", "reza_ma_kurt", + "l_kurt", ] diff --git a/src/obscure_stats/kurtosis/kurtosis.py b/src/obscure_stats/kurtosis/kurtosis.py index 6347573..56c789b 100644 --- a/src/obscure_stats/kurtosis/kurtosis.py +++ b/src/obscure_stats/kurtosis/kurtosis.py @@ -2,7 +2,42 @@ import numpy as np -from scipy import stats # type: ignore[import-untyped] +from scipy import special, stats # type: ignore[import-untyped] + + +def l_kurt(x: np.ndarray) -> float: + """Calculate standardized linear kurtosis. + + This measure is a 4th linear moment, which is an + alternative to conventional moments. + + Parameters + ---------- + x : array_like + Input array. + + Returns + ------- + lkr : float + The value of L-Kurtosis. + + References + ---------- + Hosking, J. R. M. (1990). + L-moments: analysis and estimation of distributions + using linear combinations of order statistics. + Journal of the Royal Statistical Society, Series B. 52 (1): 105-124. + """ + n = len(x) + _x = np.sort(x) + common = 1 / special.comb(n - 1, (0, 1, 2, 4)) / n + betas = [ + common[i] * np.nansum(special.comb(np.arange(i, n), i) * _x[i:]) + for i in range(4) + ] + l4 = 20 * betas[3] - 30 * betas[2] + 12 * betas[1] - betas[0] + l2 = 2 * betas[1] - betas[0] + return l4 / l2 def moors_kurt(x: np.ndarray) -> float: @@ -20,7 +55,7 @@ def moors_kurt(x: np.ndarray) -> float: Returns ------- - mk : float or array_like. + mk : float The value of Moor's kurtosis. References @@ -44,7 +79,7 @@ def moors_octile_kurt(x: np.ndarray) -> float: Returns ------- - mok : float or array_like. + mok : float The value of Moor's octile kurtosis. References @@ -73,7 +108,7 @@ def hogg_kurt(x: np.ndarray) -> float: Returns ------- - hgc : float or array_like. + hgc : float The value of Hogg's kurtosis coefficient. References @@ -107,7 +142,7 @@ def crow_siddiqui_kurt(x: np.ndarray) -> float: Returns ------- - csk : float or array_like. + csk : float The value of Crow & Siddiqui kurtosis coefficient. References @@ -134,7 +169,7 @@ def reza_ma_kurt(x: np.ndarray) -> float: Returns ------- - rmk : float or array_like. + rmk : float The value of Reza & Ma kurtosis coefficient. References diff --git a/src/obscure_stats/skewness/__init__.py b/src/obscure_stats/skewness/__init__.py index c0660d6..b98c92f 100644 --- a/src/obscure_stats/skewness/__init__.py +++ b/src/obscure_stats/skewness/__init__.py @@ -8,6 +8,7 @@ groeneveld_skew, hossain_adnan_skew, kelly_skew, + l_skew, medeen_skew, pearson_median_skew, pearson_mode_skew, @@ -16,14 +17,15 @@ __all__ = [ "auc_skew_gamma", - "wauc_skew_gamma", + "bickel_mode_skew", "bowley_skew", "forhad_shorna_rank_skew", "groeneveld_skew", "hossain_adnan_skew", "kelly_skew", + "l_skew", "medeen_skew", "pearson_median_skew", "pearson_mode_skew", - "bickel_mode_skew", + "wauc_skew_gamma", ] diff --git a/src/obscure_stats/skewness/skewness.py b/src/obscure_stats/skewness/skewness.py index a9797c2..bbffdde 100644 --- a/src/obscure_stats/skewness/skewness.py +++ b/src/obscure_stats/skewness/skewness.py @@ -3,11 +3,46 @@ from __future__ import annotations import numpy as np -from scipy import stats # type: ignore[import-untyped] +from scipy import special, stats # type: ignore[import-untyped] from obscure_stats.central_tendency import half_sample_mode +def l_skew(x: np.ndarray) -> float: + """Calculate standardized linear skewness. + + This measure is a 3rd linear moment, which is an + alternative to conventional moments. + + Parameters + ---------- + x : array_like + Input array. + + Returns + ------- + lsk : float. + The value of L-Skewness. + + References + ---------- + Hosking, J. R. M. (1990). + L-moments: analysis and estimation of distributions + using linear combinations of order statistics. + Journal of the Royal Statistical Society, Series B. 52 (1): 105-124. + """ + n = len(x) + _x = np.sort(x) + common = 1 / special.comb(n - 1, (0, 1, 2)) / n + betas = [ + common[i] * np.nansum(special.comb(np.arange(i, n), i) * _x[i:]) + for i in range(3) + ] + l3 = 6 * betas[2] - 6 * betas[1] + betas[0] + l2 = 2 * betas[1] - betas[0] + return l3 / l2 + + def pearson_mode_skew(x: np.ndarray) -> float: """Calculate Pearson's mode skew coefficient. @@ -20,7 +55,7 @@ def pearson_mode_skew(x: np.ndarray) -> float: Returns ------- - pmods : float or array_like. + pmods : float The value of Pearson's mode skew coefficient. References @@ -48,7 +83,7 @@ def bickel_mode_skew(x: np.ndarray) -> float: Returns ------- - phmods : float or array_like. + phmods : float The value of Bickel's mode skew coefficient. References @@ -71,7 +106,7 @@ def pearson_median_skew(x: np.ndarray) -> float: Returns ------- - pmeds : float or array_like. + pmeds : float The value of Pearson's median skew coefficient. References @@ -100,7 +135,7 @@ def medeen_skew(x: np.ndarray) -> float: Returns ------- - mss : float or array_like. + mss : float The value of Medeen's skewness statistic. References @@ -129,7 +164,7 @@ def bowley_skew(x: np.ndarray) -> float: Returns ------- - bsk : float or array_like. + bsk : float The value of Bowley's skewness coefficinet. References @@ -157,7 +192,7 @@ def groeneveld_skew(x: np.ndarray) -> float: Returns ------- - bsk : float or array_like. + bsk : float The value of Groeneveld's skewness coefficinet. References @@ -187,7 +222,7 @@ def kelly_skew(x: np.ndarray) -> float: Returns ------- - ksc : float or array_like. + ksc : float The value of Kelly's skewness coefficinet. References @@ -214,7 +249,7 @@ def hossain_adnan_skew(x: np.ndarray) -> float: Returns ------- - has : float or array_like. + has : float The value of Houssain and Adnan skewness coefficient. References @@ -241,7 +276,7 @@ def forhad_shorna_rank_skew(x: np.ndarray) -> float: Returns ------- - fsrs : float or array_like. + fsrs : float The value of Forhad-Shorna coefficient of Rank Skewness. References @@ -287,7 +322,7 @@ def auc_skew_gamma(x: np.ndarray, dp: float = 0.01) -> float: Returns ------- - aucbs : float or array_like. + aucbs : float The value of AUC Bowley skewness. References @@ -316,7 +351,7 @@ def wauc_skew_gamma(x: np.ndarray, dp: float = 0.01) -> float: Returns ------- - aucbs : float or array_like. + aucbs : float The value of AUC Bowley skewness. References diff --git a/tests/test_association.py b/tests/test_association.py index 472cfd8..2bad367 100644 --- a/tests/test_association.py +++ b/tests/test_association.py @@ -14,12 +14,12 @@ ) all_functions = [ - zhangi, chatterjeexi, concordance_corrcoef, concordance_rate, - tanimoto_similarity, symmetric_chatterjeexi, + tanimoto_similarity, + zhangi, ] diff --git a/tests/test_central_tendency.py b/tests/test_central_tendency.py index dafde1c..37c04ef 100644 --- a/tests/test_central_tendency.py +++ b/tests/test_central_tendency.py @@ -19,13 +19,13 @@ all_functions = [ contraharmonic_mean, + half_sample_mode, + hodges_lehmann_sen_location, midhinge, midmean, midrange, - trimean, - hodges_lehmann_sen_location, standard_trimmed_harrell_davis_quantile, - half_sample_mode, + trimean, ] diff --git a/tests/test_dispersion.py b/tests/test_dispersion.py index b9926a2..a6a1c7e 100644 --- a/tests/test_dispersion.py +++ b/tests/test_dispersion.py @@ -6,6 +6,7 @@ import pytest from obscure_stats.dispersion import ( coefficient_of_lvariation, + coefficient_of_range, coefficient_of_variation, dispersion_ratio, lloyds_index, @@ -19,15 +20,16 @@ all_functions = [ coefficient_of_lvariation, + coefficient_of_range, coefficient_of_variation, - robust_coefficient_of_variation, dispersion_ratio, lloyds_index, morisita_index, quartile_coefficient_of_dispersion, + robust_coefficient_of_variation, + shamos_estimator, standard_quantile_absolute_deviation, studentized_range, - shamos_estimator, ] @@ -61,6 +63,7 @@ def test_mock_aggregation_functions( quartile_coefficient_of_dispersion, standard_quantile_absolute_deviation, shamos_estimator, + coefficient_of_range, ], ) @pytest.mark.parametrize("seed", [1, 42, 99]) @@ -69,8 +72,13 @@ def test_dispersion_sensibility(func: typing.Callable, seed: int) -> None: rng = np.random.default_rng(seed) low_disp = np.round(rng.exponential(scale=1, size=100) + 1, 2) high_disp = np.round(rng.exponential(scale=10, size=100) + 1, 2) - if func(low_disp) > func(high_disp): - msg = "Dispersion in the first case should be lower." + low_disp_res = func(low_disp) + high_disp_res = func(high_disp) + if low_disp_res > high_disp_res: + msg = ( + f"Dispersion in the first case should be lower, " + f"got {low_disp_res} > {high_disp_res}" + ) raise ValueError(msg) @@ -81,6 +89,7 @@ def test_dispersion_sensibility(func: typing.Callable, seed: int) -> None: coefficient_of_variation, robust_coefficient_of_variation, quartile_coefficient_of_dispersion, + coefficient_of_range, ], ) def test_cv_corner_cases(func: typing.Callable) -> None: diff --git a/tests/test_kurtosis.py b/tests/test_kurtosis.py index fe28d53..fe8d867 100644 --- a/tests/test_kurtosis.py +++ b/tests/test_kurtosis.py @@ -7,16 +7,18 @@ from obscure_stats.kurtosis import ( crow_siddiqui_kurt, hogg_kurt, + l_kurt, moors_kurt, moors_octile_kurt, reza_ma_kurt, ) all_functions = [ + crow_siddiqui_kurt, + hogg_kurt, + l_kurt, moors_kurt, moors_octile_kurt, - hogg_kurt, - crow_siddiqui_kurt, reza_ma_kurt, ] @@ -49,8 +51,12 @@ def test_kurt_sensibility(func: typing.Callable, seed: int) -> None: rng = np.random.default_rng(seed) platy = np.round(rng.uniform(size=100), 2) lepto = np.round(rng.exponential(size=100), 2) - if func(platy) > func(lepto): - msg = "Kurtosis in the first case should be lower." + platy_res = func(platy) + lepto_res = func(lepto) + if platy_res > lepto_res: + msg = ( + f"Kurtosis in the first case should be lower, got {platy_res} > {lepto_res}" + ) raise ValueError(msg) diff --git a/tests/test_skewness.py b/tests/test_skewness.py index 6acd819..7df7eee 100644 --- a/tests/test_skewness.py +++ b/tests/test_skewness.py @@ -12,6 +12,7 @@ groeneveld_skew, hossain_adnan_skew, kelly_skew, + l_skew, medeen_skew, pearson_median_skew, pearson_mode_skew, @@ -20,16 +21,17 @@ all_functions = [ auc_skew_gamma, - wauc_skew_gamma, + bickel_mode_skew, bowley_skew, forhad_shorna_rank_skew, groeneveld_skew, hossain_adnan_skew, kelly_skew, + l_skew, medeen_skew, pearson_median_skew, pearson_mode_skew, - bickel_mode_skew, + wauc_skew_gamma, ] @@ -61,8 +63,13 @@ def test_skew_sensibility(func: typing.Callable, seed: int) -> None: rng = np.random.default_rng(seed) no_skew = np.round(rng.normal(size=100), 2) left_skew = np.round(rng.exponential(size=100) + 1, 2) - if func(no_skew) > func(left_skew): - msg = "Skewness in the first case should be lower." + no_skew_res = func(no_skew) + left_skew_res = func(left_skew) + if no_skew_res > left_skew_res: + msg = ( + f"Skewness in the first case should be lower, " + f"got {no_skew_res} > {left_skew_res}" + ) raise ValueError(msg) diff --git a/tests/test_variation.py b/tests/test_variation.py index 91580b9..496cb90 100644 --- a/tests/test_variation.py +++ b/tests/test_variation.py @@ -50,10 +50,10 @@ def test_var_sensibility_higher_better(func: typing.Callable, seed: int) -> None rng = np.random.default_rng(seed) low_var = rng.choice(["a", "b", "c", "d"], p=[0.25, 0.25, 0.25, 0.25], size=100) high_var = rng.choice(["a", "b", "c", "d"], p=[0.75, 0.15, 0.05, 0.05], size=100) - low_res = func(low_var) - high_res = func(high_var) - if low_res < high_res: - msg = f"Statistic value should be higher, got {low_res} < {high_res}" + low_var_res = func(low_var) + high_var_res = func(high_var) + if low_var_res < high_var_res: + msg = f"Statistic value should be higher, got {low_var_res} < {high_var_res}" raise ValueError(msg)