Levene 方差齐性检验#

Levene 检验 scipy.stats.levene 检验所有输入样本是否来自具有相同方差的总体这一零假设。当存在显著的非正态性偏差时,Levene 检验是 Bartlett 检验 scipy.stats.bartlett 的替代方法。

[1] 中,研究了维生素 C 对豚鼠牙齿生长的影响。在一项对照研究中,将 60 名受试者分为小剂量组、中剂量组和大剂量组,分别接受每日 0.5 毫克、1.0 毫克和 2.0 毫克的维生素 C。42 天后,测量了牙齿的生长情况。

下面的 small_dosemedium_doselarge_dose 数组记录了三组的牙齿生长测量值,单位为微米。

import numpy as np
small_dose = np.array([
    4.2, 11.5, 7.3, 5.8, 6.4, 10, 11.2, 11.2, 5.2, 7,
    15.2, 21.5, 17.6, 9.7, 14.5, 10, 8.2, 9.4, 16.5, 9.7
])
medium_dose = np.array([
    16.5, 16.5, 15.2, 17.3, 22.5, 17.3, 13.6, 14.5, 18.8, 15.5,
    19.7, 23.3, 23.6, 26.4, 20, 25.2, 25.8, 21.2, 14.5, 27.3
])
large_dose = np.array([
    23.6, 18.5, 33.9, 25.5, 26.4, 32.5, 26.7, 21.5, 23.3, 29.5,
    25.5, 26.4, 22.4, 24.5, 24.8, 30.9, 26.4, 27.3, 29.4, 23
])

scipy.stats.levene 统计量对样本之间方差的差异很敏感。

from scipy import stats
res = stats.levene(small_dose, medium_dose, large_dose)
res.statistic
0.6457341109631506

当方差存在较大差异时,统计量的值往往会很高。

我们可以通过将观察到的统计量值与零分布进行比较来检验组间方差的不等性:零分布是在三个组的总体方差相等这一零假设下得出的统计量值分布。

对于此检验,零分布遵循如下所示的 F 分布。

import matplotlib.pyplot as plt
k, n = 3, 60   # number of samples, total number of observations
dist = stats.f(dfn=k-1, dfd=n-k)
val = np.linspace(0, 5, 100)
pdf = dist.pdf(val)
fig, ax = plt.subplots(figsize=(8, 5))

def plot(ax):  # we'll reuse this
    ax.plot(val, pdf, color='C0')
    ax.set_title("Levene Test Null Distribution")
    ax.set_xlabel("statistic")
    ax.set_ylabel("probability density")
    ax.set_xlim(0, 5)
    ax.set_ylim(0, 1)

plot(ax)
plt.show()
../../_images/67bd61cbd59550554e2ecee2e6e816620f188ebc984415c2874c9a205e9a36a9.png

比较通过 p 值量化:零分布中大于或等于观察到的统计量值的比例。

fig, ax = plt.subplots(figsize=(8, 5))
plot(ax)
pvalue = dist.sf(res.statistic)
annotation = (f'p-value={pvalue:.3f}\n(shaded area)')
props = dict(facecolor='black', width=1, headwidth=5, headlength=8)
_ = ax.annotate(annotation, (1.5, 0.22), (2.25, 0.3), arrowprops=props)
i = val >= res.statistic
ax.fill_between(val[i], y1=0, y2=pdf[i], color='C0')
plt.show()
../../_images/accc3e532be928d8e798bcc04500b327e81620f445d3f572332e5a022c57d4cc.png
res.pvalue
0.5280694573759905

如果 p 值“小”,也就是说,如果从具有相同方差的分布中抽样数据产生如此极端的统计量值的概率很低,则这可以作为反对零假设的证据,而支持另一种假设:各组的方差不相等。请注意

  • 反之则不然;也就是说,该检验不用于为零假设提供证据。

  • 被认为“小”的值的阈值是一个选择,应该在分析数据之前做出 [2],并考虑假阳性(错误地拒绝零假设)和假阴性(未能拒绝错误的零假设)的风险。

  • 小的 p 值不是 大的 效应的证据;相反,它们只能为“显著”效应提供证据,这意味着它们不太可能在零假设下发生。

请注意,F 分布提供了零分布的渐近近似。对于小样本,执行置换检验可能更合适:在所有三个样本都从同一总体中抽取的零假设下,每个测量值都同样可能在三个样本中的任何一个中观察到。因此,我们可以通过在许多随机生成的观察结果到三个样本的分区下计算统计量来形成随机化的零分布。

def statistic(*samples):
    return stats.levene(*samples).statistic
ref = stats.permutation_test(
    (small_dose, medium_dose, large_dose), statistic,
    permutation_type='independent', alternative='greater'
)
fig, ax = plt.subplots(figsize=(8, 5))
plot(ax)
bins = np.linspace(0, 5, 25)
ax.hist(
    ref.null_distribution, bins=bins, density=True, facecolor="C1"
)
ax.legend(['asymptotic approximation\n(many observations)',
           'randomized null distribution'])
plot(ax)
plt.show()
../../_images/04212f15c4160651734feb3e1dbcfea72e329126b523710eefafbd3f4649fa7f.png
ref.pvalue  # randomized test p-value
0.4565

请注意,此处计算的 p 值与上面 scipy.stats.levene 返回的渐近近似之间存在显著差异。可以从置换检验中严格得出的统计推断是有限的;尽管如此,它们在许多情况下可能是首选方法 [3]

参考文献#