Тест хи-квадрат с использованием частот, бинов, CDF, Python - PullRequest
2 голосов
/ 25 октября 2010

Я пытаюсь написать критерий соответствия по критерию хи-квадрат для распространения бета-версии с нуля, без использования каких-либо внешних функций.Приведенный ниже код сообщает «1» для подбора, хотя kstest из scipy.stats возвращает ноль.Данные распределяются нормально, поэтому моя функция также должна возвращать ноль.

import numpy as np
from scipy.stats import chi2
from scipy.stats import beta
from scipy.stats import kstest
from scipy.stats import norm

preds = norm.rvs(5,2,size=200)
preds.sort()

bin_size = 30
bins = np.linspace(0,10,bin_size)
counts = np.digitize(preds, bins)
mean = 5
var = 2

sum = 0
for i in range(len(bins)-1):
    p = beta.cdf(bins[i+1], mean, var) - beta.cdf(bins[i], mean, var)  
    freq = len(counts[counts==i]) / float(len(counts))    
    sum = sum + ((freq - p)**2)/p

dof = len(counts)-2
pval = 1 - chi2.cdf(sum, dof)
print pval

В коде я создаю бины, измеряю частоты на основе бинов, вычисляю ожидаемую частоту с помощью CDF бета-распределения и суммирую ее, получая в результатев статистике теста X ^ 2.

Вызов kstest:

print kstest(preds, 'beta', [mean, var])

Что я здесь не так делаю?

Спасибо,

Ответы [ 2 ]

3 голосов
/ 27 апреля 2014

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

Во-первых, согласно вашей реализации, dof, рассчитанный с использованием len(counts)-2, аналогичен len(preds)-2. Так что изменение, которое не имеет никакого значения.

Во-вторых, чтобы выполнить тест Chi ^ 2 по подгонке параметра, вам нужно создать ряд элементов MECE, что означает отсутствие перекрытия между элементами и они совместно охватывают все возможные значения X. Однако, настроив свои лотки с помощью bins = np.linspace(0,10,bin_size), вы принудительно остановили крайний правый лоток на 10. В то время как распределение Гаусса охватывает -инф до инф. Так что есть вероятность, что сгенерированные вами случайные числа превысят 10.

Но это может быть меньшей проблемой по сравнению с этим: обычно требуется, чтобы количество отсчетов для каждой ячейки составляло не менее 5. Тем не менее, использование вашего метода для подсчета чисел, попадающих в ячейки (в данном случае вы задаете 30 ячеек) может и фактически почти всегда имеет числа ниже 5, и даже 0. 0 отсчетов в любом ячейке приводит к бесконечности в последующих вычислениях sum и это может дать отказ, независимо от того, хорошо или плохо. И я думаю, именно поэтому вы получаете 0 после изменения dof на len(preds)-2, у вас просто есть хотя бы один 0 в счетчиках бин.

Другая проблема - это расчет Chi ^ 2. Я думаю, что вы не используете частоты, но фактические значения в каждом бине:

p = beta.cdf(bins[i+1], mean, var) - beta.cdf(bins[i], mean, var)  
p = p*200
freq = len(counts[counts==i])    
sum = sum + ((freq - p)**2)/p

То есть, p и freq - это количество импульсов в каждой категории, а не относительные частоты. Но я не совсем уверен в этом.

Наконец, определение dof - это число бинов - количество подходящих параметров (здесь 2) -1. Так что, если у вас есть 10 корзин, dof = 10 - 2 - 1 = 7. В вашем коде это 200 - 2 = 198. Распределение chi ^ 2 с таким большим значением dof чрезвычайно сглажено, что означает, что вам нужно очень большое значение chi ^ 2, чтобы отклонить подгонку. Вот почему вы получаете 1, используя ваш код.

0 голосов
/ 25 октября 2010

Проблема была с определением DOF:

dof = len (preds) -2

- правильный выбор. Кроме того, мне пришлось уменьшить размер корзины до 15, чтобы получить согласованный результат «0». Известно, что тесты Chi ^ 2 чувствительны к размеру бина.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...