import scikit_posthocs as sp
import pandas as pd
# Same exam scores as before
class_a =[78,85,90,72,88]
class_b =[65,70,68,74,60]
class_c =[88,92,95,85,91]# Combine
scores = class_a + class_b + class_c
groups =["A"]*5+["B"]*5+["C"]*5
df = pd.DataFrame({"score": scores,"group": groups})# Run the test
result = sp.posthoc_dunn(df, val_col="score", group_col="group", p_adjust="bonferroni")print(result)技术支持
Python 中的 Dunn 检验
每个单元格显示该对组别的调整后 p 值。此处,只有 B 与 C(p = 0.004)低于 0.05 阈值,因此这两个组存在差异。A 与 B(p = 0.167)以及 A 与 C(p = 0.607)不显著,意味着班级 A 与另两个班级在统计上均无显著差异。
在 R 中进行 Dunn 检验
首先,如有需要,请通过 install.packages("dunn.test") 命令安装该库:
library(dunn.test)# Same exam scores as before
class_a <- c(78,85,90,72,88)
class_b <- c(65,70,68,74,60)
class_c <- c(88,92,95,85,91)
scores <- c(class_a, class_b, class_c)
groups <- factor(rep(c("A","B","C"), each =5))# Run the test
dunn.test(scores, groups, method ="bonferroni")技术支持
R 中的 Dunn 检验
结果与 Python 相符,正如所预期。只有 B 与 C 显著,而 A 与 B、A 与 C 不显著。由 Kruskal-Wallis 检验检测到的差异,主要来自班级 B 与班级 C。
Mann-Whitney U 检验用于比较两个独立组,Kruskal-Wallis 检验则将这一方法扩展到三个或以上组。两者都基于秩且不假设正态性。若您仅有两个组,选择 Mann-Whitney U;Kruskal-Wallis 是其多组等价方法。
Kruskal-Wallis 之后何时应使用 Dunn 检验?⌄
当 Kruskal-Wallis 的结果显著且您需要知道具体哪些组对存在差异时,运行 Dunn 检验。它在所有组之间进行两两比较,并调整 p 值以降低误报概率。在 Python 中,可使用 scikit_posthocs.posthoc_dunn();在 R 中,可使用 dunn.test 包实现相同功能。
当您的数据服从正态分布时,比较多个组并不难。问题在于,大多数真实世界的数据并非如此。
如果您默认使用 ANOVA,它会将您带向错误的结论,因为它假设数据服从正态分布。当数据不满足时——比如偏态分布或样本量很小——您需要换一种方法。
Kruskal-Wallis 检验正是这种不同的方法。它是 ANOVA 的非参数替代方案,基于秩而非原始值进行分析,因此不要求正态分布。
本文将介绍其概念、背后的数学原理、如何在 Python 和 R 中运行,以及如何解读结果。
什么是 Kruskal-Wallis 检验?
Kruskal-Wallis 检验是一种用于比较三个或以上独立组的非参数方法。它会将所有观测值转换为秩,并在组间比较这些秩,而不是直接处理原始数值。
您可以把它看作是Mann-Whitney U 检验的扩展,我也写过相关内容。
Mann-Whitney U 同样进行基于秩的比较,但只适用于两个组。Kruskal-Wallis 检验将其扩展到三个或以上,因此当您有多个组且无法使用 ANOVA 时,应当使用它。
因为它基于秩而非原始值进行工作,所以不假设数据服从任何特定分布。这也是它在真实世界数据中有用的原因,因为真实数据往往很难完美地服从某一种分布。
何时使用 Kruskal-Wallis 检验
当您遇到以下情况时,Kruskal-Wallis 检验非常合适:
下面是一个简单的例子。
假设您想比较三个不同班级的考试成绩。分数呈偏态且样本较小,因此 ANOVA 并不合适。Kruskal-Wallis 检验不需要正态性,因此可在此使用。它将告诉您是否至少有一个班级与其他班级的成绩不同,而无需做出您的数据无法支撑的假设。
Kruskal-Wallis 与 ANOVA 的比较
两种检验都用于比较组别,但方法不同。
ANOVA 比较的是组别的均值,并假设数据近似正态且方差相等。当这些假设成立时,它是更好的选择——统计功效更高,结果也更易解读。
Kruskal-Wallis 检验基于秩比较组别的分布。它不关心正态性或方差齐性。这让它更灵活,但代价是一定程度上的统计功效损失。
下面是一张快速对比表:
ANOVA 与 Kruskal-Wallis 检验的比较
如果您的数据服从正态分布,请使用 ANOVA。如果不服从——或无法验证其服从——就使用 Kruskal-Wallis。
Kruskal-Wallis 检验公式
Kruskal-Wallis 检验可归结为一个检验统计量
H。公式如下:Kruskal-Wallis 公式
各组成部分解释如下:
N—— 所有组的观测值总数k—— 组的数量n_i—— 第i个组的观测值个数R_i—— 第i个组的秩和该公式衡量各组的秩和相对于“若所有组完全相同”这一期望的偏离程度。H 大表示组间存在差异,
H小表示差异不大。得到
H后,将其与自由度为k - 1的卡方分布比较以获得 p 值。Kruskal-Wallis 检验的工作流程
执行 Kruskal-Wallis 检验需要四个步骤:
R_iH公式中。如果各组相似,则它们的秩和会接近,H会较小;如果某一组的秩系统性更高或更低,H会变大就是这样!
您可以看到,该检验并不关注具体数值,而是关注它们相对于整体的位置。
在 Python 中进行 Kruskal-Wallis 检验
Python 的
scipy库提供了 Kruskal-Wallis 检验的内置函数,您无需手动实现公式。让我们看一个示例。假设您在比较三个班级的考试成绩。以下是运行检验的方法:
Python 输出
p 值低于 0.05,这意味着至少有一个班级的成绩与其他班级不同。请注意,该检验不会告诉您具体是哪一个——您需要进行事后检验,下一节会介绍。
在 R 中进行 Kruskal-Wallis 检验
与 Python 类似,R 也有该检验的内置函数。我们继续使用同样的考试成绩情境。
R 输出
输出与我在 Python 中得到的相同——同样的
H统计量和同样的 p 值。由于 p < 0.05,您将拒绝原假设,并得出至少有一组存在差异的结论。如何解读 Kruskal-Wallis 结果
Kruskal-Wallis 检验的原假设是所有组具有相同的分布。p 值告诉您是否拒绝该假设。解读如下:
0.05 是一种惯例。根据您的领域或分析的重要性,您可能会使用更严格的阈值(如 0.01)或更宽松的阈值(如 0.10)。
请记住,此检验不会告诉您具体哪个组不同。显著结果仅意味着各组并非完全相同。您知道存在差异,但不知道差异在哪里。要找出哪些成对组驱动了差异,您需要进行事后检验。
Kruskal-Wallis 之后的事后检验
该检验告诉您至少有一组不同,但不会指出究竟哪个组不同。若您有三个组且 p < 0.05,可能是 A 对 B、A 对 C、B 对 C,或它们的某种组合。您需要执行事后检验以获得这些两两比较。
Dunn 检验是最常见的选择。它对所有组进行两两比较,并调整 p 值以控制多重比较带来的影响——如果不做调整,误报的概率会被抬高。比较越多,单纯由偶然性导致“显著”结果的风险越高。
在 Python 中进行 Dunn 检验
您需要使用
scikit_posthocs库。如果尚未安装,请运行pip install scikit-posthocs进行安装。之后,计算很简单:
Python 中的 Dunn 检验
每个单元格显示该对组别的调整后 p 值。此处,只有 B 与 C(p = 0.004)低于 0.05 阈值,因此这两个组存在差异。A 与 B(p = 0.167)以及 A 与 C(p = 0.607)不显著,意味着班级 A 与另两个班级在统计上均无显著差异。
在 R 中进行 Dunn 检验
首先,如有需要,请通过
install.packages("dunn.test")命令安装该库:R 中的 Dunn 检验
结果与 Python 相符,正如所预期。只有 B 与 C 显著,而 A 与 B、A 与 C 不显著。由 Kruskal-Wallis 检验检测到的差异,主要来自班级 B 与班级 C。
Kruskal-Wallis 检验的假设
Kruskal-Wallis 检验比 ANOVA 更灵活,但在运行前仍需检查三个假设:
若违反前两个假设,检验结果将不可靠。第三个假设相对宽松,它影响的是如何解读结果,而非是否可以运行检验。
何时不应使用 Kruskal-Wallis 检验
以下三种情况更适合使用其他检验:
总结
当数据不满足 ANOVA 等检验所要求的正态分布时,Kruskal-Wallis 检验可用于比较三个或以上独立组。这得益于其基于秩而非原始值进行分析。
尽管如此,它并不是ANOVA的替代品。如果数据服从正态分布,ANOVA 更好,因为它具有更高的统计效力。另一方面,如果数据是配对的,请使用 Friedman 检验。归根结底,合适的检验取决于您的数据。
在条件合适时,Kruskal-Wallis 检验是可靠且直接的选择。您需要运行它、查看 p 值,并在需要定位差异来源时结合 Dunn 检验进行后续分析。
统计学知识有些生疏?参加我们的统计学入门课程,只需一个下午即可重回正轨。