🎓 レベル:標準 | 重要度:B(標準)
📎 前提:なぜRCTが黄金律か | 次:操作変数法と2SLS(IVの本格展開)
要点(BLUF)
- 現実のRCTでは**非遵守(noncompliance)**が起きる。治療に割り当てても飲まない人、対照に割り当てても入手して飲む人がいる。割り当て と実際の処置 が食い違う。
- ITT(intention-to-treat)=割り当てによる効果は不偏だが、非遵守で希釈される。as-treated(実際に飲んだか で比較)は自己選択で偏る。
- 遵守者だけの効果 LATE(=CACE) は Wald 推定量 で回収できる。真の LATE に対し、ITT は (希釈)、as-treated は (偏り)、Wald は 。これは操作変数法(操作変数法と2SLS)の最も単純な形だ。
1. 非遵守とは何か
割り当て (ランダム)と、実際に受けた処置 を区別する。
- (処置に割り当て)でも (飲まない)人がいる。
- (対照に割り当て)でも (手に入れて飲む)人がいる。
問題は、誰が遵守し誰がしないかが、その人の性質(健康度・意欲)と結びついていること。「自分の判断で飲んだ/飲まなかった」という選択は、結果に効く隠れた要因 と相関する。だから「実際に飲んだ人 vs 飲まなかった人」を比べると、ランダム化で断ったはずの交絡が裏口から戻ってくる。
flowchart LR
Z["割り当てZ(ランダム)"] --> D["実際の服用D"]
U["潜在的な型U(遵守傾向・健康度)"] --> D
U --> Y["結果Y"]
D --> Y
はランダムなので と独立()。だが は の影響を受ける。 で群分けすると のバックドアが開く。一方 で群分けすれば、 は と独立なのでこの裏口は開かない。「ランダムなのは であって ではない」——これが全ての出発点だ。
2. 4つのタイプ(principal strata)
割り当てに対する反応で母集団を4つに分ける。
| 型 | のとき | のとき | 説明 |
|---|---|---|---|
| 遵守者(complier) | 割り当て通りに行動 | ||
| 常用者(always-taker) | 割り当てに関係なく必ず処置を受ける | ||
| 不服用者(never-taker) | 割り当てに関係なく決して受けない | ||
| 天邪鬼(defier) | 割り当てと逆。単調性で除外 |
各個体の型は観測できない( は片方しか見られない)。だが割り当てがランダムなので、4タイプの構成比は 群と 群で同じ。この対称性が後の識別を可能にする。
3. 3つの推定量:ITT・as-treated・LATE
**ITT(intention-to-treat)**は「割り当てられたこと」の効果。実際に飲んだかは問わない。
はランダムなので ITT は不偏。ただし測っているのは「処置を提供することの効果」で、非遵守者が混ざるぶん「処置を受けることの効果」より薄まる(希釈)。
第1段階は、割り当てが実際の服用をどれだけ動かしたか。単調性のもとでこれは遵守者の割合に等しい。
**LATE(local average treatment effect)= CACE(complier average causal effect)**は、遵守者に限った処置効果。Wald 推定量で識別される。
直観:ITT は「遵守者だけが処置の有無を切り替わる」効果を、全体(遵守者+非遵守者)で薄めたもの。だから遵守者割合 で割り戻せば、遵守者あたりの効果に復元できる。
**as-treated(per-protocol の素朴版)**は、実際に飲んだか で比較する。
これは の交絡を含むので偏る。常用者(元々健康で予後が良い)が 側に、不服用者が 側に固まるためだ。
識別の仮定(Angrist–Imbens–Rubin)
LATE が Wald 推定量で識別されるための条件:
- SUTVA(干渉なし・一貫性)。
- ランダム割り当て:。RCTで保証。
- 除外制約(exclusion restriction): は を通してのみ に影響( から への直接の矢印がない)。割り当てそれ自体が結果を動かさない。
- 単調性(monotonicity):天邪鬼がいない(割り当てが処置を減らす人はいない)。
- 関連性(relevance):(遵守者が存在する=第1段階が効いている)。
4. コード:ITT・as-treated・Wald を比べる
遵守者 /常用者 /不服用者 の擬似データを作る。遵守者への真の効果(=LATE)を と仕込み、ITT・as-treated・Wald がそれぞれ何を当てるかを見る。タイプによってベースラインと効果が異なる(異質)点に注意。
import numpy as np
import pandas as pd
# === 非遵守のある擬似データ:ITT・as-treated・Wald(LATE) を比べる ===
rng = np.random.default_rng(42)
n = 40000
# 真のLATE(遵守者[complier]に対する治療の効果)を 4 と仕込む
LATE_true = 4.0
# 3つのタイプ:遵守者 0.5 / 常用者(always-taker) 0.2 / 不服用者(never-taker) 0.3
types = rng.choice(["complier", "always", "never"], size=n, p=[0.5, 0.2, 0.3])
# Z:ランダムな割り当て(操作変数)。コイン投げ
Z = rng.binomial(1, 0.5, size=n)
# D:実際の服用。タイプと割り当てから決まる
D = np.zeros(n, dtype=int)
D[types == "always"] = 1 # 常用者は割り当てに関係なく服用
D[types == "never"] = 0 # 不服用者は割り当てに関係なく服用しない
D[types == "complier"] = Z[types == "complier"] # 遵守者は割り当て通り
# 潜在結果:タイプ別ベースライン + 服用したときの効果(遵守者の効果= LATE_true)
baseline = np.where(types == "complier", 10.0,
np.where(types == "always", 14.0, 8.0)) # 常用者は元々高い、不服用者は低い
effect = np.where(types == "complier", LATE_true,
np.where(types == "always", 1.0, 10.0)) # タイプで効果が異なる(異質)
Y = baseline + effect * D + rng.normal(0.0, 2.0, size=n)
df = pd.DataFrame({"types": types, "Z": Z, "D": D, "Y": Y})
# ITT:割り当て Z による効果(実際に服用したかは問わない)
ITT_Y = df.loc[df.Z == 1, "Y"].mean() - df.loc[df.Z == 0, "Y"].mean()
# 第1段階(コンプライアンス率)= 割り当てが服用をどれだけ動かしたか
ITT_D = df.loc[df.Z == 1, "D"].mean() - df.loc[df.Z == 0, "D"].mean()
# Wald推定量 = ITT_Y / ITT_D(=LATE)
wald = ITT_Y / ITT_D
# as-treated(実際に服用したか D で素朴に比較)
as_treated = df.loc[df.D == 1, "Y"].mean() - df.loc[df.D == 0, "Y"].mean()
print(f"真のLATE(遵守者への効果) = {LATE_true:+.3f}")
print(f"ITT (割り当て効果, 服用問わず) = {ITT_Y:+.3f} ← 非遵守で希釈され過小")
print(f"第1段階 ITT_D(コンプライアンス率) = {ITT_D:+.3f} ← 遵守者の割合 0.5")
print(f"as-treated(実服用で素朴比較) = {as_treated:+.3f} ← 自己選択でバイアス")
print(f"Wald = ITT_Y / ITT_D = {wald:+.3f} ← LATEを回収")
# IV(操作変数)としての等価性:cov(Y,Z)/cov(D,Z) も同じ値
iv = np.cov(Y, Z, ddof=1)[0, 1] / np.cov(D, Z, ddof=1)[0, 1]
print(f"IV cov(Y,Z)/cov(D,Z) = {iv:+.3f} ← Waldと一致(2SLSの単純版)")
出力:
真のLATE(遵守者への効果) = +4.000
ITT (割り当て効果, 服用問わず) = +1.982 ← 非遵守で希釈され過小
第1段階 ITT_D(コンプライアンス率) = +0.496 ← 遵守者の割合 0.5
as-treated(実服用で素朴比較) = +5.566 ← 自己選択でバイアス
Wald = ITT_Y / ITT_D = +4.000 ← LATEを回収
IV cov(Y,Z)/cov(D,Z) = +4.000 ← Waldと一致(2SLSの単純版)
出力の意味:3つの推定量がきれいに分かれた。ITT は不偏だが「割り当ての効果」であって、非遵守者が混ざるぶん真の処置効果 より小さい(希釈)。as-treated は真値を大きく超える——常用者(ベースライン で高い)が 側に集まる自己選択バイアスだ。Wald だけが真の LATE を回収した。 という割り算が効いている。最後の行は、Wald が共分散比 と同一=操作変数法の単純な姿であることを示す。
5. コード:標本分布で「何を中心にするか」を確認
1回の推定では偶然当たることもある。多数回くり返して、各推定量が何を中心にするかを見る。
import numpy as np
import matplotlib.pyplot as plt
import japanize_matplotlib
# === モンテカルロ:ITT・as-treated・Wald の標本分布を比べる ===
rng = np.random.default_rng(99)
LATE_true = 4.0
n = 3000
n_rep = 3000
itt_list, attr_list, wald_list = [], [], []
for _ in range(n_rep):
types = rng.choice(["complier", "always", "never"], size=n, p=[0.5, 0.2, 0.3])
Z = rng.binomial(1, 0.5, size=n)
D = np.zeros(n, dtype=int)
D[types == "always"] = 1
D[types == "complier"] = Z[types == "complier"]
baseline = np.where(types == "complier", 10.0,
np.where(types == "always", 14.0, 8.0))
effect = np.where(types == "complier", LATE_true,
np.where(types == "always", 1.0, 10.0))
Y = baseline + effect * D + rng.normal(0.0, 2.0, size=n)
itt_y = Y[Z == 1].mean() - Y[Z == 0].mean()
itt_d = D[Z == 1].mean() - D[Z == 0].mean()
itt_list.append(itt_y)
wald_list.append(itt_y / itt_d)
attr_list.append(Y[D == 1].mean() - Y[D == 0].mean())
itt_arr = np.array(itt_list)
attr_arr = np.array(attr_list)
wald_arr = np.array(wald_list)
print(f"真のLATE = {LATE_true:+.3f}")
print(f"ITT 平均={itt_arr.mean():+.3f} (希釈され過小)")
print(f"as-treated平均={attr_arr.mean():+.3f} (自己選択でバイアス)")
print(f"Wald 平均={wald_arr.mean():+.3f} SD={wald_arr.std():.3f} (LATEを回収)")
plt.figure(figsize=(8, 4.5))
plt.hist(itt_arr, bins=40, alpha=0.55, label="ITT")
plt.hist(attr_arr, bins=40, alpha=0.55, label="as-treated")
plt.hist(wald_arr, bins=40, alpha=0.55, label="Wald (LATE)")
plt.axvline(LATE_true, color="red", linestyle="--", linewidth=2, label="真のLATE=4")
plt.xlabel("推定値")
plt.ylabel("頻度")
plt.title("ITT・as-treated・Wald の標本分布:Waldだけが真のLATEを中心にする")
plt.legend()
plt.tight_layout()
plt.show()
出力:
真のLATE = +4.000
ITT 平均=+1.997 (希釈され過小)
as-treated平均=+5.535 (自己選択でバイアス)
Wald 平均=+3.992 SD=0.169 (LATEを回収)
出力の意味:3000回の反復で、ITT は 、as-treated は を中心に固まる——どちらも を増やしても真の LATE には寄らない(系統的なズレ)。Wald だけが = 真値を中心にする。ヒストグラムでも Wald の山だけが赤い破線()に乗る。「不偏な ITT」と「真の処置効果」は別物で、両者を橋渡しするのが第1段階による割り戻し(Wald)だと視覚的に分かる。
6. ITT は無意味か:使い分け
希釈されるからといって ITT が劣るわけではない。問いが違うだけだ。
- ITT が答える問い:「この処置を提供する政策に効果はあるか?」薬を処方しても飲まない人がいる現実込みの、政策・運用の効果。規制当局の薬事審査が ITT を主軸にするのはこのため(飲まない人を除外すると都合よく見えてしまう)。
- LATE が答える問い:「処置を実際に受けたら(遵守者にとって)効果はあるか?」生物学的・機序的な効果に近い。
- as-treated/per-protocol:自己選択バイアスを持ち込むので、因果効果としては基本的に信用しない。
LATE の弱点は 「遵守者」という観測できない部分集団の効果である点(外的妥当性)。遵守者割合が小さい(弱い操作変数)と Wald の分母が小さく、推定が不安定になる。
⚠️ よくある誤解・落とし穴
(1)「飲んだ人だけ/プロトコルを守った人だけ」で分析する誘惑 最もやりがちな誤り。(実際の服用)や遵守状況で対象を絞った瞬間、ランダム化の保護が消えて交絡が戻る。ランダムなのは だけ、を忘れない。
(2)除外制約は検証できない仮定 Wald が LATE になる鍵は「 が を通してのみ に効く」こと。割り当てを知ること自体が行動を変える(プラセボ効果、ホーソン効果)と崩れる。盲検化はこの仮定を守るための装置。
(3)弱い操作変数(遵守率が低い) が小さいと は に近い数での割り算になり、ばらつき・偏りが拡大する。第1段階の強さ(遵守率)を必ず確認する。詳細は 操作変数法と2SLS。
(4)LATE を ATE と混同する LATE は「遵守者」限定の効果。常用者・不服用者には外挿できない。本コードでも全体平均効果は で LATE と一致しない。データから識別できるのは遵守者ぶんだけ、という限界を明示する。
関連ノート
- 因果:なぜRCTが黄金律か(理想のRCT。本ノートはその破れ)/ABテストの設計と分析(Webでも非遵守は起きる)
- 次(IVの本格展開):操作変数法と2SLS(Wald=最も単純なIV。複数の操作変数・共変量込みへ一般化)
- 識別の枠組み:識別の仮定