Python中的卡方拟合优度测试:p值太低,但拟合函数是正确的

时间:2017-03-19 16:19:53

标签: python scipy chi-squared p-value goodness-of-fit

尽管已经在相关问题中搜索了两天,但我还没有真正找到这个问题的答案......

在下面的代码中,我生成n个正态分布的随机变量,然后用直方图表示:

import numpy as np
import matplotlib.pyplot as plt

n = 10000                        # number of generated random variables 
x = np.random.normal(0,1,n)      # generate n random variables

# plot this in a non-normalized histogram:
plt.hist(x, bins='auto', normed=False)    

# get the arrays containing the bin counts and the bin edges:
histo, bin_edges = np.histogram(x, bins='auto', normed=False)
number_of_bins = len(bin_edges)-1

之后,找到曲线拟合函数及其参数。 它通常与参数a1和b1一起分布,并使用scaling_factor进行缩放以满足样本未标准化的事实。 它确实非常适合直方图:

import scipy as sp

a1, b1 = sp.stats.norm.fit(x)

scaling_factor = n*(x.max()-x.min())/number_of_bins

plt.plot(x_achse,scaling_factor*sp.stats.norm.pdf(x_achse,a1,b1),'b')

Here's the plot of the histogram with the fitting function in red.

之后,我想用卡方检验测试这个函数与直方图的拟合程度。 此测试使用观察值和这些点中的预期值。为了计算期望值,我首先计算每个bin中间的位置,这个信息包含在数组x_middle中。然后我计算每个bin中间点的拟合函数的值,它给出expected_value数组:

observed_values = histo

bin_width = bin_edges[1] - bin_edges[0]

# array containing the middle point of each bin:
x_middle = np.linspace(  bin_edges[0] + 0.5*bin_width,    
           bin_edges[0] + (0.5 + number_of_bins)*bin_width,
           num = number_of_bins) 

expected_values = scaling_factor*sp.stats.norm.pdf(x_middle,a1,b1)

将其插入Scipy的chisquare函数中,得到大约e-5到e-15数量级的p值,这告诉我拟合函数没有描述直方图:

print(sp.stats.chisquare(observed_values,expected_values,ddof=2)) 

但事实并非如此,该函数非常适合直方图!

有人知道我犯了什么错吗?

非常感谢!! 查尔斯

p.s。:我将delta自由度的数量设置为2,因为从样本中估计出2个参数a1和b1。我尝试使用其他ddof,但结果仍然很差!

1 个答案:

答案 0 :(得分:4)

您对数组blog_comment的终点的计算是一个;它应该是:

id

请注意comment_name的第二个参数中的额外comment_email

更简洁的版本是

comment_content

计算art_id的另一种(可能更准确)方法是使用CDF的差异,而不是在每个间隔的中间使用PDF来近似这些差异:

created_at

通过这个计算,我从卡方检验得到以下结果:

updated_at