← 返回《数据科学的统计基础》
📑 查看全课大纲(第 29 / 41 节)

正态性检验

约 15 分钟

📺 正在播放小象官方高清录播(支持倍速与清晰度调节)

正态性检验

小象实战讲义 · 数据科学的统计基础

在实际数据分析中,许多经典的统计推断方法(如 t 检验、方差分析、线性回归等)都建立在数据服从正态分布的前提之上。因此,在应用这些方法之前,对数据进行正态性检验至关重要。本节将介绍两种被广泛认可且功效强大的正态性检验方法:W 检验(Shapiro-Wilk 检验)和 D 检验(D‘Agostino 检验)。学完本节,你将能够根据样本量选择合适的检验方法,理解其背后的统计思想,并利用统计软件或查表完成正态性检验的实践操作。

💡 核心导读

  • 检验目标:判断一组数据是否来自正态总体。原假设 H0H_0 为数据服从正态分布。
  • W 检验:适用于小样本(n50n \le 50),基于次序统计量构造检验统计量 WW,其值越接近 1 越支持正态性假设。
  • D 检验:适用于大样本(n>50n > 50),是 W 检验在大样本下的有效近似,计算更为简便。
  • 检验逻辑:两种检验均通过比较样本数据对正态分布参数的两种不同估计量来构造统计量,若数据来自正态总体,这两种估计应非常接近。
  • 实践要点:掌握两种检验的适用场景、拒绝域方向,并学会通过查表或软件计算进行判断。

W 检验 (Shapiro-Wilk 检验)

检验问题与统计量

X1,X2,,XnX_1, X_2, \ldots, X_n 是来自总体分布 F(x)F(x) 的独立同分布样本。正态性检验关心如下假设: H0:F(x) 是正态分布 N(μ,σ2),其中 μ,σ2 未知vsH1:F(x) 不是正态分布.H_0: F(x) \text{ 是正态分布 } N(\mu, \sigma^2) \text{,其中 } \mu, \sigma^2 \text{ 未知} \quad vs \quad H_1: F(x) \text{ 不是正态分布}.

W 检验由 Shapiro 和 Wilk 于 1965 年提出。其检验统计量 WW 定义为: W=[k=1[n/2]ak,n(X(n+1k)X(k))]2i=1n(XiXˉ)2.W = \frac{\left[ \sum_{k=1}^{[n/2]} a_{k,n} (X_{(n+1-k)} - X_{(k)}) \right]^2}{\sum_{i=1}^{n} (X_i - \bar{X})^2}. 其中,X(1)X(2)X(n)X_{(1)} \le X_{(2)} \le \ldots \le X_{(n)} 为次序统计量,[n/2][n/2] 表示不超过 n/2n/2 的最大整数,Xˉ\bar{X} 为样本均值。系数 ak,na_{k,n} 是依赖于样本容量 nn 和位置 kk 的特定常数,其计算较为复杂,通常由统计软件或查专用表获得。

拒绝域:当 WW 小于某个临界值 cc 时,我们拒绝原假设 H0H_0。临界值 cc 由显著性水平 α\alpha 决定,满足 PH0(W<c)=αP_{H_0}(W < c) = \alpha。直观上,WW 统计量的值介于 0 和 1 之间,越接近 1 表明样本数据越可能来自正态分布。

W 统计量的构造思想

W 统计量的构造基于一个深刻的几何直观:若样本来自正态总体,则其标准化后的次序统计量与其期望值近似在一条直线上。

  1. 模型设定:假设样本来自正态总体 N(μ,σ2)N(\mu, \sigma^2)。令 Yi=(X(i)μ)/σY_i = (X_{(i)} - \mu)/\sigma,则 YiY_i 是标准正态分布 N(0,1)N(0,1) 的次序统计量。记 mi=E(Yi)m_i = E(Y_i)Vij=Cov(Yi,Yj)V_{ij} = \operatorname{Cov}(Y_i, Y_j)
  2. 线性近似:当样本量 nn 较大时,X(i)E(X(i))=μ+σmiX_{(i)} \approx E(X_{(i)}) = \mu + \sigma m_i。这意味着点 (mi,X(i))(m_i, X_{(i)}) 近似位于一条斜率为 σ\sigma、截距为 μ\mu 的直线上。
  3. 相关系数检验:为了检验这 nn 个点 (mi,X(i))(m_i, X_{(i)}) 是否在一条直线上,很自然地可以计算它们的(决定)系数 R2R^2R2=[i=1n(mimˉ)(X(i)Xˉ)]2i=1n(mimˉ)2i=1n(XiXˉ)2.R^2 = \frac{\left[ \sum_{i=1}^{n} (m_i - \bar{m})(X_{(i)} - \bar{X}) \right]^2}{\sum_{i=1}^{n} (m_i - \bar{m})^2 \sum_{i=1}^{n} (X_i - \bar{X})^2}. 如果数据正态,R2R^2 应接近 1。
  4. 化简与等价:由于 YiY_i 服从标准正态分布且对称,可以证明 mˉ=0\bar{m} = 0。利用次序统计量的对称性(YkY_kYn+1k-Y_{n+1-k} 同分布),可以将求和从 11nn 简化为 11[n/2][n/2]。经过一系列代数变换,并令 ak,na_{k,n} 为特定的权重系数,最终可以证明 W=R2W = R^2

直观解释:分母 (XiXˉ)2\sum (X_i - \bar{X})^2 是样本方差 (n1)S2(n-1)S^2 的倍数,是 σ2\sigma^2 的一个估计。分子 [ak,n(X(n+1k)X(k))]2\left[ \sum a_{k,n} (X_{(n+1-k)} - X_{(k)}) \right]^2 本质上是利用样本次序统计量构造的 σ2\sigma^2 的另一个估计(最佳线性无偏估计,BLUE)。在正态假设下,这两个估计应该相差不大,故其比值 WW 应接近 1。若数据非正态,分子对 σ2\sigma^2 的估计效率会下降,导致 WW 值变小。

适用范围与查表

W 检验在 3n503 \le n \le 50 的样本范围内非常有效。当 n>50n > 50 时,计算系数 ak,na_{k,n} 及其分位数变得异常困难。因此,国家标准推荐在 n50n \le 50 时使用 W 检验。在实际应用中,我们通常直接调用统计软件(如 Python 的 SciPy 库)进行计算和判断,或查阅 Shapiro-Wilk 检验的专用临界值表。

import numpy as np
from scipy import stats
import matplotlib.pyplot as plt

# 设置随机种子以保证结果可复现
np.random.seed(321)

# 示例1:生成一组来自正态分布的数据
n_small = 30
data_normal = np.random.normal(loc=10, scale=2, size=n_small)

# 示例2:生成一组来自指数分布的数据(非正态)
data_exp = np.random.exponential(scale=2, size=n_small)

# 进行 Shapiro-Wilk 检验
# scipy.stats.shapiro 返回 (W统计量, p值)
w_stat_normal, p_val_normal = stats.shapiro(data_normal)
w_stat_exp, p_val_exp = stats.shapiro(data_exp)

print("=== Shapiro-Wilk 正态性检验 (n=30) ===")
print(f"正态数据: W = {w_stat_normal:.4f}, p-value = {p_val_normal:.4f}")
print(f"结论: {'不能拒绝正态性假设 (p > 0.05)' if p_val_normal > 0.05 else '拒绝正态性假设 (p <= 0.05)'}")
print()
print(f"指数分布数据: W = {w_stat_exp:.4f}, p-value = {p_val_exp:.4f}")
print(f"结论: {'不能拒绝正态性假设 (p > 0.05)' if p_val_exp > 0.05 else '拒绝正态性假设 (p <= 0.05)'}")

# 可视化:绘制数据的直方图和Q-Q图
fig, axes = plt.subplots(2, 2, figsize=(10, 8))

# 正态数据的直方图和Q-Q图
axes[0, 0].hist(data_normal, bins='auto', edgecolor='black', alpha=0.7)
axes[0, 0].set_title('正态数据直方图')
axes[0, 0].set_xlabel('观测值')
axes[0, 0].set_ylabel('频数')

stats.probplot(data_normal, dist="norm", plot=axes[0, 1])
axes[0, 1].set_title('正态数据Q-Q图')

# 指数分布数据的直方图和Q-Q图
axes[1, 0].hist(data_exp, bins='auto', edgecolor='black', alpha=0.7)
axes[1, 0].set_title('指数分布数据直方图')
axes[1, 0].set_xlabel('观测值')
axes[1, 0].set_ylabel('频数')

stats.probplot(data_exp, dist="norm", plot=axes[1, 1])
axes[1, 1].set_title('指数分布数据Q-Q图')

plt.tight_layout()
plt.show()

D 检验 (D‘Agostino 检验)

动机与统计量

由于 W 检验在大样本下计算困难,D‘Agostino 提出了一种适用于大样本 (n>50n > 50) 的正态性检验方法,即 D 检验。

其思想源于 W 统计量的本质:它是正态分布标准差 σ\sigma 的两种估计量(最佳线性无偏估计 BLUE 与样本标准差 SS)之比的平方。D 检验用更易于计算的估计量替代了复杂的 BLUE 估计。

D 检验统计量 DD 定义为: D=i=1n(in+12)X(i)n2m2,D = \frac{\sum_{i=1}^{n} \left( i - \frac{n+1}{2} \right) X_{(i)}}{n^2 \sqrt{m_2}}, 其中 m2=1ni=1n(XiXˉ)2m_2 = \frac{1}{n}\sum_{i=1}^{n}(X_i - \bar{X})^2 为样本二阶中心矩。

直观理解:分子 (in+12)X(i)\sum (i - \frac{n+1}{2}) X_{(i)} 可以看作是对样本顺序与大小相关性的一种度量。对于对称分布(如正态分布),这个量有其特定的期望。分母 n2m2n^2 \sqrt{m_2} 是一个尺度因子。当数据来自正态总体时,DD 统计量应接近某个理论值(近似为 12π0.2821\frac{1}{2\sqrt{\pi}} \approx 0.2821)。当 DD 远离此值时,我们怀疑数据的正态性。

标准化与拒绝域

在原假设 H0H_0(数据来自正态总体)成立且 nn \to \infty 时,可以证明 DD 统计量近似服从正态分布。通常我们使用其标准化版本: Y=n(DEH0(D))VarH0(D).Y = \frac{\sqrt{n}(D - E_{H_0}(D))}{\sqrt{\operatorname{Var}{H_0}(D)}}. 其中 EH0(D)E{H_0}(D)VarH0(D)\operatorname{Var}_{H_0}(D)DDH0H_0 下的渐近期望和方差。标准化后,YY 近似服从标准正态分布 N(0,1)N(0,1)

拒绝域:对于双侧检验,在显著性水平 α\alpha 下,拒绝域为 Y>z1α/2|Y| > z_{1-\alpha/2},其中 z1α/2z_{1-\alpha/2} 是标准正态分布的 1α/21-\alpha/2 分位数。对于单侧检验,则根据备择假设的方向(如偏度)选择 Y>z1αY > z_{1-\alpha}Y<zαY < z_{\alpha}

与 W 检验一样,实践中我们通常依赖统计软件来完成 D 检验的计算和 p 值判断。

# 续上文的Python环境
from scipy.stats import norm

# 示例:生成一组大样本数据
n_large = 150
data_large_normal = np.random.normal(loc=5, scale=1.5, size=n_large)
data_large_uniform = np.random.uniform(low=2, high=8, size=n_large) # 均匀分布,对称但非正态尾

# 手动计算D统计量 (用于理解公式)
def d_agostino_statistic(x):
    """计算D‘Agostino检验的D统计量"""
    x_sorted = np.sort(x)
    n = len(x)
    i = np.arange(1, n+1)
    numerator = np.sum((i - (n+1)/2) * x_sorted)
    m2 = np.mean((x - np.mean(x))**2)  # 样本二阶中心矩,1/n口径
    denominator = n**2 * np.sqrt(m2)
    D = numerator / denominator
    return D

# 计算D值
D_normal = d_agostino_statistic(data_large_normal)
D_uniform = d_agostino_statistic(data_large_uniform)

print("\n=== D‘Agostino 检验统计量计算 (n=150) ===")
print(f"正态数据: D = {D_normal:.4f}")
print(f"均匀分布数据: D = {D_uniform:.4f}")
print(f"\n理论参考值 (n->∞): E(D) ≈ {1/(2*np.sqrt(np.pi)):.4f}")

# 使用scipy的normaltest函数,它包含了基于偏度和峰度的D‘Agostino‘s K^2检验
# 这是对原始D检验的改进和扩展,同样适用于大样本
k2_stat_normal, p_val_d_normal = stats.normaltest(data_large_normal)
k2_stat_uniform, p_val_d_uniform = stats.normaltest(data_large_uniform)

print("\n=== D‘Agostino‘s K^2 正态性检验 (scipy.stats.normaltest) ===")
print(f"正态数据: K^2 = {k2_stat_normal:.4f}, p-value = {p_val_d_normal:.4f}")
print(f"结论: {'不能拒绝正态性假设' if p_val_d_normal > 0.05 else '拒绝正态性假设'}")
print()
print(f"均匀分布数据: K^2 = {k2_stat_uniform:.4f}, p-value = {p_val_d_uniform:.4f}")
print(f"结论: {'不能拒绝正态性假设' if p_val_d_uniform > 0.05 else '拒绝正态性假设'}")

📝 动手练一练

  1. 情景选择:某工厂质检部门需要分析一批新生产线生产的零件尺寸(共 35 个测量值)是否符合正态分布,以便后续进行过程能力分析。他们应该优先选择哪种正态性检验方法?为什么? 参考答案:应优先选择 W 检验 (Shapiro-Wilk 检验)。因为样本量 n=35n=35,满足 3n503 \le n \le 50 的条件,在此范围内 W 检验被认为是功效最强的正态性检验方法之一,被国际和国家标准所推荐。

  2. 结果解读:对一组 n=120n=120 的客户满意度评分数据进行 D 检验,计算得到标准化统计量 Y=2.85Y = 2.85。若取显著性水平 α=0.05\alpha = 0.05,请问能否认为该评分数据服从正态分布?(已知 z0.9751.96z_{0.975} \approx 1.96参考答案:不能认为数据服从正态分布。因为这是一个双侧检验,临界值为 z0.975=1.96|z_{0.975}| = 1.96。计算得到的 Y=2.85>1.96|Y| = 2.85 > 1.96,落在拒绝域内。因此,在 0.05 的显著性水平下,我们拒绝“数据来自正态总体”的原假设。

本章小结

本节深入探讨了数据科学中验证数据正态性的两种核心检验方法。

  • W 检验 基于次序统计量,通过比较 σ\sigma 的两种估计量(BLUE 与样本方差)构造统计量 WW,适用于小样本 (n50n \le 50),是功效最强的检验之一。
  • D 检验 是 W 检验在大样本 (n>50n > 50) 下的有效近似,通过一个与样本顺序相关的线性组合来构造统计量,计算更为简便,通常使用其标准化版本进行判断。

行动清单

  1. 数据审查:在进行 t 检验、方差分析等参数检验前,养成先检查样本量并执行相应正态性检验的习惯。
  2. 工具实践:使用 Python 的 scipy.stats.shapiro (小样本) 和 scipy.stats.normaltest (大样本,基于 D‘Agostino 思想) 函数对你手头或公开的数据集进行正态性检验演练。
  3. 综合判断:理解 p 值的含义,结合 Q-Q 图、直方图等图形工具,对数据的分布形态做出更全面的评估,避免单一检验的局限性。

— 小象教研组

配套学习资源与课件
  • 第5章课件:分布的检验(PDF · 3.8MB)
    下载
🎁 免费学习资源

领取《小象 11GB VIP 课件资料包与大厂真题手册》

包含全套实战 Jupyter 源码、清洗后数据集、大厂高频面试真题与专属学员答疑交流群。

  • 完整 Python / 数据分析 Jupyter 实战源码
  • 大厂真实业务数据集与练习题
  • 微信扫码添加课程顾问,免费获取网盘下载链接
微信二维码:扫码添加课程顾问微信扫码添加顾问