Mímisbrunnr知恵の泉

← 因果推論 一覧

🎓 レベル:発展 | 重要度:B(標準)

📎 前提:媒介分析 | バックドア基準と識別

要点(BLUF)


1. 概念:良い統制と悪い統制

調整(統制)してよい変数は「交絡だけ」だ。交絡を入れればバイアスは減るが、それ以外の変数は入れるとかえってバイアスを生むことがある。代表的な「悪い統制」は2つ。

役割DAG 上の位置調整すると
交絡XCYX \leftarrow C \to Yバイアスが減る(入れるべき)
媒介XMYX \to M \to Y因果パスを遮断 → 過剰調整
合流点XKYX \to K \leftarrow Y や M字パスを開く → 合流点/Mバイアス

媒介の害は衝突点バイアスと選択バイアスの合流点バイアスと並ぶ「悪い統制」の二大巨頭である。順に数値で見る。


2. 過剰調整:媒介を入れると効果が消える

識別

総効果は処置から結果へ至るすべての有向パスの寄与だ。XMYX\to M\to Y が唯一の経路なら、総効果はこの間接効果に等しい。ところが MM を条件付けると XMYX\to M\to Y の道が遮断され、残るのは XX から YY への直接の矢(ここでは存在しない)だけになる。

flowchart LR
    X["処置 X"] --> M["媒介 M"]
    M --> Y["結果 Y"]

形式的には、総効果と直接効果を分けて

総効果=(XY の直接効果)ここでは 0+(XMY の間接効果)測りたいもの.\text{総効果} = \underbrace{(X\to Y \text{ の直接効果})}_{\text{ここでは }0} + \underbrace{(X\to M\to Y \text{ の間接効果})}_{\text{測りたいもの}}.

MM を統制すると間接効果が落ち、推定されるのは直接効果(=0=0)になる。

実証

XMYX\to M\to Y で、XXYY への直接効果はゼロ、効果はすべて MM 経由とする(真の総効果 =3.0=3.0)。

import numpy as np
import statsmodels.api as sm

# === (a) 媒介変数 M を調整すると、X→M→Y の効果が消える(過剰調整)===
rng = np.random.default_rng(3)
n = 50_000
X = rng.binomial(1, 0.5, size=n)                  # 処置
M = 2.0 * X + rng.normal(0, 1, size=n)            # 媒介(X→M)
Y = 1.5 * M + rng.normal(0, 1, size=n)            # 結果(M→Y、直接効果なし)
ATE_total_true = 2.0 * 1.5                        # 総効果 = 3.0

m1 = sm.OLS(Y, sm.add_constant(X)).fit()
m2 = sm.OLS(Y, sm.add_constant(np.column_stack([X, M]))).fit()

print(f"真の総効果 = {ATE_total_true:.2f}")
print(f"(1) Y ~ X      の X係数 = {m1.params[1]:.3f}(総効果を回収)")
print(f"(2) Y ~ X + M  の X係数 = {m2.params[1]:.3f}(媒介を調整して0に消える)")

出力は次の通り。

真の総効果 = 3.00
(1) Y ~ X      の X係数 = 2.982(総効果を回収)
(2) Y ~ X + M  の X係数 = -0.002(媒介を調整して0に消える)

出力の意味――媒介 MM を入れない回帰(1)は総効果 2.983.02.98\approx 3.0 を正しく回収する。ところが「念のため」と MM を入れた回帰(2)では、XX 係数が 0.002-0.002ほぼゼロになった。効果が消えたのではなく、測りたかった間接効果を MM の調整が吸い取っただけだ。XX 係数が表すのはいまや直接効果(真にゼロ)である。総効果を知りたいなら媒介を入れてはならない。

❓ 確認:では「直接効果だけ」を知りたいときは MM を入れてよいか? ―― 入れる必要があるが、それでも一般には不十分。媒介分析(媒介分析)には MMYY 間の交絡がないなど追加の仮定が要る。単純に MM を回帰へ足すだけでは直接効果さえ偏りうる。


3. Mバイアス:処置前変数でも調整すると偏る

「媒介は処置の後だから危ない。処置に決まった変数なら入れて安全」――この経験則は間違っている。反例が M字構造だ。

識別

未観測交絡が2つ(U1,U2U_1, U_2)あり、観測できる変数 MM が両者の合流点になっている状況を考える。

flowchart TB
    U1["未観測 U1"] --> X["処置 X"]
    U1 --> M["合流点 M(処置前)"]
    U2["未観測 U2"] --> M
    U2 --> Y["結果 Y"]
    X --> Y

XX から YY へのバックドア経路は XU1MU2YX \leftarrow U_1 \to M \leftarrow U_2 \to Y ただ一本。中間の MM合流点だから、何もしなければこの経路は閉じている――つまり MM を入れなければ素朴な回帰でも XYX\to Y を正しく推定できる。ところが「MM は処置前だし XX とも YY とも相関するから交絡だろう」と MM を調整すると、合流点が開きU1U_1U2U_2 に見かけの相関が生じて XU1U2YX\leftarrow U_1\cdots U_2\to Y という裏口が通ってしまう。

偏りの符号も合流点バイアスと同じ式で読める。M=U1+U2M=U_1+U_2(雑音省略, Var(M)=3\operatorname{Var}(M)=3 をモデルに合わせて)に対し

Cov(U1,U2M)=Cov(U1,M)Cov(U2,M)Var(M)=113<0.\operatorname{Cov}(U_1, U_2 \mid M) = -\frac{\operatorname{Cov}(U_1,M)\,\operatorname{Cov}(U_2,M)}{\operatorname{Var}(M)} = -\frac{1\cdot 1}{3} < 0.

XXU1U_1 に正、YYU2U_2 に正で乗るので、U1U_1U2U_2 の負相関が XXYY負のバイアスとして現れ、推定値は真値より小さくなる。

実証

import numpy as np
import statsmodels.api as sm
import matplotlib.pyplot as plt
import japanize_matplotlib

# === (b) M字構造: M を調整すると未観測交絡パスが開いて偏る ===
rng = np.random.default_rng(11)
n = 100_000
U1 = rng.normal(0, 1, size=n)                       # 未観測
U2 = rng.normal(0, 1, size=n)                       # 未観測
X = U1 + rng.normal(0, 1, size=n)                   # U1 → X
M = U1 + U2 + rng.normal(0, 1, size=n)              # U1 → M ← U2(M は合流点)
tau_true = 1.0
Y = tau_true * X + U2 + rng.normal(0, 1, size=n)    # X → Y(真の効果), U2 → Y

b_no = sm.OLS(Y, sm.add_constant(X)).fit().params[1]
b_adj = sm.OLS(Y, sm.add_constant(np.column_stack([X, M]))).fit().params[1]
print(f"真の効果 tau = {tau_true:.2f}")
print(f"M を調整しない: X係数 = {b_no:.3f}(合流点は閉じている→真値を回収)")
print(f"M を調整する  : X係数 = {b_adj:.3f}(合流点を開く→M字バイアスで偏る)")

labels = ["真値", "M を調整しない", "M を調整する"]
vals = [tau_true, b_no, b_adj]
colors = ["gray", "#2ca02c", "crimson"]
fig, ax = plt.subplots(figsize=(6.5, 4.2))
ax.bar(labels, vals, color=colors)
ax.axhline(tau_true, ls="--", color="gray")
ax.set_ylabel("X→Y の推定値")
ax.set_title("M字構造では M を調整しない方が正しい")
plt.tight_layout()
plt.show()

出力は次の通り。

真の効果 tau = 1.00
M を調整しない: X係数 = 0.999(合流点は閉じている→真値を回収)
M を調整する  : X係数 = 0.799(合流点を開く→M字バイアスで偏る)

出力の意味――MM入れないほうが真値 1.001.00 をぴたりと当て(0.9990.999)、MM入れたほうが 0.7990.799 へ下方に偏った。導出した符号(負のバイアス)と一致する。「処置前で、XX とも YY とも相関する変数」を律儀に統制した結果、正しかった推定を壊したわけだ。MM が交絡か合流点かは相関を見ても分からない。DAG を描いて初めて区別できる。


4. 「全部入れる」が誤りである理由

機械学習の予測では「使える特徴は全部入れる」が定石だ。だが因果では逆になりうる。理由は2節・3節で見た通り:

どちらも「相関しているから入れた」結果増えたバイアスだ。入れてよいのはバックドアパスを塞ぐ交絡だけで、それを判定するのは相関の強さではなく DAG とバックドア基準バックドア基準と識別)である。**「迷ったら入れる」ではなく「DAG で役割を確かめてから入れる」**が因果での作法だ。


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


関連ノート