Mímisbrunnr知恵の泉

← 因果推論 一覧

🎓 レベル:基礎 | 重要度:A(必須)

📎 前提:因果ダイアグラムとd分離 | 次に読む:識別の仮定 | 数理:重回帰分析(統計)・交絡の調整(統計)

要点(BLUF)

1. 識別とは何か

因果効果(例:ATE)は反事実 Y(1),Y(0)Y(1),Y(0) で定義されますが、反事実は片方しか観測できません(潜在結果モデル)。そこで問うのが 識別 です。

観測できる量(X,Y,ZX,Y,Z の同時分布)だけを使って、因果効果を一意な式で表せるか?

表せれば「識別可能(identifiable)」。あとはその式を有限データで推定するだけ(回帰による調整とその限界 以降)。表せなければ、どれだけデータを集めても因果は出ません。識別と推定を分けるのが因果推論の作法です。バックドア基準は「交絡を調整すれば識別できる」ための、DAG 上の十分条件を与えます。

2. バックドアパスと調整の狙い

XXYY の間の経路のうち、XX に矢印が入って始まる経路バックドアパス と呼びます。下の DAG では XCYX \leftarrow C \rightarrow Y がそれです。バックドアパスは交絡由来の見せかけの相関を運ぶので、塞ぎたい。一方 XYX\to Y(および XMYX\to M\to Y)の因果的経路は残したい

flowchart LR
  C["交絡 C"] --> X["処置 X"]
  C --> Y["結果 Y"]
  X --> M["媒介 M"] --> Y
  X --> K["合流点 K"]
  Y --> K
  X -.->|"直接効果"| Y

この図には罠が3つあります。

3. バックドア基準と調整公式

バックドア基準(Pearl):変数集合 ZZ が順序対 (X,Y)(X,Y) に関してバックドア基準を満たすとは、

このとき ATE は バックドア調整公式(adjustment formula) で識別されます。離散の ZZ なら

P ⁣(Ydo(X=x))  =  zP ⁣(YX=x,Z=z)P(Z=z)P\!\left(Y \mid do(X{=}x)\right) \;=\; \sum_{z} P\!\left(Y \mid X{=}x,\, Z{=}z\right)\,P(Z{=}z)

であり、平均処置効果は各層の効果を ZZ の分布で加重した形になります。

ATE  =  EZ ⁣[E[YX=1,Z]E[YX=0,Z]]\text{ATE} \;=\; E_{Z}\!\Big[\, E[Y \mid X{=}1, Z] - E[Y \mid X{=}0, Z] \,\Big]

ポイントは、右辺がすべて観測できる条件付き期待値と ZZ の分布で書けていること。これが「識別できた」状態です。条件 (a) は「媒介や合流点を間違って入れるな」、(b) は「交絡を取りこぼすな」に対応します。

4. 擬似データで「正しい調整」と「誤った調整」を対比する

第2節の DAG をそのまま構造方程式にして、真の総合効果を ATEtrue=2.0\text{ATE}_\text{true}=2.0(直接 1.01.0+媒介 2.0×0.5=1.02.0\times0.5=1.0)と仕込みます。回帰の XX の係数で効果を推定し、調整集合を変えて当たり外れを見ます。

import numpy as np
import statsmodels.api as sm

# === バックドア:正しい調整集合は真値を当て、合流点/媒介を誤調整すると外す ===
rng = np.random.default_rng(2)
n = 40000

# 構造方程式モデル(SCM)
C = rng.normal(0, 1, n)                       # 交絡(C→X, C→Y)
X = 0.8 * C + rng.normal(0, 1, n)             # 処置
M = 0.5 * X + rng.normal(0, 1, n)             # 媒介 X→M→Y
b_X, b_M, b_C = 1.0, 2.0, 1.5
Y = b_X * X + b_M * M + b_C * C + rng.normal(0, 1, n)
K = 0.7 * X + 0.7 * Y + rng.normal(0, 1, n)   # 合流点 X→K←Y

# 真の総合効果 = 直接 1.0 + 媒介 2.0×0.5 = 2.0
ATE_true = b_X + b_M * 0.5
print(f"真の総合効果 ATE = {ATE_true:.3f}\n")


def beta_on_X(extra_cols):
    design = sm.add_constant(np.column_stack([X] + extra_cols))
    return sm.OLS(Y, design).fit().params[1]   # 定数の次が X の係数


print(f"素朴 (調整なし)    Y~X      : {beta_on_X([]):.3f}")
print(f"交絡Cで調整(正解)  Y~X+C    : {beta_on_X([C]):.3f}")
print(f"媒介Mも調整(過剰)  Y~X+C+M  : {beta_on_X([C, M]):.3f}")
print(f"合流Kも調整(誤り)  Y~X+C+K  : {beta_on_X([C, K]):.3f}")

出力:

真の総合効果 ATE = 2.000

素朴 (調整なし)    Y~X      : 2.720
交絡Cで調整(正解)  Y~X+C    : 1.991
媒介Mも調整(過剰)  Y~X+C+M  : 1.005
合流Kも調整(誤り)  Y~X+C+K  : -0.132

出力の意味:4つの調整を真値 2.02.0 と照らします。

「とにかく多く調整する」が安全でないことが数値で分かります。何を入れ、何を入れないかを DAG とバックドア基準で決める——これが識別の実務です。

5. 仮定の直観的意味:なぜ条件 (a)(b) なのか

要するにバックドア基準は、d分離(因果ダイアグラムとd分離)を「交絡だけをきれいに消す調整集合」の言葉に翻訳したものです。なお交絡を前から塞げないとき(未観測交絡があるとき)でも、媒介を経由して前から識別する フロントドア基準 など別ルートがあり、第6章の構造的因果モデルで扱います。

⚠️ よくある誤解・落とし穴

関連ノート