Я не думаю, что ваш ответ на ваш собственный вопрос правильный, и в ваших кодах есть ряд проблем.
Во-первых, согласно вашей реализации, 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, используя ваш код.