共计 1575 个字符,预计需要花费 4 分钟才能阅读完成。
从 AB 测试到因果推断
传统 AB 测试的局限性在于,它只能告诉我们干预组和对照组的差异,却无法解释这种差异是否真正由干预引起。例如在广告效果评估中,高消费用户可能更倾向于点击广告(自然倾向),这会导致我们高估广告的真实效果。这种由混淆变量(confounder)导致的偏差问题,正是因果推断要解决的核心问题。
倾向分匹配 (PSM) 原理详解
倾向分匹配的核心思想可以概括为:通过构建一个 ” 虚拟实验 ”,使得干预组和对照组在观察特征上尽量相似。具体实现分为三个关键步骤:
-
倾向分估计:
使用逻辑回归模型估计每个样本接受干预的概率:e(X) = P(T=1|X) = 1/(1+exp(-(βX)))其中 T 表示处理状态(0/1),X 为协变量矩阵
-
匹配阶段:
- 最近邻匹配(1:1 或 1:k)
- 卡尺匹配(caliper matching)
-
核密度匹配
-
平衡性检验:
匹配后需要检验协变量在处理组和对照组间的标准化差异(standardized difference)是否 <0.1
因果森林的双重机器学习
与 PSM 不同,因果森林基于以下两个关键创新:
-
双重残差学习:
Y - E[Y|X] = τ(X)(T - E[T|X]) + ε通过先拟合 outcome 模型和 propensity 模型,再用残差进行因果效应估计
-
异质性处理:
通过构建决策树自动发现不同子群体(subgroup)的差异化处理效应
Python 实战代码
PSM 实现示例
from sklearn.linear_model import LogisticRegression
from causalinference import matching
# 步骤 1:拟合倾向分模型
ps_model = LogisticRegression().fit(X, treatment)
prop_scores = ps_model.predict_proba(X)[:,1]
# 步骤 2:进行匹配
matched_data = matching.PropensityScoreMatching(
treatment=treatment,
propensity=prop_scores,
caliper=0.2 # 卡尺宽度
)
因果森林实现
from causalml.forest import CausalForest
cf = CausalForest(
n_estimators=1000,
max_depth=10,
min_samples_leaf=10
)
# 拟合模型
cf.fit(X, treatment, y)
# 获取个体处理效应(ITE)
ite = cf.predict(X)
# 计算平均处理效应(ATE)
print(f"ATE: {ite.mean():.3f}")
效果对比实验
不同匹配方法比较
| 方法 | 样本损失率 | SMD 均值 |
|---|---|---|
| 最近邻匹配 | 15% | 0.08 |
| 半径匹配 | 22% | 0.05 |
| 核匹配 | 8% | 0.12 |
树深度对因果森林的影响

最佳实践建议
- 协变量平衡诊断:
- 绘制 Love plot 展示匹配前后标准化差异
-
检验 t -test 的 p 值是否 >0.1
-
重叠假设检验:
# 检查倾向分分布重叠 plt.hist(prop_scores[treatment==0], alpha=0.5, label='Control') plt.hist(prop_scores[treatment==1], alpha=0.5, label='Treatment')
开放性问题思考
- 当处理组和对照组分布差异极大时,可以考虑:
- 使用倾向分加权 (IPTW) 代替匹配
-
尝试非参数平衡方法如熵平衡
-
验证因果发现的可信度:
- 进行 placebo test(将处理变量随机打乱)
- 添加已知效应的阳性对照
- 使用双重差分法 (DID) 进行交叉验证
结语
因果推断是一个需要不断迭代验证的过程。在实践中,我建议同时尝试 PSM 和因果森林等多种方法,当不同方法得出的结论一致时,我们才能对因果效应有更强的信心。记住:没有完美的因果推断方法,只有针对具体问题最合适的方法选择。
正文完
发表至: 未分类
近一天内
