ヘロログ
統計学

クラスカル・ウォリス検定

「3つ以上の処理群に差があるか調べたいが、正規分布を仮定できない」。こうした状況で用いられるのがクラスカル・ウォリス検定(Kruskal–Wallis test)である。

1952年、シカゴ大学の統計学者ウィリアム・クラスカル(William H. Kruskal, 1919–2005)とW・アレン・ウォリス(W. Allen Wallis, 1912–1998)は、論文「Use of Ranks in One-Criterion Variance Analysis」を発表した。この手法は、1940年代に発展した順位に基づく2群の検定(ウィルコクソンの順位和検定やマン・ホイットニーのU検定)を3群以上に拡張したものであり、一元配置分散分析(ANOVA)のノンパラメトリック版として位置づけられる。

クラスカル・ウォリス検定は、臨床試験における複数の治療群の比較、教育研究における複数の指導法の評価など、正規性を仮定しにくい場面で広く用いられている。

基本的な考え方

クラスカル・ウォリス検定は、複数の独立な群の分布に差があるかを検定する。帰無仮説は「すべての群の分布は同じ」であり、対立仮説は「少なくとも1つの群の分布が他と異なる」である。

ここで重要なのは、どの群とどの群が異なるかは問わないという点である。どれか1つでも他と異なると判断されれば帰無仮説は棄却される。各群の分布の形が同じであるという仮定のもとでは、中央値の差の検定と解釈できる。

ウィルコクソンの順位和検定との関係

クラスカル・ウォリス検定は、ウィルコクソンの順位和検定を3群以上に一般化したものである。2群の場合にクラスカル・ウォリス検定を適用すると、順位和検定と同じ結論を与える。

検定統計量

k 個の群があり、第 i 群のサンプルサイズを n_i、全体のサンプルサイズを N = n_1 + n_2 + \cdots + n_k とする。全データを統合して小さい順に1から N までの順位を割り振り、第 i 群の順位和を R_i、順位の平均を \bar{R}_i = R_i / n_i とする。

全体の順位の平均(中央値)は \tilde{N} = \dfrac{N+1}{2} である。タイがない場合のクラスカル・ウォリス検定統計量 H

H = \dfrac{12}{N(N+1)} \sum_{i=1}^{k} n_i \left(\bar{R}_i - \tilde{N}\right)^2

と定義される。これは「各群の順位平均が全体の中央値からどれだけ離れているか」を測る量であり、一元配置分散分析の群間変動に対応する。また、次のように書き直すこともできる。

H = \dfrac{12}{N(N+1)} \sum_{i=1}^{k} \dfrac{R_i^2}{n_i} - 3(N+1)

帰無仮説のもとで、各群のサンプルサイズが十分大きいとき、H は近似的に自由度 k - 1カイ二乗分布に従う。

分散分析との対応

クラスカル・ウォリス検定統計量は、元のデータを順位に置き換えたうえで一元配置分散分析を行ったものと本質的に同じである。正規母集団の場合はANOVAのF検定を用い、正規性が仮定できない場合にこの検定を用いる。

計算例

例:3種の教材の効果比較

3種類の教材A, B, Cを用いて試験を行い、以下の得点が得られた。3群の成績に差があるかを検定する。

A(教材A) 65 70 72
B(教材B) 80 85 78 82
C(教材C) 55 60 58 63

Step 1:統合して順位を付ける

55 58 60 63 65 70 72 78 80 82 85
C C C C A A A B B B B
順位 1 2 3 4 5 6 7 8 9 10 11

Step 2:各群の順位和と順位平均を求める

サンプルサイズ n_i 順位和 R_i 順位平均 \bar{R}_i
A 3 5 + 6 + 7 = 18 18 / 3 = 6.00
B 4 8 + 9 + 10 + 11 = 38 38 / 4 = 9.50
C 4 1 + 2 + 3 + 4 = 10 10 / 4 = 2.50

全体の中央値は \tilde{N} = \dfrac{11 + 1}{2} = 6 である。

Step 3:検定統計量 H を計算する

\begin{aligned} H &= \dfrac{12}{11 \times 12} \left( 3 \times (6.00 - 6)^2 + 4 \times (9.50 - 6)^2 + 4 \times (2.50 - 6)^2 \right) \\[6pt] &= \dfrac{12}{132} \left( 3 \times 0 + 4 \times 12.25 + 4 \times 12.25 \right) \\[6pt] &= \dfrac{12}{132} \times 98 = \dfrac{1176}{132} \approx 8.91 \end{aligned}

Step 4:カイ二乗分布で判定する

自由度 k - 1 = 3 - 1 = 2 のカイ二乗分布の上側5%点は \chi_{0.05}^2(2) = 5.99 である。

H = 8.91 > 5.99 = \chi_{0.05}^2(2)

帰無仮説を棄却する。3群の教材の効果には差があると判断できる(P値 ≈ 0.012)。ただし、この検定だけではどの群とどの群に差があるかはわからない。具体的なペア比較にはダンの検定などの多重比較法を用いる。

練習問題

問1. 3種類のトレーニング法A, B, Cの効果を比較するため、各3人のグループに実施し、以下のスコアを得た。
A 45 52 48
B 60 55 58
C 38 42 35

有意水準5%で、3群に差があるかクラスカル・ウォリス検定で検定せよ。ただし、カイ二乗分布近似を用いてよい。なお、自由度2のカイ二乗分布の上側5%点は5.99である。

統合して順位を付ける。

35 38 42 45 48 52 55 58 60
C C C A A A B B B
順位 1 2 3 4 5 6 7 8 9

R_A = 15, \; R_B = 24, \; R_C = 6

H = \dfrac{12}{9 \times 10} \left( \dfrac{15^2}{3} + \dfrac{24^2}{3} + \dfrac{6^2}{3} \right) - 3 \times 10 = \dfrac{12}{90} \times 297 - 30 = 39.6 - 30 = 7.20

自由度2のカイ二乗分布の上側5%点は5.99であり、H = 7.20 > 5.99 なので帰無仮説を棄却する。

結論:有意水準5%で、3群のトレーニング法には差がある(P値 ≈ 0.027)。

問2. 4群でそれぞれ5回ずつ実験を行ったところ(合計20回)、各群の順位の平均が 15, 14, 7, 6 であった。帰無仮説「4群の分布は同じ」を有意水準5%でクラスカル・ウォリス検定を用いて検定せよ。ただし、カイ二乗分布近似を用いてよい。なお、自由度3のカイ二乗分布の上側5%点は7.81である。

N = 20, \; \tilde{N} = 10.5, \; n_i = 5 \; (i = 1, 2, 3, 4)

\begin{aligned} H &= \dfrac{12}{20 \times 21} \left( 5(15 - 10.5)^2 + 5(14 - 10.5)^2 + 5(7 - 10.5)^2 + 5(6 - 10.5)^2 \right) \\[6pt] &= \dfrac{12}{420} \left( 5 \times 20.25 + 5 \times 12.25 + 5 \times 12.25 + 5 \times 20.25 \right) \\[6pt] &= \dfrac{12}{420} \times 325 = \dfrac{3900}{420} \approx 9.29 \end{aligned}

自由度 4 - 1 = 3 のカイ二乗分布の上側5%点は \chi_{0.05}^2(3) = 7.81 であり、H = 9.29 > 7.81 なので帰無仮説を棄却する。

結論:有意水準5%で、4群に差がある(P値 ≈ 0.026)。

まとめ

項目 内容
目的 3群以上の独立な群の分布に差があるかを検定
前提 母集団分布の仮定不要(各群の分布の形は同じと仮定)
検定統計量 H = \dfrac{12}{N(N+1)} \displaystyle\sum_{i=1}^{k} \dfrac{R_i^2}{n_i} - 3(N+1)
帰無分布 自由度 k - 1 のカイ二乗分布(近似)
パラメトリック版 一元配置分散分析(ANOVA)
2群の場合 ウィルコクソンの順位和検定と等価

Python実装

kruskal_wallis.py
import numpy as np
from scipy import stats

# === クラスカル・ウォリス検定 ===
A = [65, 70, 72]
B = [80, 85, 78, 82]
C = [55, 60, 58, 63]

print("=== クラスカル・ウォリス検定 ===")

# scipy で実行
stat, p_value = stats.kruskal(A, B, C)
print(f"検定統計量 H = {stat:.4f}")
print(f"P値 = {p_value:.4f}")
print()

# 手動計算で検証
all_data = np.array(A + B + C)
groups = ['A']*len(A) + ['B']*len(B) + ['C']*len(C)
ranks = stats.rankdata(all_data)

for g in ['A', 'B', 'C']:
    idx = [i for i, x in enumerate(groups) if x == g]
    r = ranks[idx]
    print(f"群{g}: 順位和={r.sum():.0f}, 順位平均={r.mean():.2f}")

print()

# 式(13.2)による計算
N = len(all_data)
n = [len(A), len(B), len(C)]
R = [ranks[:n[0]].sum(), ranks[n[0]:n[0]+n[1]].sum(), ranks[n[0]+n[1]:].sum()]

H = (12 / (N * (N + 1))) * sum(R[i]**2 / n[i] for i in range(3)) - 3 * (N + 1)
print(f"手動計算: H = {H:.4f}")

# カイ二乗分布の臨界値
df = 2
print(f"自由度{df}のカイ二乗分布:")
print(f"  上側 5% 点: {stats.chi2.ppf(0.95, df):.3f}")
print(f"  上側 1% 点: {stats.chi2.ppf(0.99, df):.3f}")
print(f"  P値: {1 - stats.chi2.cdf(H, df):.4f}")
=== クラスカル・ウォリス検定 === 検定統計量 H = 8.9091 P値 = 0.0116 群A: 順位和=18, 順位平均=6.00 群B: 順位和=38, 順位平均=9.50 群C: 順位和=10, 順位平均=2.50 手動計算: H = 8.9091 自由度2のカイ二乗分布: 上側 5% 点: 5.991 上側 1% 点: 9.210 P値: 0.0116