Как выполнить chi-squared goodness of fit test с использованием научных библиотек в Python?

Предположим, что у меня есть некоторые данные, которые я получил эмпирически:

from scipy import stats
size = 10000
x = 10 * stats.expon.rvs(size=size) + 0.2 * np.random.uniform(size=size)

Он экспоненциально распределен (с некоторым шумом), и я хочу проверить это, используя критерий чистоты соответствия (GoF). Каков самый простой способ сделать это, используя стандартные научные библиотеки в Python (например, scipy или statsmodels) с наименьшим количеством ручных шагов и допущений?

Я могу поместить модель с помощью:

param = stats.expon.fit(x)
plt.hist(x, normed=True, color='white', hatch='/')
plt.plot(grid, distr.pdf(np.linspace(0, 100, 10000), *param))

distribution and empirical data plot

Очень изящно рассчитать тест Колмогорова-Смирнова.

>>> stats.kstest(x, lambda x : stats.expon.cdf(x, *param))
(0.0061000000000000004, 0.85077099515985011)

Однако я не могу найти хороший способ вычисления теста хи-квадрат.

Существует chi-squared GoF-функция в statsmodel, но она предполагает дискретное распределение (и экспоненциальное распределение непрерывно).

официальное учебное пособие по scipy.stats охватывает только случай для пользовательского распространения, а вероятности создаются путем использования многих выражений (npoints, npointsh, nbound, normbound), поэтому мне не совсем понятно, как это сделать для других дистрибутивов. примеры chisquare предполагают, что ожидаемые значения и DoF уже получены.

Кроме того, я не ищу способ "вручную" выполнить тест, как уже обсуждался , но хотел бы знать, как применить один из доступных библиотечных функций.

Ответы

Ответ 1

Приближенное решение для вероятностных бинов:

  • Оцените параметры распределения
  • Используйте обратный cdf, ppf, если это scipy.stats.distribution, чтобы получить бинги для регулярной сетки вероятности, например. distribution.ppf(np.linspace(0, 1, n_bins + 1), *args)
  • Затем используйте np.histogram для подсчета количества наблюдений в каждом бункере

затем используйте тест chisquare на частотах.

Альтернативой было бы найти края бункера из процентилей отсортированных данных и использовать cdf для поиска фактических вероятностей.

Это только приблизительное, так как теория критерия проверки предполагает, что параметры оцениваются по максимальному правдоподобию на биндинговых данных. И я не уверен, влияет ли выбор бинов на основе данных асимптотического распределения.

Я долгое время не рассматривал это. Если приблизительное решение недостаточно эффективно, я бы рекомендовал вам задать вопрос о stats.stackexchange.

Ответ 2

Зачем вам нужно "проверять", что оно экспоненциально? Вы уверены, что вам нужен статистический тест? Я могу в значительной степени гарантировать, что это не является в конечном счете экспоненциальным, и тест будет значительным, если у вас будет достаточно данных, что делает логику использования теста довольно принудительной. Это может помочь вам прочитать эту тему резюме: Является ли тестирование нормальности "по сути бесполезным" ? или мой ответ здесь: Тестирование для гетероседастичность со многими наблюдениями.

Обычно лучше использовать qq-сюжет и/или pp-сюжет (в зависимости от того, интересуетесь ли вы положением в хвостах или середине распространения, см. мой ответ здесь: PP-графики и QQ-графики). Информацию о том, как сделать qq-графики в Python SciPy, можно найти в этом потоке SO: Quantile-Quantile с использованием SciPy