Causal ML / Orthogonalization

DML 与因果森林

DML 先用机器学习吸收高维混杂,再用 Neyman 正交矩保护目标参数;因果森林把这个思想局部化为异质性处理效应。

Mechanism Lab

动画:DML 如何把预测信号变成正交因果信号

动画从高维 X 进入两个 nuisance 模型开始,随后展示 Y 与 D 的残差化、正交矩、交叉拟合折叠,以及因果森林的局部 tau(x)。

Step 1 / 5

Nuisance ML

用机器学习分别预测 E[Y|X] 和 E[D|X]。

ell_hat(X), m_hat(X)

Animation Control

Reduced-motion users receive the same step states without continuous motion.

01 / 直觉

核心直觉

普通机器学习擅长预测 Y 或 D,但因果问题关心的是处理变量 D 的可解释扰动,而不是预测器本身。

DML 的核心操作是先残差化:把 Y 和 D 中能由 X 预测的部分拿掉,再用剩下的正交残差信号估计 theta。

交叉拟合让 nuisance 模型在训练样本外预测,避免过拟合误差直接污染目标参数;因果森林进一步让 theta 变成 tau(x)。

02 / 数学

从偏线性模型到正交矩与局部森林

01 / 目标模型

在高维控制变量 X 下,偏线性模型把结果分成处理效应、非参数控制函数和不可解释误差。theta_0 是平均边际处理效应。

Y = theta_0 D + g_0(X) + U
D = m_0(X) + V
E[U|X,D]=0, E[V|X]=0

02 / 残差化

令 ell_0(X)=E[Y|X]。把 Y 和 D 分别投影到 X 上,再取残差;在真值处,Y 残差只保留处理残差乘以 theta_0 与噪声。

tilde Y = Y - ell_0(X)
tilde D = D - m_0(X)
tilde Y = theta_0 tilde D + U

03 / 正交矩

DML 不直接把机器学习预测当成因果结论,而是把它们放入一个对 nuisance 一阶误差不敏感的矩条件。

psi(W;theta,eta) = (Y - ell(X) - theta(D-m(X)))(D-m(X))
E[psi(W;theta_0,eta_0)] = 0

04 / Neyman 正交性

对 ell 的扰动 h_l 和对 m 的扰动 h_m 求 Gateaux 导数。在真值处,条件均值 E[D-m_0(X)|X] 与 E[U|X] 都为 0,所以一阶项消失。

d/dt E[psi(theta_0, ell_0+t h_l, m_0)]|0 = -E[h_l(X)V] = 0
d/dt E[psi(theta_0, ell_0, m_0+t h_m)]|0 = E[h_m(X)(theta_0 V-U)] = 0

05 / 交叉拟合估计量

把样本分成 K 折,在非本折样本上训练 nuisance,再在本折预测。最后用残差回归得到 theta_hat。

theta_hat = sum_i tilde D_i tilde Y_i / sum_i tilde D_i^2
where tilde Y_i, tilde D_i are cross-fitted residuals

06 / 因果森林局部化

若处理效应随 X 变化,森林为每个目标点 x 生成邻域权重 alpha_i(x),在局部正交矩上解 tau(x)。

tau_hat(x) = [sum_i alpha_i(x) tilde D_i tilde Y_i] / [sum_i alpha_i(x) tilde D_i^2]

03 / 代码

Python 代码:交叉拟合 DML 与简化异质性估计

下面的代码模拟高维混杂场景,用随机森林估计 nuisance,交叉拟合残差,再估计 ATE 和一个可视化用的 tau(x) 代理模型。

import numpy as np
import pandas as pd
from sklearn.base import clone
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import KFold

rng = np.random.default_rng(7)
n = 2500
p = 12
X = rng.normal(size=(n, p))

# Heterogeneous treatment effect for demonstration.
tau = 0.8 + 0.6 * (X[:, 0] > 0) - 0.35 * X[:, 1]
m = 0.4 * X[:, 0] - 0.25 * X[:, 2] + 0.2 * X[:, 3] ** 2
D = m + rng.normal(scale=1.0, size=n)
g = 1.2 * np.sin(X[:, 0]) + X[:, 1] * X[:, 2]
Y = tau * D + g + rng.normal(scale=1.0, size=n)

base_y = RandomForestRegressor(
    n_estimators=250,
    min_samples_leaf=20,
    random_state=11,
    n_jobs=-1,
)
base_d = RandomForestRegressor(
    n_estimators=250,
    min_samples_leaf=20,
    random_state=17,
    n_jobs=-1,
)

y_hat = np.zeros(n)
d_hat = np.zeros(n)
folds = KFold(n_splits=5, shuffle=True, random_state=23)

for train_idx, test_idx in folds.split(X):
    model_y = clone(base_y).fit(X[train_idx], Y[train_idx])
    model_d = clone(base_d).fit(X[train_idx], D[train_idx])
    y_hat[test_idx] = model_y.predict(X[test_idx])
    d_hat[test_idx] = model_d.predict(X[test_idx])

y_resid = Y - y_hat
d_resid = D - d_hat
theta_hat = np.sum(d_resid * y_resid) / np.sum(d_resid ** 2)

# Orthogonal score should be close to zero at theta_hat.
score = (y_resid - theta_hat * d_resid) * d_resid
se = np.sqrt(np.mean(score ** 2) / (np.mean(d_resid ** 2) ** 2 * n))

# A simple heterogeneity display: pseudo-outcome for tau(X).
# Production causal forests use honest splitting and forest weights.
pseudo_tau = y_resid / np.where(np.abs(d_resid) < 0.05, np.nan, d_resid)
mask = np.isfinite(pseudo_tau) & (np.abs(d_resid) > 0.2)
tau_model = RandomForestRegressor(
    n_estimators=300,
    min_samples_leaf=40,
    random_state=31,
    n_jobs=-1,
).fit(X[mask], pseudo_tau[mask])

grid = pd.DataFrame({
    "x0_group": ["low X0", "high X0"],
    "tau_hat": [
        tau_model.predict(X[X[:, 0] <= 0]).mean(),
        tau_model.predict(X[X[:, 0] > 0]).mean(),
    ],
})

print(f"DML theta_hat = {theta_hat:.3f} +/- {1.96 * se:.3f}")
print(f"orthogonal score mean = {score.mean():.4f}")
print(grid)

04 / 案例

案例:职业培训项目的高维选择偏差与异质性

  • 研究问题:一个职业培训项目是否提高后续收入?参与者通常有不同的教育背景、行业、地区、过去收入和求职历史。
  • 预测收入的强变量不一定是因果证据;DML 先用 X 解释收入和参与倾向,再用剩余的处理变动估计平均效应。
  • 因果森林可回答“谁受益更多”:例如低基线收入、行业转换者或年轻求职者的 tau(x) 是否更高。
  • 可信报告需要列出识别假设、overlap 检查、nuisance 模型样本外表现、交叉拟合方案、ATE 区间、异质性校准和预注册的分组解释。

05 / 风险

常见误区

把随机森林或 boosting 的预测重要性解释成因果机制。
在同一批样本上训练 nuisance 又估计 theta,导致过拟合误差进入目标参数。
忽略 overlap:如果某些 X 区域几乎没有处理或对照,残差化不能创造可比性。
展示漂亮的 tau(x) 热力图,却没有诚实样本分裂、校准检验、置信区间或预先定义的异质性问题。

参考资料