1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

効いたかと、どの経路で効いたか:DoWhyで総効果と媒介効果を分ける

1
Posted at

問いと設定

中間指標を回帰へ入れて介入の係数が小さくなっても、それだけで作用経路を因果的に確認したことにはなりません。総効果の推定と媒介効果の分解には異なる仮定が必要です。

介入Tがbiomarker Mを変え、MとTが結果Yに影響する合成データを作ります。真の直接効果は0.8、間接効果は1.1×0.8=0.88、総効果は1.68です。後半ではTの割付とは独立なUをMとYの共通原因として追加します。解析側はUを観測しません。

実行できるコード

Python 3.12.14で実行しました。解析はすべて合成データを使う研究・学習用の例です。

専用の仮想環境で、次の版をインストールして実行します。数値は2026-10-02の実行結果です。

python -m pip install numpy==2.4.6 pandas==3.0.6 scipy==1.15.3 scikit-learn==1.6.1 statsmodels==0.15.0 dowhy==0.14

次のコードは上から一括実行できます。seedを固定していますが、依存ライブラリや実装の変更で細かな数値は変わり得ます。

import numpy as np
import pandas as pd
from scipy.special import expit
from dowhy import CausalModel
from dowhy.causal_identifier.auto_identifier import EstimandType

graph = '''digraph {age -> treatment; age -> biomarker; age -> outcome;
severity -> treatment; severity -> biomarker; severity -> outcome;
treatment -> biomarker; biomarker -> outcome; treatment -> outcome;}'''
rows = []
for hidden in [False, True]:
    rng = np.random.default_rng(20261002)
    n = 5000
    age = rng.normal(60,10,n)
    severity, u, em, ey = rng.normal(size=(4,n))
    treatment = rng.binomial(1,expit(.04*(65-age)+1.1*severity))
    biomarker = 1.1*treatment+.45*severity-.03*(age-60)+.8*hidden*u+em
    outcome = .8*treatment+.8*biomarker-.9*severity-.02*(age-60)+hidden*u+ey
    df = pd.DataFrame(dict(age=age,severity=severity,treatment=treatment,biomarker=biomarker,outcome=outcome))
    model = CausalModel(data=df,treatment='treatment',outcome='outcome',graph=graph)
    row = dict(hidden_mediator_outcome_confounder=hidden)
    for name, kind, method in [('ATE',EstimandType.NONPARAMETRIC_ATE,'backdoor.linear_regression'),
                                ('NDE',EstimandType.NONPARAMETRIC_NDE,'mediation.two_stage_regression'),
                                ('NIE',EstimandType.NONPARAMETRIC_NIE,'mediation.two_stage_regression')]:
        estimand = model.identify_effect(estimand_type=kind)
        estimate = model.estimate_effect(estimand,method_name=method)
        row[name] = estimate.value
    rows.append(row)
print('True ATE, NDE, NIE:', 1.68,.8,.88)
print(pd.DataFrame(rows).round(4).to_string(index=False))

実行結果

M–Y未観測交絡 ATE NDE NIE
なし 1.6235 0.7644 0.8591
あり 1.5987 0.2093 1.3894
生成式の真値 1.6800 0.8000 0.8800

Uを加えた条件でも総効果は真値に比較的近い一方、経路の配分は大きく変わりました。NDEとNIEの和がATEに一致することは、分解が正しいことの検証にはなりません。

推定する量の定義

Tを0→1へ変える比較で、Y(t,m)、M(t)を潜在結果として表します。ここでは以下の組合せを考えます。

TE=E[Y(1,M(1))-Y(0,M(0))]
NDE=E[Y(1,M(0))-Y(0,M(0))],\quad
NIE=E[Y(1,M(1))-Y(1,M(0))]

今回の線形・交互作用なしの設定ではNIEは係数の積、NDEは直接経路の係数になります。非線形モデルやT×M交互作用がある場合に、同じ係数分解をそのまま使う説明ではありません。

追加で必要な仮定

自然直接・間接効果には、介入–結果、介入–中間指標、中間指標–結果の交絡を扱う必要があります。特に、介入によって変わる中間指標–結果の交絡因子があると、通常の自然効果の識別は難しくなります。観察されない別世界の中間指標を使うcross-worldの仮定も、単なる予測精度からは検証できません。

今回のUは介入Tには影響しないため、介入前共変量によるT–Yの調整を直接壊していません。しかしM–Yの関係が交絡するので、経路の分解は偏ります。RCTでTを無作為化しても、Mまで無作為化されたことにはなりません。

この教材が示したのは既知の生成式での比較です。実際のbiomarkerが治療効果を媒介する、代替エンドポイントとして使える、という証拠ではありません。測定時点、Mの介入可能性、欠測、治療後交絡を別途検討します。

出典

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?