🎓 レベル:発展 | 重要度:A(必須)
📎 前提:因果ダイアグラムとd分離 | バックドア基準と識別
要点(BLUF)
- 合流点(コライダー、衝突点) = 2本の矢が突き当たるノード()。d分離では合流点はパスを閉じるが、合流点(やその子孫)で条件付けると逆にパスが開き、独立な2変数に見かけの相関が生じる。
- 選択バイアス = 標本に入る/残る条件が実質的に合流点での条件付けであること。自己選抜・打ち切り・生存者だけの分析などが該当し、Berkson のパラドックスはその典型。
- だから「関連していそうな変数は全部調整・層別」は誤り。合流点を調整すると無いはずのバイアスを作り込む。独立な が合流点条件付けで負相関を持つことをコードで実証する。
1. 概念:合流点は「条件付けると開く」
因果ダイアグラムとd分離 で見たパスの開閉を思い出そう。鎖()と分岐()は、中間の を条件付けると閉じる。ところが合流点 だけは逆で、
- 何もしなければ 閉じている( と は 経由では繋がらない)
- (またはその子孫)を条件付けると開く( と に依存が生じる)
flowchart TB
X["才能 X"] --> C["合格 C(合流点)"]
Y["運 Y"] --> C
直観はこうだ。合格 が「才能 + 運 が高いほど起きやすい」とする。 と がもともと無関係でも、「合格した人」に話を限れば、才能が低いのに合格した人は運が良かったはず、運が悪いのに合格した人は才能が高かったはず――と、 と に負の埋め合わせが生まれる。これが合流点バイアスだ。
2. 識別:なぜ条件付けで相関が湧くか(数式)
を独立な標準正規、合流点を (説明のため雑音は省く)とする。多変量正規では、 を与えた条件付き共分散が次で書ける。
ここに 、、 を入れると
第1項 は「もともと無関係」を表す。第2項 が、合流点で条件付けたために注入された見かけの(ここでは負の)相関だ。 がともに を押し上げる(共分散が同符号)から、引き算される項は必ず符号を持ち、条件付き相関はゼロから外れる。
❓ 確認: と がともに を「下げる」( 同士)ならどうなる? ―― 第2項は で、やはり負の見かけ相関が出る。向きが揃っていれば符号は同じ。
3. 実証(1):独立な2変数が選抜で負相関になる
(才能)と (運)を独立に作り、合格スコア の上位だけを「観測」する。これは合流点 で条件付けるのと同じだ。
import numpy as np
# === X と Y は独立。だが両方が合流点 C へ矢印(X→C←Y)===
rng = np.random.default_rng(1)
n = 100_000
X = rng.normal(0, 1, size=n) # 例: 学力(才能)
Y = rng.normal(0, 1, size=n) # 例: 運(X と独立に生成)
C = X + Y + rng.normal(0, 0.3, size=n) # 合格スコア = 学力 + 運(合流点)
corr_all = np.corrcoef(X, Y)[0, 1]
threshold = np.quantile(C, 0.8)
admitted = C > threshold # 上位20%だけ「観測」= 合流点で選抜
corr_sel = np.corrcoef(X[admitted], Y[admitted])[0, 1]
print(f"全体の corr(X, Y) = {corr_all:+.3f}(独立なのでほぼ0)")
print(f"合格者内の corr(X, Y) = {corr_sel:+.3f}(負の相関が出現=選択バイアス)")
出力は次の通り。
全体の corr(X, Y) = +0.002(独立なのでほぼ0)
合格者内の corr(X, Y) = -0.596(負の相関が出現=選択バイアス)
出力の意味――母集団全体では と の相関は 、ほぼゼロ(設計通り独立)。ところが合格者( 上位 20%)だけを見ると相関は 。データを一切いじっていないのに、「観測する人を選んだ」だけで強い負相関が現れた。「優秀な大学では才能と運が逆相関する」式の俗説は、たいていこの選択バイアスである。
4. 実証(2):合流点を回帰に入れると係数が湧く
「全部入れれば安心」という発想で、合流点 を統制変数として回帰に加えるとどうなるか。
import numpy as np
import statsmodels.api as sm
# === 合流点 C を回帰に入れると、独立な X-Y に見かけの係数が生じる ===
rng = np.random.default_rng(1)
n = 100_000
X = rng.normal(0, 1, size=n)
Y = rng.normal(0, 1, size=n) # X と独立
C = X + Y + rng.normal(0, 0.3, size=n) # 合流点
m1 = sm.OLS(Y, sm.add_constant(X)).fit()
m2 = sm.OLS(Y, sm.add_constant(np.column_stack([X, C]))).fit()
print(f"(1) Y ~ X の X係数 = {m1.params[1]:+.3f}(真値0に近い)")
print(f"(2) Y ~ X + C の X係数 = {m2.params[1]:+.3f}(負に偏る=合流点バイアス)")
出力は次の通り。
(1) Y ~ X の X係数 = +0.002(真値0に近い)
(2) Y ~ X + C の X係数 = -0.917(負に偏る=合流点バイアス)
出力の意味―― と は独立なので、 を入れない回帰(1)の 係数は 、正しくゼロ近傍。ところが合流点 を統制に加えた回帰(2)では、 係数が と強い負の値になった。真の係数がゼロの変数に、調整のしかた一つで大きな係数を作り込んでしまったわけだ。「統制変数は多いほど安心」が誤りである、最も鮮明な反例である。
5. 図:選抜が生む見かけの相関
散布図で「全体は雲(無相関)」「選抜した部分集合だけ右肩下がり(負相関)」を見る。
import numpy as np
import matplotlib.pyplot as plt
import japanize_matplotlib
# === 散布図: 全体は無相関、合流点で選抜した部分集合だけ負の相関 ===
rng = np.random.default_rng(1)
n = 4000
X = rng.normal(0, 1, size=n)
Y = rng.normal(0, 1, size=n)
C = X + Y + rng.normal(0, 0.3, size=n)
admitted = C > np.quantile(C, 0.8)
fig, ax = plt.subplots(figsize=(6.5, 5.5))
ax.scatter(X[~admitted], Y[~admitted], s=8, color="lightgray", label="非選抜")
ax.scatter(X[admitted], Y[admitted], s=12, color="crimson", label="選抜(合格者)")
slope, intercept = np.polyfit(X[admitted], Y[admitted], 1)
xs = np.linspace(X.min(), X.max(), 50)
ax.plot(xs, intercept + slope * xs, color="black", lw=2,
label=f"選抜群の回帰(傾き {slope:+.2f})")
ax.set_xlabel("X(学力)")
ax.set_ylabel("Y(運)")
ax.set_title("合流点で選抜すると独立な2変数に負の相関が生じる(Berkson)")
ax.legend(loc="upper right")
plt.tight_layout()
plt.show()
灰色の点(全体)は丸い雲=無相関。赤い点(選抜群)は右上の三角に切り取られ、その中では右肩下がり=負相関になる。同じ点を、見る範囲を変えただけで相関の符号が変わる。これが選択バイアスの幾何学だ。
6. 選択バイアス=広い意味の合流点条件付け
「合流点を調整する」のと「合流点で標本を絞る」のは同じことだ。標本に入る/残るという事象 が処置や結果(あるいはそれらの原因)に依存していれば、 に限った分析は を条件付けたことになる。代表例:
- 生存者バイアス:死亡・脱落した人を除外。生存 が処置とも結果とも関係するなら、生存者だけの比較は偏る。
- 健康労働者効果:働けている人だけを観察。就労 が曝露とも健康とも関係する。
- 自己選抜・回答バイアス:アンケートに答えた人だけ。回答 が態度とも結果とも関係する。
- 入院データ(本家 Berkson):2つの独立な疾患がどちらも入院を起こすと、入院患者内では疾患どうしが負相関して見える。
flowchart TB
X["処置/曝露 X"] --> S["標本に入る S(合流点)"]
Y["結果 Y"] --> S
X --> Y
S --> sel["S=1 だけ観測 = 合流点で条件付け"]
対策は調整ではなく設計だ。標本選抜の構造を DAG に描き、 が合流点なら「 で条件付けない(=選抜に依存しない)」データ取得を目指すか、選抜確率で重み付け(逆確率重み)して補正する。調整変数を足しても選択バイアスは消えない――むしろ合流点を足せば作り出してしまう。
⚠️ よくある誤解・落とし穴
- 「相関するから統制に入れる」は危険。予測では効く変数でも、因果では合流点なら入れた瞬間にバイアスを生む。入れてよいかは相関の強さでなくDAG 上の役割(バックドア基準と識別)で決まる。
- 合流点の”子孫”を調整しても同じ。 そのものでなく、 の影響を受けた下流変数を入れても部分的にパスが開く。「合流点の近く」は丸ごと危ない。
- 処置後変数は原則として統制しない。処置の後に測った変数は、合流点か媒介(過剰調整とMバイアス)であることが多く、入れるとバイアス源になる。
- 欠測・脱落は”見えない”合流点。解析から外れたサンプルがランダムでなければ、それ自体が選択バイアス。欠測機構を DAG に描いて点検する。
関連ノート
- 因果:因果ダイアグラムとd分離(合流点の開閉ルールの出どころ)/バックドア基準と識別(入れてよい変数を決める基準)/過剰調整とMバイアス(処置前変数でも合流点なら危険な例)/因果推論のチェックリスト(選抜構造を DAG で点検する手順)
- 統計:条件付き確率・独立性・全確率の定理(条件付き独立――合流点はこれを壊す)/2変数の記述(散布図・共分散・相関係数)── 相関≠因果/rは直線関係しか測れない/外れ値1点で激変(相関の符号は見る範囲で変わる)