共计 2014 个字符,预计需要花费 6 分钟才能阅读完成。
背景与痛点
因果推断的核心问题是从观察数据中估计干预效果(Treatment Effect)。Propensity Score(倾向得分)通过模拟随机实验,帮助我们减少选择偏差。但在匹配后的样本上构建预测模型时,开发者常面临三大挑战:

- 数据维度塌缩:匹配过程可能损失原始样本量,影响模型训练
- 特征相关性变化:匹配后特征分布趋于平衡,传统特征重要性可能失效
- 效果异质性识别:需要模型能捕捉实验组 / 对照组间的非线性差异
技术方案对比
不同模型在匹配后数据上的表现差异显著:
- 线性回归
- 优点:系数可解释性强,计算效率高
-
局限:无法捕捉交互效应,假设处理效应同质
-
随机森林
- 优点:自动处理非线性关系,抗过拟合能力强
-
注意:需调整 max_depth 避免忽略微弱信号
-
XGBoost
- 优势:内置正则化,适合高维稀疏特征
- 技巧:用
monotone_constraints保持因果合理性
核心实现(Python 示例)
# 数据预处理
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
# 假设 df 是匹配后的 DataFrame,包含特征 X、处理变量 T、结果 y
train_X, val_X, train_y, val_y = train_test_split(df.drop(['outcome','treatment'], axis=1),
df['outcome'],
test_size=0.2,
stratify=df['treatment'] # 保持处理组比例
)
# 标准化连续变量
scaler = StandardScaler()
cont_cols = ['age', 'income'] # 示例连续变量
train_X[cont_cols] = scaler.fit_transform(train_X[cont_cols])
val_X[cont_cols] = scaler.transform(val_X[cont_cols])
# 模型训练(以 XGBoost 为例)import xgboost as xgb
from sklearn.metrics import mean_squared_error
# 添加处理变量交互项
train_X['treatment_feature'] = df.loc[train_X.index, 'treatment']
val_X['treatment_feature'] = df.loc[val_X.index, 'treatment']
model = xgb.XGBRegressor(
objective='reg:squarederror',
n_estimators=200,
max_depth=5,
learning_rate=0.1,
colsample_bytree=0.8
)
model.fit(train_X, train_y)
# 效果评估
val_pred = model.predict(val_X)
print(f'RMSE: {mean_squared_error(val_y, val_pred, squared=False):.3f}')
# 计算 ITE(个体处理效应)val_X_treated = val_X.copy()
val_X_treated['treatment_feature'] = 1
val_X_control = val_X.copy()
val_X_control['treatment_feature'] = 0
ite = model.predict(val_X_treated) - model.predict(val_X_control)
print(f'平均处理效应: {ite.mean():.3f}')
性能与验证
预防过拟合的关键策略:
- 样本外验证
- 保留未参与匹配的原始样本作为测试集
-
使用 Time Split 验证(适用于时序数据)
-
正则化技术
- XGBoost 的 gamma 参数控制分裂最小增益
-
线性模型添加 L2 正则项
-
因果特定指标
- 计算分组 PSI(Population Stability Index)检测分布漂移
- 检查实验组 / 对照组的预测误差差异
避坑指南
实战中高频问题解决方案:
- 样本不平衡:
- 对稀有处理组上采样时,保持协变量分布不变
-
使用 IPSW(Inverse Probability of Sampling Weights)
-
特征泄漏:
- 严格区分匹配阶段和建模阶段的特征
-
避免包含结果变量的代理特征(如 ” 最近购买金额 ” 预测 ” 是否转化 ”)
-
模型解释:
- 用 SHAP 值分析处理变量与特征的交互作用
- 可视化不同亚组的处理效应分布
延伸思考
建议读者尝试:
- 在 Lalonde 数据集上对比 PSM 后 LR 与 XGBoost 的 ATE 估计差异
- 尝试 Double Machine Learning 方法,比较与本文方案的优劣
- 当处理变量为连续值时(如剂量响应),如何调整模型架构
代码仓库包含更完整的特征工程和可视化示例,欢迎在 GitHub 讨论区分享你的实验发现。
正文完
发表至: 数据分析
近一天内
