Sherry_z
发布于

诺贝尔奖级别的因果推断方法,终于有人讲清楚了:Double ML 原理与 Python 实战


当机器学习遇见计量经济学,一个同时解决「预测精度」和「因果推断」的革命性框架

你有没有遇到过这样的困境——

传统OLS回归:解释变量一多就多重共线性,交互项遗漏就偏误,恨不得把每个变量组合都塞进去试试……

机器学习方法:预测能力很强,但输出的系数没有标准误、置信区间,想要一个p值来做假设检验?不好意思,ML不提供这个……

怎么办?

2017年,Chernozhukov 等三位经济学家提出了 Double/Debiased Machine Learning(DML,双重机器学习)——

用机器学习做预测,用计量经济学做推断。

2023年诺贝尔经济学奖表彰的「因果推断方法革命」,DML是其中最核心的框架之一。



一、为什么需要 DML?

1.1 传统方法的两个极端


方法优势致命缺陷
传统OLS推断严谨,有标准误线性假设太强,无法捕捉非线性
现代机器学习灵活捕捉非线性关系只有预测,没有推断(缺标准误)

1.2 DML 解决的核心问题

问题:高维 confounders(协变量 X 很复杂)

目标:估计 treatment T 对 outcome Y 的因果效应

传统做法

Y = α + βT + γX + ε

问题:X 的函数形式如何设定?遗漏非线性交互项导致 β 有偏

DML 做法

  1. 1. 用 ML 预测 Y(控制 X 的非线性关系)
  2. 2. 用 ML 预测 T(控制 X 的非线性关系)
  3. 3. 对残差做回归(正交化消除偏误)
  4. 4. 得到 β 的标准误和置信区间

核心思想:Neyman 正交化 + 交叉拟合(Cross-fitting)



二、DML 的四步流程

Step 1: 建立因果框架

Y = θ(T) + g(X) + εT = m(X) + ν

Step 2: 用 ML 分别估计 g(X) 和 m(X)

常用学习器:LASSO、随机森林、梯度提升、神经网络

Step 3: 计算残差

Ỹ = Y - ĝ(X)     ← Y 的残差T̃ = T - m̂(X)     ← T 的残差

Step 4: 对残差做简单OLS回归

Ỹ = θ·T̃ + 误差项

θ 就是我们想要的因果效应!

为什么有效?

通过残差化,「干掉」了 X 中与因果推断无关的部分,让 ML 的预测误差不会传递到最终估计。



三、Python 实战:econml vs DoubleML

3.1 方案一:econml(微软出品)

推荐指数:五颗星

安装

!pip install econml

完整代码

import pandas as pd
import numpy as np
from econml.dml import LinearDML, CausalForestDML

# ============ Step 1: 准备数据 ============
# Y: 结果变量(outcome)
# T: 处理变量(treatment,二值或连续)
# X: 控制变量(confounders)
# W: 其他协变量(可选)

# 模拟数据示例
np.random.seed(42)
n = 1000
X = np.random.randn(n, 5)  # 5个协变量
T = X[:, 0] + 0.5*X[:, 1] + np.random.randn(n)*0.5  # 处理变量
Y = 2*T + X[:, 0] - 0.5*X[:, 1] + np.random.randn(n)  # 结果变量

# ============ Step 2: DML 估计 ============
# 方法1: 线性 DML(假设异质性效应是线性的)
model = LinearDML(
    discrete_treatment=False,    # T 连续还是离散
    random_state=42,
    n_estimators=100,           # ML 基础学习器数量
    model_y="auto",              # 自动选择 Y 的 ML 模型
    model_t="auto"               # 自动选择 T 的 ML 模型
)

# 拟合模型
model.fit(Y, T, X=X, W=None)

# ============ Step 3: 提取结果 ============
# 平均处理效应(ATE)
ate = model.ate(X)
print(f"ATE: {ate:.4f}")

# 置信区间
ate_interval = model.ate_interval(X)
print(f"95% CI: [{ate_interval[0]:.4f}, {ate_interval[1]:.4f}]")

# ============ Step 4: 异质性处理效应(HTE)============
# 如果想看每个个体的效应差异,用 CausalForestDML
model_het = CausalForestDML(
    discrete_treatment=False,
    n_estimators=100,
    random_state=42
)
model_het.fit(Y, T, X=X)

# 个体处理效应(ITE)
ite = model_het.effect(X)
print(f"ITE 均值: {np.mean(ite):.4f}, 标准差: {np.std(ite):.4f}")

# 效应分布可视化
import matplotlib.pyplot as plt
plt.hist(ite, bins=30, edgecolor='black', alpha=0.7)
plt.xlabel('Individual Treatment Effect')
plt.ylabel('Frequency')
plt.title('Heterogeneous Treatment Effects Distribution')
plt.savefig('hte_distribution.png', dpi=150, bbox_inches='tight')
plt.show()


3.2 方案二:DoubleML(更学术导向)

推荐指数:四颗星

安装

!pip install doubleml

完整代码

import doubleml as dml
from sklearn.ensemble import RandomForestClassifier, RandomForestRegressor
from sklearn.linear_model import LassoCV

# ============ Step 1: 构造 DoubleML 数据对象 ============
from doubleml.datasets import make_dml_data

# 模拟数据(模拟 confounded 设置)
data = make_dml_data(
    'classification',      # 或 'regress' 连续
    n_obs=1000,
    dim_x=5,
    theta=1.0,
    binary_X=False,
    conf_type='didi'
)

# 构建 DML 数据集
dml_data = dml.DoubleMLData(
    data.xs,               # 特征矩阵 X
    data.y,                # 结果变量 Y
    data.d,                # 处理变量 D/T
    data.z                 # 工具变量 Z(可选)
)

# ============ Step 2: 定义 ML 模型 ============
# LASSO 作为基础学习器
learner = LassoCV(cv=5)

# 回归问题用随机森林
ml_l = RandomForestRegressor(n_estimators=100, max_depth=5, random_state=42)
ml_m = RandomForestRegressor(n_estimators=100, max_depth=5, random_state=42)

# ============ Step 3: 构造 DML 估计器 ============
# DML1 / DML2 / DML3(基于残差化方法)
dml_plr = dml.DoubleMLPLR(         # PLR: Partially Linear Regression
    dml_data,
    ml_l=ml_l,
    ml_m=ml_m,
    n_folds=5,                      # K-fold 交叉验证
    score='partialling out',        # 核心:Neyman 正交化
    dml_procedure='dml2'            # 或 'dml1', 'dml3'
)

# ============ Step 4: 估计 + 推断 ============
dml_plr.fit()

print(dml_plr.summary)              # 完整结果表

# 提取系数和标准误
theta = dml_plr.coef['theta']
se = dml_plr.se['theta']
ci = dml_plr.confint()

print(f"θ = {theta:.4f}")
print(f"SE = {se:.4f}")
print(f"95% CI: [{ci.loc['theta', '2.5 %']:.4f}, {ci.loc['theta', '97.5 %']:.4f}]")


四、DML vs 因果森林 vs 传统OLS


对比维度传统OLS因果森林DML
推断类型平均效应(ATE)个体效应(ITE)均可
非线性处理不支持支持支持
标准误/置信区间支持支持(grf提供)支持
高维协变量不支持支持强力支持
工具变量场景支持不支持支持
样本外推断一般一般交叉拟合更稳

DML的独特优势:自带交叉拟合(Cross-fitting),在有限样本下更稳健。



五、实际应用场景

场景1:劳动力市场

  • 问题:职业培训对工资的影响,在不同人群中有多大差异?
  • DML处理:用 ML 控制教育、工作经验、地区等高维交互

场景2:政策评估

  • 问题:某项政策对GDP的因果效应,哪些省份受益最大?
  • DML处理:省份特征用梯度提升捕捉非线性关系

场景3:金融研究

  • 问题:公司特征对股票收益的异质性影响
  • DML处理:用神经网络提取高维公司特征


六、常见问题 Q&A

Q1: DML 和因果森林有什么区别?

因果森林是基于决策树的非参数方法,直接估计 τ(x);DML 是框架,可以用任意 ML 模型作为「预测器」,更灵活。

Q2: 应该用哪个 ML 模型?

没有绝对标准。LASSO 适合稀疏高维数据;随机森林/梯度提升适合非线性关系;神经网络适合大规模数据。建议交叉验证选最优。

Q3: n_folds 设多少合适?

通常 5 或 10。样本量越大,fold 数影响越小。样本量小(小于500)建议用 5-fold。

Q4: DML 能做 IV 估计吗?

可以。用 DoubleMLIV 或 econml 的 IV 类,适合处理内生性问题。



七、参考文献

[1] Chernozhukov V, Chetverikov D, Demirer M, et al. (2018). Double/debiased machine learning for treatment and structural parameters. Econometrics Journal, 21(1): C1-C68.

[2] Chernozhukov V, Demirer M, Duflo E, Fernandez-Val I. (2023). Generic machine learning inference on heterogeneous treatment effects in randomized experiments. Review of Economics and Statistics, 105(5): 1104-1118.

原文:https://doi.org/10.1111/ectj.12097




浏览 (5)
点赞
收藏
删除
评论