本文主要对正态性检验方法做了汇总,重点阐述了常用的正态性检验方法的使用场景及其在 R 或 Python 中的实现。
正态分布在统计学中有着极为重要的地位,它是 χ 2 \chi^2 χ2分布、 t t t分布、 F F F分布的基础,也是许多统计方法的理论基础,故检验样本是否来自正态分布具有十分重要的意义。
正态性检验的方法有很多,以下列举了一些常见的方法:
对于正态性检验,建议首先利用直方图或核密度估计得到样本数据的分布图,若分布严重偏态或尖峰,可认为其不是来自于正态分布;若根据直方图或核密估计分布不容易做出判断,再利用各检验方法对其检验。
注意:对于正态性检验,应该避免仅根据一种检验方法便轻易的做出决策,应该使用多种方法,综合评价。 source:参考文献[1]
另还有一些选择正态性检验的规定,仅供参考:
- SPSS 规定:当样本含量 3≤n≤5000 时,结果以 Shapiro—Wilk(W 检验) 为准,当样本含量 n>5000 结果以 Kolmogorm —Smimov(D 检验,修正后的KS检验,即Lillie检验,见2.2.3) 为准。
- SAS 规定:当样本含量 n≤2000 时,结果以 Shapim—Wilk(W 检验) 为准,当样本含量 n>2000 时,结果以 Kolmogorov—Smimov(D 检验,修正后的KS检验) 为准。
下文对直方图、Q-Q图以及Shapiro检验、KS检验的原理做一个较为详细的叙述,并给出对应方法在R语言和Python中的实现。另外,对其余方法做简要叙述。
本文内容中理论部分是作者阅读文献后整理得到
直方图(histogram)是用于展示分组数据分布的一种图形,它是用矩形的宽度和高度(即面积)来表示频数分布的。绘制该图时,在平面直角坐标系中,用横轴表示数据分组,纵轴表示频数或频率,这样就形成了一个矩形(即直方图)。
直方图与柱状图的区别:①直方图的高度与宽度都有意义。柱状图是用柱子的长度表示各类别频数的多少,其宽度(表示类别)固定;而直方图是用面积表示各组频数的多少,矩形的高度表示每一组的频数或频率,宽度则表示各组的组距;②由于分组数据具有连续性,直方图的各矩形通常是连续排列,而柱状图则是分开排列;③柱状图用于展示分类型数据,直方图用于展示数值型数据。source:参考文献[2]
直方图的具体绘制方法见参考文献[3] p 15 p_{15} p15
假设样本 X 1 , X 2 , . . . , X n X_1 ,X_2 ,...,X_n X1,X2,...,Xn来自正态总体 N ( µ , σ 2 ) N(µ,σ^2 ) N(µ,σ2). 将样本观测值按照由小到大的顺序排列, 得到次序统计量 x ( 1 ) ≤ x ( 2 ) ≤ ⋅ ⋅ ⋅ ≤ x ( n ) x_{(1)} \le x_{(2)} \le ··· \le x_{(n)} x(1)≤x(2)≤⋅⋅⋅≤x(n)和经验分布函数
F n ( x ) = { 0 x < x ( 1 ) k / n x ( k ) ≤ x ≤ x ( k + 1 ) , k = 1 , 2 , . . . , n 1 x ≥ x ( n ) F_n(x)=\left\{ \begin{array}{rcl} 0 & & {x < x_{(1)}}\\ k/n & & {x_{(k)}\le x \le x_{(k+1)}, k=1,2,...,n}\\ 1 & & {x\ge x{(n)}}\\ \end{array} \right. Fn(x)=⎩⎨⎧0k/n1x<x(1)x(k)≤x≤x(k+1),k=1,2,...,nx≥x(n)
由于当 n n n充分大时, ∀ ε > 0 \forall \varepsilon >0 ∀ε>0有 P ( ∣ F n ( x ) − F ( x ) ∣ > ε ) = 0 P(|F_n(x)-F(x)| >\varepsilon)=0 P(∣Fn(x)−F(x)∣>ε)=0.
又 F ( x ) = P ( X ≤ x ) = ϕ ( x − μ σ ) F(x)=P(X\le x) =\phi(\frac{x-\mu}{\sigma}) F(x)=P(X≤x)=ϕ(σx−μ)
故当 n n n充分大时, F n ( x ) = ϕ ( x − μ σ ) F_n(x)=\phi(\frac{x-\mu}{\sigma}) Fn(x)=ϕ(σx−μ), a . s a.s a.s
即 x − μ σ = ϕ ( − 1 ) ( F n ( x ) ) , a . s \frac{x-\mu}{\sigma}=\phi^{(-1)}(F_n(x)), a.s σx−μ=ϕ(−1)(Fn(x)),a.s
∀ x ∈ R \forall x \in R ∀x∈R, 令 ϕ − 1 ( F n ( x ) ) ≡ ω \phi^{-1}(F_n(x)) \equiv \omega ϕ−1(Fn(x))≡ω, 则有
x ≡ σ ω + μ , a . s x \equiv \sigma \omega + \mu, a.s x≡σω+μ,a.s
上式意味着,当总体是 N ( μ , σ 2 ) N(\mu, \sigma^2) N(μ,σ2)且样本量 n n n充分大时,样本观测值 x x x和逆标准正态分布值 ω \omega ω组成的点 ( ω , x ) (\omega, x) (ω,x)几乎处于一条直线上. source: 参考文献[3] p 22 p_{22} p22
library(car)
qqnorm(x)
# QQ图
import statsmodels.api as sm
sm.qqplot(y,line='s')
# PP图
from scipy import stats
stats.probplot(x, dist="norm", plot=plt)
建立假设
H 0 : H_0: H0:总体 X X X的分布为正态分布 N ( μ , σ 2 ) N(\mu, \sigma^2) N(μ,σ2);(样本来自总体与正态分布无显著差异,即符合正态分布)
H 1 : H_1: H1:总体 X X X的分布不是正态分布 N ( μ , σ 2 ) N(\mu, \sigma^2) N(μ,σ2)
W 检验全称 Shapiro-Wilk 检验,是一种基于相关性的算法。计算可得到一个相关系数,它越接近 1 就越表明数据和正态分布拟合得越好。
注:这里, x i x_i xi是第 i 个顺序统计量,即第 i 个最小的样本观测值。
$a_i , i=1,2…,n $是常数,它们的定义为
( a 1 , . . . , a n ) = m T V − 1 ( m T V − 1 V − 1 m ) 1 / 2 (a_1, ..., a_n) = \frac{m^TV^{-1}}{(m^TV^{-1}V^{-1}m)^{1/2}} (a1,...,an)=(mTV−1V−1m)1/2mTV−1
m = ( m 1 , . . . , m n ) T m=(m_1, ..., m_n) ^T m=(m1,...,mn)T 是样本顺序统计量的样本均值, V是样本
顺序统计量的协方差矩阵。
(a可直接查表得到)
shapiro.test(x)
from scipy import stats
stats.shapiro(x)
KS检验基于经验分布函数,该检验用大样本近似。其检验的是标化后的数据是否服从理论的分布。
需要注意的是样本数据如果有结点(及是重复的数据),则无法计算准确的P值。
设样本的经验概率分布函数定义为 F n ( x ) = 1 n ∑ i = 1 n I X i ≤ x F_n(x)=\frac{1}{n}\sum_{i=1}^nI_{X_i \le x} Fn(x)=n1∑i=1nIXi≤x,若 X i ≤ 1 X_i \le 1 Xi≤1 则 I X i ≤ x = 1 I_{X_i \le x}=1 IXi≤x=1,否则0.
D n D_n Dn的计算:
1)计算原数据的均值 x ‾ \overline{x} x与标准差 s s s,以及各水平对应的频数;
2)对水平的大小排序,得到频数序列,计算累计频数;
3)再计算累计频率,以及对应水平用Z-score法标准化后的取值;
4)使用标准化后的取值 x x x,查表得到理论分布的值;
5) D n = m a x ( 累 计 频 率 − 理 论 分 布 ) D_n=max(累计频率 - 理论分布) Dn=max(累计频率−理论分布)
D值越小越接近正态分布
ks.test(x, "pnorm",mean(x),sd(x))
#x为要检验的样本数据,其函数默认修改的精确公式、双边检验。
#需要大样本近似命令中加exact = F;
#单边我们可以用alternative = "less"或alternative= "greater"选择。
from scipy import stats
stats.kstest(x, 'norm', (x.mean(), x.std())) # 注意,Python的ks检验其P-value有时会与其他统计软件略微不同
Lilliefors (Lillie)检验最早由Lilliefors 于1967年提出,它是对KS正态性检验的的修正,适合大样本。
适用于一般的正态性检验。
Lillie检验实现:
library(nortest)
lillie.test(x)
# Python中未找到lillie检验的封装函数.
import scipy.stats as ss
ss.jarque_bera(y)
https://www.php.cn/python-tutorials-391980.html
R中可用tseries包中的jarque.bera.test()实现
详见参考文献[4][1]
还可以参考:
https://blog.csdn.net/u013524655/article/details/41053045 (SPSS)
http://www.mamicode.com/info-detail-937349.html (R)https://blog.csdn.net/cyan_soul/article/details/81236124 (Python)
参考文献:
[1] 何凤霞,马学俊. 基于R软件的正态性检验的功效比较[J].统计与决策,2012(18):17-19.
[2] 贾俊平. 统计学[M]. 第6版. 北京:中国人民大学出版社, 2014.12
[3] 高慧璇. 统计计算[M]. 北京:北京大学出版社, 1995.
[4] 李洪成. 数据的正态性检验方法及其统计软件实现 [J]. 统计与决策, 2009(12):155-156.