この連載について
因果推論を「本を読んだ」で終わらせず、自分の言葉で説明でき、コードで再現できる状態まで落とす30日連載です。直前のDay 26では、推定した異質効果を「誰に配るか」の意思決定へつなぐアップリフトモデリングとQini曲線を扱いました。これで道具は出そろいました。
今日は新しい道具を出しません。26日分の道具を「出す前の総点検」として1枚に畳みます。手法選定のフロー図と、設計・調整・推定・解釈の15項目のチェックリストです。各項目に「破ると何が起きるか」を本連載の実測数値で添えたので、連載全体の総索引としても使えます。
TL;DR(3行)
- チェックリストは儀式ではなく「どの仮定を買ったかの申告」です。 因果の主張は必ず、データからは検証できない仮定(非交絡性・除外制約・平行トレンドなど)の上に立ちます ← どの仮定を買ったかを自分で言えるか、が15項目の芯。
- 設計4・調整4・推定4・解釈3の15項目。 破るとどうなるかは本連載で実測済みです。真値ゼロが +2.15 の「有意な効果」に化け(Day 6)、対照群を間違えると効果は -8,498ドル に崩壊し(Day 8)、悪い調整1つで符号が反転します(Day 11)。
- 手法選定は3つの分岐で決まります。 RCTできるか → 交絡をすべて観測できていると信じるか → 外生の割付の断片(てこ・閾値・パネル)はあるか。この順で聞けば、26日分の道具が1枚のフロー図に収まります。
今日の問い
「推定値は3.2で、統計的に有意でした」。数字は出た。
この数字を会議に出す前に、何をどの順で確かめれば、胸を張って「因果効果」と言えるのか?
答えを先に言うと、「すべて確かめれば因果と言い切れる」ようなリストは存在しません。Day 6 の非交絡性も、Day 17 の除外制約も、Day 18 の平行トレンドも、データからは検証できないからです。だからこのチェックリストの目的は合格判定ではありません。自分がどの検証できない仮定を買ったのかを、自覚して申告できる状態を作ることです。飛行機の離陸前チェックが「翼は落ちない」を証明しないのと同じで、確かめられるものを確かめ、確かめられないものを明示する。それが因果推論の報告の作法です。
手法選定フロー、まずどの道具かを決める
チェックリストの前に、そもそもどの道具を選ぶかです。分岐は3つしかありません。「処置を自分で割り付けられるか」「交絡をすべて観測できていると信じられるか」「信じられないなら、外生の割付の断片が転がっていないか」。この順で聞きます。
このフローで大事なのは、矢印を進むたびに買う仮定が変わることです。左上の RCT は設計が仮定を保証してくれる世界、右下へ行くほど「検証できない何か」を信じる量が増えます。どの箱に着地したかは、どの仮定を買ったかの申告そのものです。
なお「誰に効くか」を問う異質効果の系譜(CATE・メタラーナー・Causal Forest・アップリフト、Day 22〜26)は、このフローで着地した識別戦略の上に乗る話です。識別が壊れていれば、どんな高級な学習器も壊れた効果を精密に推定するだけです。
チェックリスト、4カテゴリ×15項目
分析の工程順に、設計 → 調整 → 推定 → 解釈の4カテゴリに分けます。各項目の「破ると何が起きるか」は、ほぼすべて本連載で実際に数値で見せたものです。該当 Day の列が総索引を兼ねます。
設計(データを見る前に決める4項目)
| # | 問い | 破ると何が起きるか | 該当 Day |
|---|---|---|---|
| 1 | 推定対象(estimand)を1つ言えるか。ATE・ATT・CATE・LATE のどれの話か | 手法ごとに違う量を答えているのに1つの「効果」として混ぜて報告する。LATE 2.07 と ATE 3.19 は同じデータの別の量 | 2, 8, 21, 22 |
| 2 | RCT にできないか、部分的にでも実験を仕込めないか検討したか | 実験できたはずの場面で、買わなくてよい仮定(非交絡性)を買う。RCT なら引き算がそのまま因果 | 4, 5 |
| 3 | 処置の定義は1つか。SUTVA(干渉なし・処置のバージョン違いなし)は成り立つか | 「個体の処置効果」の定義自体が崩れる。隣へ効果が漏れる空間データが典型 | 2, 8, 28 |
| 4 | 割付メカニズムを言葉で説明できるか。誰が、なぜ処置を受けたのか | 交絡の当たりがつかず、調整のしようがない。自己選択を放置した素朴な引き算は 4.92(真値3.0) | 6 |
調整(何で条件付けるかを決める4項目)
| # | 問い | 破ると何が起きるか | 該当 Day |
|---|---|---|---|
| 5 | 因果の仮定を DAG に描いて宣言したか。矢印の「無い」ところも仮定だと自覚しているか | 調整セット選びが勘と声の大きさで決まる。仮定が図になっていないと、そもそも議論も反証もできない | 10 |
| 6 | 調整セットはバックドア基準を満たすか。中間変数・合流点・M字を入れていないか | 中間変数で効果が 0.00 に消え、合流点で -0.75 に符号反転し、M字では真の効果ゼロが -0.40 の「効果」に化ける | 11, 16 |
| 7 | オーバーラップはあるか。傾向スコアが 0 や 1 に貼りついた領域はないか | 比較相手のいない領域を外挿で語る。IPW では最大重み 16.7(1人で16.7人分)のような裾が推定を支配する | 6, 7, 8 |
| 8 | 処置後の変数で条件付け・サンプル絞り込みをしていないか | 選択バイアス。回帰に入れるだけでなく、「稼働中の設備だけ」「回答者だけ」と絞る操作も同じ事故を起こす | 10, 11, 16 |
推定(数字の出し方を点検する4項目)
| # | 問い | 破ると何が起きるか | 該当 Day |
|---|---|---|---|
| 9 | 調整が効いた証拠(バランス診断、SMD 目安 0.1)を出したか | 調整したつもりの数字に根拠がない。マッチングでは SMD 2.43 → 0.08 まで潰して初めて比較の土台に乗る | 7, 8 |
| 10 | 推定量やスペックを変えても答えが大きく動かないか確かめたか | スペック1本の数字を握って報告する。同じマッチングでもスペック次第で +2,202 が +513 まで動いた | 8, 15 |
| 11 | 使ったデザイン固有の診断を出したか(第1段階F・プレトレンド・事前適合・バンド幅感度・密度検査) | 弱い操作変数は F≈2 で真値1.0が中央値 1.56 に歪み、RDD はバンド幅次第で -0.03〜+0.10 まで動く。診断なしの点推定は読めない | 17, 18, 19, 20 |
| 12 | 機械学習を推定に使うなら、その作法(残差化・交差適合・標本分割)を踏んだか | 正則化と過学習の癖がそのまま効果推定のバイアスになる。FWL の「残差×残差」が作法の背骨 | 16, 24, 25 |
解釈(報告の書き方を点検する3項目)
| # | 問い | 破ると何が起きるか | 該当 Day |
|---|---|---|---|
| 13 | 検証できない仮定(非交絡性・除外制約・平行トレンド)を報告に明記したか | 読み手が、仮定を買ったことに気づかないまま結論だけ受け取る。真値ゼロでも X 調整後 +2.15、95%CI はゼロから遠く、見かけは「明確な効果」 | 6, 17, 18 |
| 14 | その仮定がどれだけ破れたら結論が覆るか(感度分析)を数字にしたか | 「仮定が正しければ」の但し書きが宙に浮く。E-value 2.35 のような耐性の数字が、仮定と結論の間を埋める | 9 |
| 15 | その効果が「誰の・どこの」効果かを守って書いたか。射程の外へ外挿していないか | RDD の効果はカットオフの際だけ、LATE はコンプライヤーだけ、ATT は共通サポート内だけ。射程を超えた瞬間、根拠のない数字になる | 20, 21, 22 |
15項目のうち、設計の1番と解釈の15番は対になっています。始める前に「どの量を推定するのか」を決め、書き終わる前に「その量の射程を守れたか」を確かめる。この往復が崩れた報告は、途中の推定がどれだけ精密でも読めません。
手を動かす:悪い調整は3行で起きる
コードは今日はこれだけです。チェックリスト6番(悪い調整)が、どれほどあっけなく起きるかを見ます。処置はコイン投げ、つまり完全な RCT で、真の効果は 1.0 です。そこに「処置と結果の両方から矢印が刺さる変数 $c$」を1つ、善意で調整に加えます。
import numpy as np
import pandas as pd
import statsmodels.formula.api as smf
rng = np.random.default_rng(27)
N = 100_000
w = rng.binomial(1, 0.5, N) # 処置はコイン投げ(RCT相当)
y = 1.0 * w + rng.normal(0, 1, N) # 真の効果 τ = 1.0
c = w + y + rng.normal(0, 1, N) # 合流点:処置と結果の両方から矢印が刺さる
d = pd.DataFrame({"w": w, "y": y, "c": c})
print("そのまま = %.2f (真値 1.00)" % smf.ols("y ~ w", d).fit().params["w"])
print("cを調整 = %.2f" % smf.ols("y ~ w + c", d).fit().params["w"])
そのまま = 1.00 (真値 1.00)
cを調整 = 0.00
RCT のきれいな 1.00 が、変数を1つ足しただけで 0.00 に消えました。せっかくの無作為割付も、合流点(Day 10・11)への条件付け1つで台なしです。「とりあえず手元の変数を全部入れる」が因果推論で通用しない理由が、この10行に詰まっています。チェックリストの調整カテゴリは、この事故を出荷前に捕まえるためにあります。
つまづき・誤解しやすい点
- 「15項目すべてに合格=因果の証明」ではありません。 チェックリストが確かめられるのは手続きと診断だけで、芯にある非交絡性(Day 6)や除外制約(Day 17)は原理的に検証できません。全項目に丸が付いた状態は「因果が証明された」ではなく、「どの仮定を買ったかを自覚し、耐性まで開示した」という状態です。それでも、そこまで書かれた報告と書かれていない報告の間には、実務上大きな差があります。
- チェックは分析の後にやるものではありません。 設計カテゴリの4項目はデータを見る前に決める項目です。推定値を見てから estimand を選び直すのは、Day 22 で扱ったサブグループ漁りと同型の事故を、分析の入口で起こしていることになります。Imbens & Rubin が「設計は結果を見ずに済ませよ」と繰り返すのは、まさにこの順序の話です。
- 項目の重みは均等ではありません。 デザインごとに命綱が違います。操作変数なら除外制約(13番)、DID なら平行トレンド(13番と11番のプレトレンド)、RDD なら操作の痕跡(11番の密度検査)、傾向スコア系ならオーバーラップ(7番)。15項目を薄くなぞるより、自分のデザインの命綱1本を深く点検するほうが、報告の質は上がります。
GISデータ実務での使い方
- 評価レポートに「買った仮定」の欄を常設します。 自治体施策の効果検証を出すとき、推定値と信頼区間の隣に、非交絡性・SUTVA など買った仮定と、その耐性(E-value 等)を書く欄を最初からテンプレートに入れておきます。13番と14番を書式で強制する発想です。仮定が書いてあれば、後から反論が来たときに「どの仮定への反論か」を切り分けて議論できます。
- チェックリストは非専門家との共通言語になります。 「バックドア基準」を会議で説明するのは大変ですが、「処置の後に決まる変数で調整していないか」「比較相手のいない自治体を外挿で語っていないか」という問いの形なら、ドメインの専門家のほうがむしろ強いことがあります。項目4(誰がなぜ導入したか)は、現場の人しか答えられません。
- 空間データでは3番と7番が真っ先に壊れます。 隣の自治体へ施策の効果が漏れれば SUTVA(3番)が崩れ、「導入済みは大都市ばかり」ならオーバーラップ(7番)が崩れます。つまり私の主戦場では、チェックリストの一般論だけでは足りません。何がどう壊れ、どこまで救えるのかを、次回まとめて掘ります。
参考(本棚)
- Imbens & Rubin『Causal Inference for Statistics, Social, and Biomedical Sciences』 — 設計を推定に先行させる思想。設計カテゴリの下敷き
- Pearl『入門 統計的因果推論』 — DAG・バックドア・悪い調整。調整カテゴリの下敷き
- Facure『Causal Inference for the Brave and True』 — デザイン固有の診断の実務。推定カテゴリの下敷き
- 安井翔太『効果検証入門』 — セレクションバイアスと報告の実務視点
- T・エドワード・デイマー『誤謬論入門』 — 良い議論の条件。チェックリストを「相手を落とす道具」でなく「自分の議論を強くする道具」として使う姿勢はここから
- 本文のコードは合成データです。乱数シードを含めコピペで再現できます
次回予告(Day 28)
チェックリストの3番(SUTVA)と7番(オーバーラップ)が同時に壊れる場所が、私の主戦場である空間データです。隣り合う自治体は似た未観測要因を共有し(空間交絡)、施策の効果は境界を越えて漏れます(空間干渉)。そのとき「個体の処置効果」という定義自体がどう書き直しになるのか。次回Day 28は、仕上げの3日間の初日として、格子状の合成空間データで何がどう壊れ、どこまで救えるのかを真値を握った状態で確かめます。この連載の独自性の核になる回です。