🎓 レベル:基礎 | 重要度:A(必須)
📎 次に読む:潜在結果モデル | 数理:2変数の記述(散布図・共分散・相関係数)── 相関≠因果/rは直線関係しか測れない/外れ値1点で激変(統計)・クロス集計表・行/列比率・連関 ── 同じ表でも「何で割るか」で結論が変わる(統計)
要点(BLUF)
- 相関 ≠ 因果。2変数が一緒に動くこと(相関)と、片方を動かすともう片方が動くこと(因果)は別物です。
- 観察データの素朴な平均差は、処置と結果の両方に影響する第3の変数(交絡 confounder)があると、真の効果から外れます。場合によっては符号まで逆転します。
- 交絡で層別して調整すれば真の効果に戻る——これを擬似データ(真の効果
ATE_trueを自分で仕込む)で数値で示します。
1. なぜ「相関=因果」と言えないのか
「アイスクリームの売上が増えると水難事故が増える」——両者は強く相関しますが、アイスが事故を起こすわけではありません。背後に気温という共通の原因があり、暑い日はアイスも売れるし水遊びも増えるだけです。
このように、処置 (アイス売上)と結果 (事故)の**両方に矢印を出している変数 (気温)**を 交絡(confounder) と呼びます。交絡があると、 と は因果関係がなくても相関します。
flowchart LR C["交絡 C(気温・重症度など)"] --> X["処置 X"] C --> Y["結果 Y"] X -.->|"本当に知りたい因果効果"| Y
という経路(バックドアパス、因果ダイアグラムとd分離 で厳密化)が開いていると、 と の相関には「本当の因果()」と「交絡由来の見せかけ( 経由)」が混ざります。素朴な相関・平均差はこの2つを区別できません。
識別の話を先に:観察データの平均差を因果効果と読むには「交絡がすべて観測され調整されている」といった仮定が要ります。どんな仮定なら因果と言えるかは 識別の仮定 で、調整すべき変数の選び方は バックドア基準と識別 で扱います。本ノートはまず「素朴な比較が壊れる」事実を体感します。
2. 交絡で符号が逆転する様子を擬似データで作る
シミュレーションの強みは、真の因果効果を自分で決められることです。ここでは処置 の真の効果を と仕込みます。一方で交絡 (重症度)は「重症ほど処置されやすく()」「重症ほど結果が悪い()」という形で入れます。すると素朴な平均差はどうなるでしょうか。
import numpy as np
import pandas as pd
# === 交絡があると素朴な平均差が真の効果と逆符号になることを確かめる ===
rng = np.random.default_rng(42)
n = 20000
# 交絡 C(例:重症度): 0/1。半々で発生
C = rng.binomial(1, 0.5, size=n)
# 処置 X: C が高い(重症)ほど処置されやすい(C→X)
prob_treat = np.where(C == 1, 0.8, 0.2)
X = rng.binomial(1, prob_treat)
# 結果 Y: 真の処置効果は +1.0。ただし C は Y を 3 下げる(C→Y)
ATE_true = 1.0
Y = 2.0 + ATE_true * X - 3.0 * C + rng.normal(0, 1.0, size=n)
# 素朴な平均差(交絡を無視)
naive = Y[X == 1].mean() - Y[X == 0].mean()
# C で層別し、各層の効果を母集団の層比率で加重平均
effect_by_level = []
weight_by_level = []
for c in [0, 1]:
in_level = C == c
diff = Y[(X == 1) & in_level].mean() - Y[(X == 0) & in_level].mean()
effect_by_level.append(diff)
weight_by_level.append(in_level.mean())
adjusted = np.average(effect_by_level, weights=weight_by_level)
print(f"真の ATE = {ATE_true:.3f}")
print(f"素朴な平均差 = {naive:.3f}")
print(f"C で層別・調整後 = {adjusted:.3f}")
print(f"層内効果: C=0 {effect_by_level[0]:.3f}, C=1 {effect_by_level[1]:.3f}")
出力:
真の ATE = 1.000
素朴な平均差 = -0.787
C で層別・調整後 = 1.006
層内効果: C=0 0.986, C=1 1.025
出力の意味:真の効果は (処置は結果を良くする)なのに、素朴な平均差は と負になりました。符号が逆転しています。理由は「処置を受けた群は重症()が多く、重症はもともと結果が悪い」から。処置の良い効果が、重症であることの悪さに覆い隠されたのです。ところが と に層別して各層内で比べると、どちらも約 (0.986 と 1.025)。それを母集団比率で加重平均すると に戻りました。交絡を調整すれば真値が見える——因果推論の出発点です。
3. シンプソンの逆説:部分集団と全体で符号が反対になる
第2節の現象が一番劇的に出るのが シンプソンの逆説(Simpson’s paradox) です。実在データで見ます。腎臓結石の治療 A(開腹手術)と B(経皮的腎砕石術)の回復率を比べた古典例(Charig ら 1986)です。
import pandas as pd
# === シンプソンの逆説:部分集団では A 優勢なのに全体では B 優勢 ===
# 腎臓結石の治療 A/B の回復データ(Charig 1986 の有名な実データ)
data = pd.DataFrame({
"結石サイズ": ["小", "小", "大", "大"],
"治療": ["A", "B", "A", "B"],
"回復": [81, 234, 192, 55],
"患者数": [87, 270, 263, 80],
})
data["回復率"] = (data["回復"] / data["患者数"]).round(3)
print("【部分集団ごと】")
print(data.to_string(index=False))
# 治療ごとに小・大を合算した「全体」回復率
totals = data.groupby("治療")[["回復", "患者数"]].sum()
totals["全体回復率"] = (totals["回復"] / totals["患者数"]).round(3)
print("\n【全体(小+大を合算)】")
print(totals.to_string())
出力:
【部分集団ごと】
結石サイズ 治療 回復 患者数 回復率
小 A 81 87 0.931
小 B 234 270 0.867
大 A 192 263 0.730
大 B 55 80 0.688
【全体(小+大を合算)】
回復 患者数 全体回復率
治療
A 273 350 0.780
B 289 350 0.826
出力の意味:結石が小さい場合は A(0.931)が B(0.867)に勝ち、大きい場合も A(0.730)が B(0.688)に勝つ。どちらのサイズでも A が良いのに、全体で合算すると B(0.826)が A(0.780)を逆転します。種明かしは交絡=結石サイズです。難しい大結石には主に A(263 人)が、易しい小結石には主に B(270 人)が使われました。A は不利なケースを多く引き受けたため、合算すると見かけの回復率が下がるのです。
ここで重要なのは「どちらを信じるべきか」。結石サイズという交絡を**揃えて(層別して)**比べた部分集団の結論(A が良い)が因果的に正しく、合算した全体の比較は交絡に汚染されています。「データを足し合わせれば真実に近づく」は誤りで、揃えるべきものを揃えて初めて因果が見える——これが因果推論の核心的な教訓です。
4. 仮定の直観的意味:なぜ「揃える」と因果が見えるのか
層別が効いたのは、同じ の中では処置の割り当てが結果と無関係に近くなるからです。重症度 を固定すれば、その層の中での処置・非処置はおおむね「同じ条件の人を比べている」状態に近づきます。これを厳密にしたのが 条件付き交換可能性(conditional exchangeability)
で、「 を与えれば、誰が処置されるかは潜在結果と独立」という仮定です(潜在結果モデル で潜在結果 を、識別の仮定 でこの仮定そのものを扱います)。この仮定が成り立つ をすべて調整できたときに限り、層別・調整した平均差を因果効果と読めます。逆に言えば、調整し損ねた交絡(未観測交絡)が残れば、いくら層別しても因果にはなりません。
⚠️ よくある誤解・落とし穴
- 「相関係数が大きい=因果が強い」ではない。相関の大きさは因果の強さを測りません。交絡だけで強い相関は簡単に作れます(第2節)。
- 「とにかく全部の変数で調整すれば安全」ではない。交絡は調整すべきですが、合流点(コライダー)や媒介変数を誤って調整すると、逆にバイアスを生みます(因果ダイアグラムとd分離・バックドア基準と識別)。「何を調整し、何を調整してはいけないか」は DAG で判断します。
- 「シンプソンの逆説では常に層別が正しい」とは限らない。層別すべきか合算すべきかは因果構造しだいです。層別変数が交絡なら層別が正しいですが、それが媒介変数なら層別はむしろ誤りになります。数表だけ見ても決まらず、DAG が要ります。
- 大標本でも消えない。これは偶然のばらつきではなく系統的なバイアスなので、データを増やしても素朴な推定は真値に近づきません(第2節は でも符号が逆のまま)。
関連ノート
- 第1章 因果推論の枠組み 目次
- 潜在結果モデル(次のトピック・因果効果を反事実で定義する)
- 因果ダイアグラムとd分離(交絡・媒介・合流点を図で区別する)
- バックドア基準と識別(何を調整すべきかの規則)
- 識別の仮定(素朴比較を因果と読むための仮定)
- 2変数の記述(散布図・共分散・相関係数)── 相関≠因果/rは直線関係しか測れない/外れ値1点で激変(統計・相関の定義と性質)
- クロス集計表・行/列比率・連関 ── 同じ表でも「何で割るか」で結論が変わる(統計・分割表とシンプソンの逆説)
- 交絡の調整(統計・交絡調整の実務)
- 因果推論テキスト 全体目次