Статистика Хи-квадрат

Применяю Хи-квадрат критерий, проверяю гипотезу о выборке из биномиального распределения с параметрами [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')
  1. Почему все же так происходит?
  2. Как этого избежать [не считая вариант самостоятельной реализации]?

Ответы (2 шт):

Автор решения: passant

Хотите именно ХИ-2 тест - придется строить вручную.

Можно задействовать тест Колмогорова-Смирнова:

stats.kstest(xs, "binom", (21, 0.9))

Его результат неутешителен:

KstestResult(statistic=0.4952700362282919, pvalue=7.51602278864889e-12)

т.е. считать ваши данные распределенными по биноминальному закону не приходится. Впрочем, это и неудивительно, с оглядкой на их гистограмму. введите сюда описание изображения

→ Ссылка
Автор решения: Shap

Итак, спустя некоторое время я нашел разгадку.

Объект 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')
→ Ссылка