Статистика Хи-квадрат
Применяю Хи-квадрат критерий, проверяю гипотезу о выборке из биномиального распределения с параметрами [21, 0.9].
from statsmodels.stats import gof
from scipy import stats
P0_VALUE = 0.05
xs = [19, 20, 20, 19, 20, 20, 19, 20, 20, 19, 18, 19, 21, 20, 19,
19, 19, 21, 20, 19, 19, 20, 18, 20, 20, 16, 20, 17, 19, 19, 20, 19,
20, 19, 20, 20, 21, 20, 21, 21, 19, 19, 20, 18, 20, 20, 21, 17, 18, 19]
res_chi_test = gof.gof_chisquare_discrete(stats.distributions.binom,
arg=[21, 0.9], rvs=xs,
alpha=P0_VALUE, msg="Binomial ")
print(res_chi_test)
Результат:
RuntimeWarning: invalid value encountered in true_divide terms = (f_obs_float - f_exp)**2 / f_exp
(nan, nan, False, 'chisquare - test for Binomial at arg = [21, 0.9] with pval = nan')
Т.е., видимо, где-то внутри происходит деление на "ноль" [скорее всего, из-за неоптимального выделения интервалов].
Вспоминаю, что Bin[n, p] эквивалентно n - Bin[n, 1-p], изменяю выборку, меняю параметр 0.9 на 0.1, запускаю:
xs = [2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 3, 2, 0, 1, 2, 2, 2, 0, 1, 2,
2, 1, 3, 1, 1, 5, 1, 4, 2, 2, 1, 2, 1, 2, 1, 1, 0, 1, 0, 0, 2, 2,
1, 3, 1, 1, 0, 4, 3, 2]
res_chi_test = gof.gof_chisquare_discrete(stats.distributions.binom,
arg=[21, 0.1], rvs=xs,
alpha=P0_VALUE, msg="Binomial ")
print(res_chi_test)
Чудо(?)
(11.082247965399947, 0.0858674790344855, True, 'chisquare - test for Binomial at arg = [21, 0.1] with pval = 0.0858674790344855')
- Почему все же так происходит?
- Как этого избежать [не считая вариант самостоятельной реализации]?
Ответы (2 шт):
Хотите именно ХИ-2 тест - придется строить вручную.
Можно задействовать тест Колмогорова-Смирнова:
stats.kstest(xs, "binom", (21, 0.9))
Его результат неутешителен:
KstestResult(statistic=0.4952700362282919, pvalue=7.51602278864889e-12)
т.е. считать ваши данные распределенными по биноминальному закону не приходится.
Впрочем, это и неудивительно, с оглядкой на их гистограмму.

Итак, спустя некоторое время я нашел разгадку.
Объект stats.distributions.binom по умолчанию определяет максимальное значение, принимаемое моделируемой СВ, как inf. При этом внутри gof_chisquare_discrete() максимальное значение определяется именно у передаваемого объекта [который в моем случае обладал значениями параметров по умолчанию], а сами параметры распределения при этом не учитываются. Из-за этого возникает лишний интервал [n;inf) с вероятностью попадания 0. Потому в слагаемом, соответствующем этому интервалу, и возникает деление на 0.
Решение проблемы - передавать объект с конкретным набором параметров распределения, а в качестве args - []:
res_chi_test = gof.gof_chisquare_discrete(stats.distributions.binom(21,0.9),
arg=[], rvs=xs,
alpha=P0_VALUE, msg="Binomial ")
Результат:
(11.077689191629469, 0.04986120886306524, False, 'chisquare - test for Binomial at arg = [] with pval = 0.04986120886306524')