我的系统是python3.6,numpy 1.16.2,scipy 1.2.1,matplotlib 3.0.3
import numpy
import matplotlib
import scipy.stats
a=numpy.arange(2,44,1)
print(scipy.stats.shapiro(a))
matplotlib.pyplot.hist(a)
以上脚本输出如下:
(0.9560521245002747, 0.10655178874731064)
显然,
a
不是正态分布,但是scipy.stats.shapiro(a)
的p-value
是0.10655178874731064
有什么问题吗?
scipy.stats.shapiro
的结果在这里不太可能是错误的;正如评论中提到的,p 值与 R 的 shapiro.test
产生的值一致。
options(digits=16)
x = seq(2, 43)
shapiro.test(x)
# W = 0.95605246967015, p-value = 0.1065549026935
与其他正态性检验相比,Shapiro-Wilk 检验对于“大多数”替代方案具有良好的功效;不过,你好像发现了一个威力不大的案例。您还有很多其他选择:
import numpy as np
from scipy import stats
a = np.arange(2, 44, 1)
print(stats.normaltest(a)) # NormaltestResult(statistic=10.128923354263879, pvalue=0.006317310740453355)
print(stats.kurtosistest(a)) # KurtosistestResult(statistic=-3.0094922587552966, pvalue=0.0026168474735435423)
print(stats.jarque_bera(a)) # SignificanceResult(statistic=2.5257207700096096, pvalue=0.2828438260708052)
print(stats.skewtest(a)) # SkewtestResult(statistic=1.0353162312819313, pvalue=0.30052125208274305)
除了
skewtest
之外,所有这些都可以通过足够大的样本检测到偏离正态性的情况。
a = np.arange(2, 44, 0.25)
print(stats.shapiro(a)) # ShapiroResult(statistic=0.9546093344688416, pvalue=2.9430553695419803e-05)
print(stats.normaltest(a)) # NormaltestResult(statistic=73.03250642958905, pvalue=1.3841805073962513e-16)
print(stats.kurtosistest(a)) # KurtosistestResult(statistic=-8.485467131605999, pvalue=2.1485385463319168e-17)
print(stats.jarque_bera(a)) # SignificanceResult(statistic=10.08142867266492, pvalue=0.006469125535965709)
print(stats.skewtest(a)) # SkewtestResult(statistic=1.014570839332235, pvalue=0.31031044559967047)
并且
skewtest
的失败是可以理解的,因为它只是尝试检测偏度是否非零(对于您的样本来说,它不是)。