因果推断实战:基于Brady Neal笔记的Python实现与避坑指南

1次阅读
没有评论

共计 1554 个字符,预计需要花费 4 分钟才能阅读完成。

image.webp

背景痛点:从相关性到因果性

传统机器学习模型常陷入 ” 相关不等于因果 ” 的陷阱。例如在医疗领域,观测数据可能显示定期体检的患者死亡率更低,但这可能仅反映健康意识强的群体特征(选择偏差 /selection bias),而非体检本身的因果效应。混杂因素 /confounder(如收入水平同时影响体检频率和健康状况)的存在,使得基于纯统计关联的结论具有误导性。

因果推断实战:基于 Brady Neal 笔记的 Python 实现与避坑指南

理论基础:两大因果框架对比

1. 结构因果模型(SCM)

  • 使用有向无环图 /DAG 表示变量间的因果关系
  • 核心工具 do-calculus:$P(Y|do(X))$ 表示干预后的概率分布
  • 优势:可视化直观,适合处理复杂因果路径

2. 潜在结果模型(Potential Outcomes)

  • 定义:每个个体同时存在处理组和对照组结果 $Y(1), Y(0)$
  • 关键假设:稳定单元处理值假设 /SUTVA
  • 适用场景:随机实验或可明确识别混杂变量的场景

Python 实战:从理论到代码

环境准备

!pip install pywhy dowhy
import numpy as np
import dowhy
from dowhy import CausalModel

构建因果图

# 模拟数据:X→Y, Z→X, Z→Y(Z 为混杂变量)n_samples = 1000
Z = np.random.normal(size=n_samples)
X = 0.5*Z + np.random.normal(size=n_samples)
Y = 0.7*X + 0.3*Z + np.random.normal(size=n_samples)
data = pd.DataFrame({'X':X, 'Y':Y, 'Z':Z})

# 定义因果模型
model = CausalModel(
    data=data,
    treatment='X',
    outcome='Y',
    common_causes=['Z']
)

估计平均处理效应(ATE)

# 识别因果效应
identified_estimand = model.identify_effect()

# 使用倾向得分匹配(PSM)estimate = model.estimate_effect(
    identified_estimand,
    method_name='backdoor.propensity_score_matching'
)
print(f"ATE 估计值: {estimate.value}")

生产环境挑战与解决方案

小样本问题

  1. 使用 Bootstrap 重采样:

    from sklearn.utils import resample
    boot_estimates = [resample(data).mean() for _ in range(1000)]

  2. 贝叶斯方法:引入先验分布补偿数据不足

高维混杂变量

  • 倾向得分模型加入 L1 正则化:
    from sklearn.linear_model import LogisticRegression
    ps_model = LogisticRegression(penalty='l1', solver='liblinear')

常见陷阱与规避策略

未观测混杂变量

  • 使用工具变量 /Instrumental Variable
  • 进行敏感性分析:
    model.sensitivity.check_robustness(
        estimate,
        confounder_shift = 0.1
    )

非线性效应处理

  • 采用双机器学习 /Double ML:
    from econml.dml import LinearDML
    dml_estimate = LinearDML().fit(Y, X, W=Z)

延伸思考

当无法进行随机对照试验时,可以:
1. 利用自然实验(政策变化、突发事件)
2. 采用断点回归设计 /RDD
3. 构建合成控制组

建议在 Colab 中尝试修改混杂变量强度,观察 ATE 估计值的变化。完整的可运行代码示例已发布在 GitHub 仓库(示例链接)。

正文完
 0
评论(没有评论)