🎓 レベル:基礎 | 重要度:A(必須)
📎 前提:潜在結果モデル | 識別の仮定 | 数理:フィッシャーの3原則(統計)
要点(BLUF)
- ランダム化(無作為割り当て)は、処置 を潜在結果 から独立にする。これにより交換可能性(ignorability)が「データ収集の設計段階で」保証され、交絡を断てる。
- だから RCT では「素朴な群間差」がそのまま平均処置効果(ATE)の不偏推定になる。観察データではこれが成り立たず、素朴な差は交絡バイアスを含む。
- 同じ母集団から (a) 交絡のある観察データと (b) ランダム割り当てした RCT を作ると、真値 に対し観察の素朴差は (治療が有害に見える!)、RCT の素朴差は になる。
1. 問題:観察データの素朴な比較はなぜ危ういか
「治療を受けた人」と「受けなかった人」の結果を単純に引き算しても、それが治療の効果とは限らない。両群が治療以外の点でも違うからだ。
典型例:重症の患者ほど治療を受けやすい。重症の患者は(治療してもなお)予後が悪い。すると「治療群=重症で予後が悪い人の集まり」「対照群=軽症で予後が良い人の集まり」になり、治療そのものは有効でも、群間差は治療を有害に見せる。これが交絡(confounding)だ。
flowchart LR
C["交絡C(重症度)"] --> T["処置T(治療する)"]
C --> Y["結果Y(回復スコア)"]
T --> Y
処置 と結果 の間には、 というバックドアパスが開いている(バックドア基準と識別)。素朴な比較はこの裏口の影響を効果と混同する。
2. ランダム化が断つもの:識別の仮定
ランダム化は、 から へ伸びる矢印を設計で消す。割り当てをコイン投げで決めれば、 は重症度 とも、その他あらゆる(既知・未知の)背景要因とも独立になる。
flowchart LR
C["交絡C(重症度)"] --> Y["結果Y(回復スコア)"]
R["ランダム化(コイン投げ)"] --> T["処置T"]
T --> Y
の矢印が消え、バックドアパスが塞がれた。これが RCT の核心だ。
因果効果を識別する3つの仮定
平均処置効果 を素朴な差で推定してよいための条件は次の3つ(識別の仮定)。
- 交換可能性(交換可能性 / ignorability):。処置の割り当てが潜在結果と独立。ランダム化はこれを設計で保証する(観察データでは仮定するしかない)。
- 正値性(positivity):。どの個体も両方の処置を取りうる。割り当て確率を など と の間に固定すれば自動的に満たす。
- SUTVA:他人の処置が自分の結果に影響しない(干渉なし)+ 一貫性 。
なぜ素朴な差が ATE になるか(導出)
観測される群間差を、一貫性で潜在結果に書き換え、 を足して引く。
第2項の選択バイアスは「もし両群とも未処置だったときの差」。観察データではここが にならない(処置群の方が元々重症= が低い)。
ランダム化のもとでは なので、条件づけが外れて
となり、選択バイアスは 、ATT は ATE に一致する。よって
素朴な差が、何の調整もなしに ATE の不偏推定になる。これが「RCT が黄金律」と呼ばれる数理的な理由だ。
3. コード:同じ母集団から観察データとRCTを作って比べる
真の効果を と仕込んだ潜在結果を作り、(a) 重症者ほど治療されやすい観察データと (b) コイン投げのRCT で、それぞれ素朴な差を計算する。あわせて交絡 の群間バランスも見る。
import numpy as np
import pandas as pd
# === 同じ母集団から「観察データ」と「RCTデータ」を作り、素朴な差を比べる ===
rng = np.random.default_rng(42)
n = 20000
# 真の処置効果(治療で回復スコアが +3 される。全員一定)
ATE_true = 3.0
# 交絡 C:ベースラインの重症度(高いほど重症=放っておくと回復スコアが低い)
C = rng.normal(0.0, 1.0, size=n)
# 潜在結果:Y(0) は重症度が高いほど低い。Y(1) = Y(0) + 効果
Y0 = 50.0 - 8.0 * C + rng.normal(0.0, 3.0, size=n)
Y1 = Y0 + ATE_true
# --- (a) 観察データ:重症な人ほど治療を受けやすい(医師の判断=交絡)---
p_treat_obs = 1.0 / (1.0 + np.exp(-2.0 * C)) # シグモイド:C が高いほど治療されやすい
T_obs = rng.binomial(1, p_treat_obs)
Y_obs = np.where(T_obs == 1, Y1, Y0) # 実際に観測される結果(一貫性)
# --- (b) RCT:コイン投げで治療を割り当て(C と独立)---
T_rct = rng.binomial(1, 0.5, size=n)
Y_rct = np.where(T_rct == 1, Y1, Y0)
# 素朴な群間差(処置群の平均 - 対照群の平均)
naive_obs = Y_obs[T_obs == 1].mean() - Y_obs[T_obs == 0].mean()
naive_rct = Y_rct[T_rct == 1].mean() - Y_rct[T_rct == 0].mean()
print(f"真の効果 ATE_true = {ATE_true:+.3f}")
print(f"観察データの素朴な差 = {naive_obs:+.3f} (バイアスあり)")
print(f"RCT の素朴な差 = {naive_rct:+.3f} (ほぼ真値)")
# 共変量バランス:交絡 C の群間平均
print("\n--- 共変量 C のバランス(治療群 vs 対照群の平均)---")
print(f"観察データ: 治療群 C={C[T_obs==1].mean():+.3f} 対照群 C={C[T_obs==0].mean():+.3f} 差={C[T_obs==1].mean()-C[T_obs==0].mean():+.3f}")
print(f"RCT : 治療群 C={C[T_rct==1].mean():+.3f} 対照群 C={C[T_rct==0].mean():+.3f} 差={C[T_rct==1].mean()-C[T_rct==0].mean():+.3f}")
出力:
真の効果 ATE_true = +3.000
観察データの素朴な差 = -6.684 (バイアスあり)
RCT の素朴な差 = +3.008 (ほぼ真値)
--- 共変量 C のバランス(治療群 vs 対照群の平均)---
観察データ: 治療群 C=+0.608 対照群 C=-0.605 差=+1.213
RCT : 治療群 C=+0.003 対照群 C=+0.007 差=-0.003
出力の意味:真の効果は (治療は有益)なのに、観察データの素朴な差は 。治療が有害に見えるという深刻な逆転だ。原因は共変量バランスを見れば一目瞭然で、観察データでは治療群の重症度 が対照群より も高い(重症者に治療が集中している)。一方 RCT では素朴な差が とほぼ真値で、 の群間差は = ランダム化が交絡 を自動でバランスさせている。コードでは を使って調整など一切していない点に注目してほしい。ランダム化は「未知の交絡すら」バランスさせるので、調整する変数を知らなくてよいのが強みだ。
4. コード:素朴な差の「標本分布」を見る
1回の実験では偶然で当たることもある。多数回くり返したときに推定値の中心(平均)が真値に一致するか=不偏性をモンテカルロで確かめる。
import numpy as np
import matplotlib.pyplot as plt
import japanize_matplotlib
# === モンテカルロ:素朴な差の「分布」が真値を中心にするか確かめる ===
rng = np.random.default_rng(7)
ATE_true = 3.0
n = 500 # 1回の実験のサンプルサイズ
n_rep = 3000 # 実験を何回繰り返すか
naive_obs_list = []
naive_rct_list = []
for _ in range(n_rep):
C = rng.normal(0.0, 1.0, size=n)
Y0 = 50.0 - 8.0 * C + rng.normal(0.0, 3.0, size=n)
Y1 = Y0 + ATE_true
# 観察データ:重症者ほど治療されやすい
p_obs = 1.0 / (1.0 + np.exp(-2.0 * C))
T_obs = rng.binomial(1, p_obs)
Y_obs = np.where(T_obs == 1, Y1, Y0)
naive_obs_list.append(Y_obs[T_obs == 1].mean() - Y_obs[T_obs == 0].mean())
# RCT:ランダム割り当て
T_rct = rng.binomial(1, 0.5, size=n)
Y_rct = np.where(T_rct == 1, Y1, Y0)
naive_rct_list.append(Y_rct[T_rct == 1].mean() - Y_rct[T_rct == 0].mean())
naive_obs_arr = np.array(naive_obs_list)
naive_rct_arr = np.array(naive_rct_list)
print(f"真の効果 ATE_true = {ATE_true:+.3f}")
print(f"観察データ 素朴差の平均 = {naive_obs_arr.mean():+.3f} (真値から大きくずれる=バイアス)")
print(f"RCT 素朴差の平均 = {naive_rct_arr.mean():+.3f} (真値とほぼ一致=不偏)")
print(f"RCT 素朴差の標準偏差 = {naive_rct_arr.std():.3f}")
plt.figure(figsize=(8, 4.5))
plt.hist(naive_obs_arr, bins=40, alpha=0.6, label="観察データの素朴な差")
plt.hist(naive_rct_arr, bins=40, alpha=0.6, label="RCT の素朴な差")
plt.axvline(ATE_true, color="red", linestyle="--", linewidth=2, label="真の効果 ATE=3")
plt.xlabel("推定された処置効果")
plt.ylabel("頻度")
plt.title("素朴な群間差の標本分布:観察データは偏り、RCTは真値を中心にする")
plt.legend()
plt.tight_layout()
plt.show()
出力:
真の効果 ATE_true = +3.000
観察データ 素朴差の平均 = -6.703 (真値から大きくずれる=バイアス)
RCT 素朴差の平均 = +3.016 (真値とほぼ一致=不偏)
RCT 素朴差の標準偏差 = 0.773
出力の意味:3000回くり返しても観察データの分布は を中心に固まっている。サンプルを増やしてもこのズレは消えない(バイアスは系統的で、 を増やすと「間違った値」に正確に収束する)。RCT の分布は真値 を中心に対称に散らばり、平均は 。RCT の素朴差は不偏で、ばらつき(標準偏差 )は を増やせば縮む。「偏り(bias)」と「ばらつき(variance)」は別物で、RCT が解決するのは偏りの方だ。ばらつきを縮める工夫は次の 共変量調整と層別とブロック化 で扱う。
5. 直観:なぜランダム化で「独立」になるのか
潜在結果 は、実験前から各個体にすでに張りついている固定値だ(重症者は が低い、など)。コイン投げは、この潜在結果の中身を一切見ずに を決める。見ずに決めた以上、 がどちらになるかは潜在結果と確率的に無関係=独立になる。
これは フィッシャーの3原則 の無作為化そのものだ。無作為化は「未知の系統的な偏りを偶然のばらつきに変換する」。因果の言葉でいえば「交絡バイアスを、推定量のばらつき(標準誤差)に付け替える」操作にあたる。だから RCT でも標準誤差は残る(消えるのは偏りだけ)。
| 観察データ | RCT | |
|---|---|---|
| 交換可能性 | 仮定するしかない(成り立つ保証なし) | 設計で保証される |
| 未知の交絡 | 調整できない(測っていない) | 自動でバランス |
| 素朴な差 | 偏る | ATE の不偏推定 |
| 残る課題 | 偏り+ばらつき | ばらつきのみ |
⚠️ よくある誤解・落とし穴
(1)小標本では1回のランダム化でも偶然の不均衡が起きる ランダム化が保証するのは「平均的に(期待値で)バランスする」こと。 が小さい1回の実験では、たまたま重症者が片群に偏ることがある。これに備えるのがブロック化・層別(共変量調整と層別とブロック化)で、既知の予後因子は設計で釣り合わせておくとよい。
(2)「RCTなら何もしなくてよい」ではない 不偏なのは「割り当てが完全に守られ、脱落がランダム」な理想状態の話。実際には非遵守(割り当てと違う行動)や脱落が起きると、素朴な差は崩れる。これは 非遵守とITT で扱う。
(3)SUTVAの干渉 ワクチン・SNS・教室介入などでは、他人の処置が自分の結果に波及する(集団免疫・ネットワーク効果)。このとき個体レベルの が定義できず、RCT でも素朴な解釈が崩れる。クラスター無作為化などの設計で対処する。
(4)外的妥当性(一般化可能性) RCT が保証するのは「その実験集団における」内的妥当性(バイアスのなさ)。被験者が母集団と違えば(例:健康な志願者ばかり)、得られた ATE を現実の対象に外挿してよいかは別問題。ランダム化はサンプル内の交絡を断つが、サンプル選択の偏りは断たない。
関連ノート
- 因果:潜在結果モデル/バックドア基準と識別/識別の仮定
- 因果(次):共変量調整と層別とブロック化(ばらつきを下げる)/非遵守とITT(割り当てが守られないとき)
- 観察データで交絡を断つ方へ:回帰による調整とその限界
- 統計(数理的土台):フィッシャーの3原則/推定量の評価(MSE・フィッシャー情報量・クラメール・ラオの不等式)(不偏性・分散)