Python中分布的正态性检验

15

我有一些从雷达卫星图像中采样的数据,并希望对其进行一些统计测试。在此之前,我想进行一个正态性检验,以确保我的数据服从正态分布。我的数据看起来服从正态分布,但当我进行测试时,得到了P值为0,这表明我的数据不服从正态分布。

我已经附上了我的代码,输出和分布直方图(我对Python相对新手,如果我的代码有任何笨拙之处,请见谅)。有人能告诉我是否做错了什么吗?从我的直方图来看,我很难相信我的数据不服从正态分布?

values = 'inputfile.h5'
f = h5py.File(values,'r')
dset = f['/DATA/DATA']
array = dset[...,0]
print('normality =', scipy.stats.normaltest(array))
max = np.amax(array)
min = np.amin(array)

histo = np.histogram(array, bins=100, range=(min, max))
freqs = histo[0]
rangebins = (max - min)
numberbins = (len(histo[1])-1)
interval = (rangebins/numberbins)
newbins = np.arange((min), (max), interval)
histogram = bar(newbins, freqs, width=0.2, color='gray')
plt.show()

这将打印出这个:(41099.095955202931, 0.0)。第一个元素是卡方值,第二个元素是p值。

我已经制作了一张关于数据的图表,并将其附加在下面。我认为,由于我处理的是负值,可能会导致问题,因此我对数值进行了归一化,但问题仍然存在。

数组中的值的直方图


1
这个问题解释了为什么你得到了如此小的p值。实际上,正态性检验几乎总是在非常大的样本量上拒绝零假设(例如,在你的样本中,你可以看到左侧有一点偏斜,在你巨大的样本量下已经足够了)。 - David Robinson
@unutbu:这不是真的:为了证明,即使均值为100,标准差为10,“normaltest(np.random.normal(loc=100, scale=10, size=1000))”仍然返回均匀的p值。 - David Robinson
@DavidRobinson:哦!感谢您的纠正。 - unutbu
1
这可能有点晚了,但是对于未来的读者:minmax是Python中的关键字,因此我建议不要将它们用作变量。 - Eulenfuchswiesel
2个回答

15

这个问题解释了为什么你得到如此小的p值。实际上,正态性检验几乎总是在非常大的样本量上拒绝零假设(例如,在你的样本中,你可以看到左侧有些偏斜,在你巨大的样本量下已经足够)。

在你的情况下,更实用的方法是绘制一个适合你数据的正态曲线拟合。然后你就可以看到正态曲线实际上有哪些不同之处(例如,你可以看到左侧的尾部是否确实过长)。例如:

from matplotlib import pyplot as plt
import matplotlib.mlab as mlab

n, bins, patches = plt.hist(array, 50, normed=1)
mu = np.mean(array)
sigma = np.std(array)
plt.plot(bins, mlab.normpdf(bins, mu, sigma))

(请注意normed=1参数:这会确保直方图被归一化为总面积为1,这使得它可以与诸如正态分布之类的密度进行比较)。


6

通常情况下,当样本数量小于50时,使用正态性检验需要谨慎。因为这些测试需要足够的证据来拒绝零假设,即“数据分布是正态分布”,而当样本数量较少时,它们无法找到这些证据。

请记住,当您未能拒绝零假设时,并不意味着备择假设是正确的。

还有另一种可能性: 某些正态性统计测试的实现将您的数据分布与标准正态分布进行比较。为了避免这种情况,建议您对数据进行标准化,然后再应用正态性检验。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接