🎓 レベル:標準 | 重要度:A(必須)
📎 前提:ブートストラップ法 | 統計:ノンパラメトリック検定(符号・順位和・Wilcoxon)
要点(BLUF)
- 並べ替え検定:「2群に差がない」という帰無仮説の下では、データへの群ラベルの割り当ては交換可能——だからラベルをシャッフルして帰無分布を直接作れます。
- 分布(正規性など)を仮定しないノンパラメトリック検定。観測した統計量が、シャッフルで作った帰無分布のどれくらい端にあるかで p 値を出します。
- 2群平均差の並べ替え p 値 0.0006 が t 検定 0.0013 とよく一致。差がない場合は p 値 0.49 で正しく非有意になります。
1. アイデア:ラベルを混ぜて帰無分布を作る
2群 A・B の平均に差があるかを検定したいとします。帰無仮説 「両群は同じ分布から来た(差がない)」が正しいなら、各データがA群かB群かというラベルは無意味で、どう振り直しても同じこと(交換可能性)。
そこで、全データをプールしてラベルをランダムに振り直し(並べ替え)、そのたびに群間差を計算します。これを多数回繰り返すと、**「差がない世界での群間差の分布(帰無分布)」**が得られます。観測した実際の差が、この帰無分布のどれくらい端(極端)にあるかが p 値です。
flowchart LR
D["A群とB群を一つにプール"] --> S["ラベルをシャッフル"]
S --> C["群間差を計算"]
C -->|"P回繰り返す"| H["帰無分布"]
H --> P["観測差の位置 = p値"]
2. 実装:2群の平均差を検定する
A群 、B群 (真に差がある)で検定し、t 検定と比べます。
import numpy as np
from scipy import stats
# 乱数シードを固定
rng = np.random.default_rng(52)
A = rng.normal(0.0, 1.0, 40)
B = rng.normal(0.5, 1.0, 40)
observed = B.mean() - A.mean()
combined = np.concatenate([A, B])
nA = len(A)
P = 20000
perm_diffs = np.empty(P)
for p in range(P):
rng.shuffle(combined) # ラベルをシャッフル
perm_diffs[p] = combined[nA:].mean() - combined[:nA].mean()
p_perm = (np.abs(perm_diffs) >= np.abs(observed)).mean() # 両側p値
t_stat, p_t = stats.ttest_ind(B, A)
print(f"観測した差 = {observed:.4f}")
print(f"並べ替え検定 p値 = {p_perm:.4f}")
print(f"t検定 p値 = {p_t:.4f}")
出力:
観測した差 = 0.6730
並べ替え検定 p値 = 0.0006
t検定 p値 = 0.0013
出力の意味:観測した群間差 0.673 は、ラベルをシャッフルして作った帰無分布のごく端(両側 p=0.0006)にあり、有意。正規性を仮定する t 検定(p=0.0013)とほぼ同じ結論ですが、並べ替え検定は分布を一切仮定していません。両者が近いのは、今回データが実際に正規だから。正規でない・小標本・外れ値があるときは、並べ替え検定の方が頑健です。
3. 帰無が正しいときは有意にならない
検定が正しく機能するには、差がないとき( が真)に有意になりすぎないことが必要です。両群を同じ から取って確かめます。
import numpy as np
# 乱数シードを固定
rng = np.random.default_rng(53)
A = rng.normal(0, 1, 40)
B = rng.normal(0, 1, 40) # 真に差がない
observed = B.mean() - A.mean()
combined = np.concatenate([A, B])
P = 20000
perm = np.empty(P)
for p in range(P):
rng.shuffle(combined)
perm[p] = combined[40:].mean() - combined[:40].mean()
print(f"観測した差 = {observed:.4f}")
print(f"並べ替え検定 p値 = {(np.abs(perm) >= np.abs(observed)).mean():.4f}")
出力:
観測した差 = 0.1801
並べ替え検定 p値 = 0.4869
出力の意味:真に差がない2群では、観測差 0.18 は帰無分布のごく普通の位置にあり、p=0.49(有意でない)。検定が誤って差を主張しない(第一種の過誤を制御している)ことの確認です。並べ替え検定は、 の下での正確な(exact、有限標本で厳密な)検定になりうる点が理論的な美点です。
4. 使いどころ
- 適用範囲:2群比較に限らず、相関の有無・対応のあるデータ・任意の検定統計量に拡張できます。「 の下で何が交換可能か」を見極めるのが鍵。
- 長所:分布を仮定しない・小標本でも使える・任意の統計量(中央値差・トリム平均差など)で検定できる。
- 計算:全並べ替えは 通りで爆発するので、ランダムに 回サンプリングするモンテカルロ並べ替え検定が実用。p 値の精度は 。
- ブートストラップ検定とは似て非なるもの:並べ替えはラベルのシャッフル(非復元)、ブートストラップは復元抽出。検定には並べ替えが素直です。
数式の直観的意味
並べ替え検定は「もし群分けが本当に意味を持たないなら、いま観測したような差は偶然どれくらい出るか」を、実際にラベルを混ぜて数える操作です。 の核心は交換可能性(exchangeability)——データの並び順・群ラベルが結果に関係ないこと。これが成り立つなら、観測されたラベル配置は「ありうる全配置のひとつ」にすぎず、特別扱いする理由がない。だから全配置(の標本)に対する観測差の順位が、そのまま有意性になる。t 検定が「正規分布という理論的な帰無分布」を使うのに対し、並べ替え検定は「データ自身をシャッフルした経験的な帰無分布」を使う——理論分布をデータ駆動の帰無分布に置き換えたのが本質で、これが頑健性の源です。
⚠️ よくある誤解・落とし穴
- 「並べ替えは復元抽出」ではない:ラベルの**シャッフル(非復元)**です。復元するとブートストラップ検定になり、帰無分布が変わります。
- 「正規性が要る」ではない:要りません。それが最大の利点。分布を仮定せず正確な検定ができます。
- 「全並べ替えが必要」ではない:通常は組合せが爆発するので、ランダムに 回で近似(モンテカルロ並べ替え)。
- 「交換可能性は常に成り立つ」ではない:分散が群間で大きく違う・データに依存構造があると交換可能でなく、検定が無効に。前提の確認が要ります。
- 「p=0 になりうる」ではない:観測差より極端な並べ替えが0個でも、 程度を下限とするのが安全(連続性補正)。
対応シミュレーション参照
本文の2群平均差の並べ替え検定(差あり default_rng(52)/差なし default_rng(53))。
関連ノート
- ブートストラップ法(前提・復元抽出との対比)
- ブートストラップ信頼区間(次のトピック・区間推定)
- ジャックナイフ法(別のリサンプリング)
- ノンパラメトリック検定(符号・順位和・Wilcoxon)(統計・検定の理論)
- 第8章 ブートストラップとリサンプリング 目次
- シミュレーション・モンテカルロ法 全体目次