【Python・统计学】Kruskal-Wallis检验/H检验(原理及代码)

前言

自学笔记,分享给对统计学原理不太清楚但需要在论文中用到的小伙伴,欢迎大佬们补充或绕道。ps:本文不涉及公式讲解(文科生小白友好体质)~(部分定义等来源于知乎百度等)

本文重点:Kruskal-Wallis检验(Kruskal-Wallis test),也称H检验

1.定义和简单原理

2.应用条件

【3.数据实例以及Python代码

【4.多重比较(例:Dunn检验)

1.定义和简单原理

Kruskal-Wallis检验(Kruskal-Wallis test),也称为克鲁斯卡尔-沃利斯检验或H检验,是一种非参数检验方法,用于比较三个或更多独立样本的差异。它可以看作是Mann-Whitney U检验的扩展

 补充1:Mann-Whitney U检验适用于两组数据,Kruskal-Wallis检验适用于三组及以上数据

【Python・统计学】Mann-Whitney U检验/Wilcoxon秩和检验(原理及代码)icon-default.png?t=N7T8https://mp.csdn.net/mp_blog/creation/editor/138028894

Kruskal-Wallis检验的基本思想是,如果各组样本来自同一总体,那么各组样本的秩和应该相近。具体步骤如下:

  1. 将所有样本的数据合并,并按照从小到大的顺序排列,记录每个数据点的秩(排名)。
  2. 对每个组内的秩求和,计算每个组的平均秩。
  3. 如果各组样本来自同一总体,那么各组的平均秩应该相近。如果某些组的平均秩明显偏高或偏低,则可能表明这些组与其他组存在显著差异。
  4. 计算Kruskal-Wallis检验的统计量H,并根据H的值和自由度,查表或计算p值,以判断是否拒绝原假设。

2.应用条件

  • 数据是独立的随机样本,各组之间相互独立。
  • 数据至少是顺序尺度的,即可以比较大小,但不要求数值之间的差异有意义。
  • 各组样本不必服从正态分布,也不要求方差齐性。
  • 各组样本的分布形状相似(如都是偏态分布或都是对称分布),但不要求完全一致。

3.数据实例以及Python代码

假设我们想比较三种不同教学方法(A、B、C)对学生数学成绩的影响。我们随机选择了一些学生,分别接受这三种教学方法,并记录他们的数学成绩(满分100分)。数据如下:

methodA = [85, 92, 78, 88, 90, 82, 84, 80]
methodB = [75, 80, 82, 74, 79, 76, 81]
methodC = [90, 87, 92, 93, 88, 91, 85, 89, 94]
from scipy.stats import kruskal

# 三组学生的数学成绩
methodA = [85, 92, 78, 88, 90, 82, 84, 80]
methodB = [75, 80, 82, 74, 79, 76, 81]
methodC = [90, 87, 92, 93, 88, 91, 85, 89, 94]

# 进行Kruskal-Wallis检验
statistic, p_value = kruskal(methodA, methodB, methodC)

print(f'检验统计量为: {statistic}')
print(f'p值为: {p_value}')

if p_value < 0.05:
    print('在显著性水平0.05下,拒绝原假设,认为三组学生的数学成绩存在显著差异')
else:
    print('在显著性水平0.05下,接受原假设,认为三组学生的数学成绩没有显著差异')
检验统计量为: 11.40568181818182
p值为: 0.0033381294063426758
在显著性水平0.05下,拒绝原假设,认为三组学生的数学成绩存在显著差异

根据输出结果,p值为0.0033381294063426758,小于显著性水平0.05,因此我们拒绝原假设,认为这三组学生的数学成绩存在显著差异。

需要注意的是,Kruskal-Wallis检验只能判断是否存在显著差异,但无法确定具体是哪些组之间存在差异。如果想进一步了解组间差异,可以进行事后多重比较,如Dunn检验

4.多重比较(例:Dunn检验)

本文使用Dunn检验进行多重比较。

Dunn多重比较代码
rank_A = np.mean([sorted(methodA + methodB + methodC).index(x) + 1 for x in methodA])
    rank_B = np.mean([sorted(methodA + methodB + methodC).index(x) + 1 for x in methodB])
    rank_C = np.mean([sorted(methodA + methodB + methodC).index(x) + 1 for x in methodC])

# 计算总样本量和每个组的样本量
n = len(methodA) + len(methodB) + len(methodC)
n_A, n_B, n_C = len(methodA), len(methodB), len(methodC)
    
# 计算Dunn检验的z值和p值
z_AB, p_AB = mannwhitneyu(methodA, methodB, alternative='two-sided')
z_AC, p_AC = mannwhitneyu(methodA, methodC, alternative='two-sided')
z_BC, p_BC = mannwhitneyu(methodB, methodC, alternative='two-sided')
    
# 调整p值 (Bonferroni correction)
p_AB, p_AC, p_BC = p_AB * 3, p_AC * 3, p_BC * 3
    
print(f'\nDunn事后检验结果:')
print(f'组A vs 组B: p值 = {p_AB}, 均值秩差 = {rank_A - rank_B}')
print(f'组A vs 组C: p值 = {p_AC}, 均值秩差 = {rank_A - rank_C}')
print(f'组B vs 组C: p值 = {p_BC}, 均值秩差 = {rank_B - rank_C}')
    
Dunn事后检验结果:
组A vs 组B: p值 = 0.06265422533333335, 均值秩差 = 5.678571428571429
组A vs 组C: p值 = 0.9698684800000001, 均值秩差 = -2.3611111111111116
组B vs 组C: p值 = 0.001467466666666643, 均值秩差 = -8.03968253968254

从输出结果可以看出,在显著性水平0.05下:

  • 组A与组B的数学成绩没有显著差异(p = 0.06265422533333335 > 0.05)。
  • 组A与组C的数学成绩没有显著差异(p = 0.9698684800000001 > 0.05)。
  • 组B与组C的数学成绩存在显著差异(p = 0.001467466666666643 < 0.05),且组C的均值秩高于组B(均值秩差为负)。

因此,我们可以得出结论,教学方法C的效果显著优于教学方法B,而教学方法A与其他两种方法没有显著差异。

需要注意的是,Dunn检验只是事后多重比较的一种方法,还有其他方法如Nemenyi检验、Conover检验等。此外,Bonferroni校正是一种较为保守的p值调整方法,有时可能会增加第二类错误(假阴性)的风险。根据具体情况,也可以考虑使用其他校正方法,如Holm-Bonferroni校正、FDR校正等。

多重比较方法选择

一般来说,如果样本量相等,可以优先考虑Nemenyi检验;

如果样本量不等,可以考虑Dunn检验或Conover检验;

如果比较次数较少,可以使用Bonferroni校正;

如果比较次数较多,可以考虑Benjamini-Hochberg FDR校正。

你可能感兴趣的:(python,统计学,python,学习,笔记)