因果推断入门:从相关到因果

你已经能熟练训练一个预测模型:给定用户特征,预测他会不会流失;给定历史销量,预测下个月卖多少。但当你被问到「如果我把价格降低 10%,销量会涨多少」或者「是这款推荐算法真正带来了转化,还是本来就想买的人恰好点了它」时,相关性的模型就哑火了。预测是「看(seeing)」,而因果是「做(doing)」——这是两件完全不同的事。

本篇面向已经掌握机器学习基础、想进一步理解因果建模的工程师与研究者,依次讲清四件事:为什么相关不等于因果(含辛普森悖论)、两大理论支柱(Rubin 的潜在结果框架与 Pearl 的 do-operator)、三种主流识别策略(随机实验、工具变量、双重差分),最后用 DoWhy 在一个小数据集上实测因果效应估计。

相关不等于因果:辛普森悖论等反例

一个老生常谈的提醒:相关系数只描述「共变」,不描述「因为」。两个变量一起变,可能是 A 导致 B,可能是 B 导致 A,也可能是一个隐藏变量 C 同时导致了 A 和 B。下面三个反例都源于这一事实。

冰淇淋与溺水:夏天冰淇淋销量上升,溺水人数也上升。没人会相信吃冰淇淋导致溺水,因为两者都被「气温」这个混淆变量同时推高。这就是最朴素的混淆(confounding)。

辛普森悖论(Simpson’s Paradox):分组看趋势与合并看趋势可能完全相反。设想一款新药在两个患者群体上的治愈率:

整体(合并)视角:
  新药治愈率 83%,旧药治愈率 78%  ->  新药更优

按病情轻重分层后:
  轻症患者:新药 90% vs 旧药 93%  ->  旧药更优
  重症患者:新药 70% vs 旧药 73%  ->  旧药更优

新药在每一层都不如旧药,合并后却「胜出」,原因是新药被 disproportionately 用在了轻症患者更多的群体里(轻症本身治愈率高),混淆变量「病情轻重」扭曲了整体结论。这直接说明:不做分层或调整的「相关」结论会骗人。

来源核验:辛普森悖论(Simpson’s paradox)的命名与「分层后结论反转」的核心机制属于因果推断与统计学的经典结论(待核实,本文未做 WebFetch 核验,建议引用前自行核对;其标准教材见 Pearl、Imbens 与 Rubin 的相关著作)。

相关陷阱的工程后果:在 A/B 之外,如果你用「点击过的用户转化率更高」来论证推荐有效,就落入了混淆——转化高的人本来就更可能点击。要回答「做了 X 会怎样」,必须进入因果语言。

潜在结果框架(Rubin)与干预 do-operator(Pearl)

因果推断有两条常被并列讲述的理论主线,它们说的是同一件事的两种方言。

Rubin 潜在结果框架(Potential Outcomes)

对每一个样本 i,设想它有两种「潜在」状态:接受治疗(treatment,记作 1)时的结果 Y_i(1),与未接受治疗(control,记作 0)时的结果 Y_i(0)。个体因果效应定义为二者之差:

个体处理效应  τ_i = Y_i(1) - Y_i(0)
平均处理效应  ATE = E[ Y_i(1) - Y_i(0) ]
条件平均处理效应  CATE(x) = E[ Y_i(1) - Y_i(0) | X_i = x ]

这里的核心困难叫「因果推断的基本问题(Fundamental Problem of Causal Inference)」:现实中每个样本只能处在一种状态下,我们永远同时观察不到 Y_i(1)Y_i(0),缺的那个就是「反事实(counterfactual)」。因果推断的全部努力,就是用一群人的「事实」去估计另一群人的「反事实」,再相减得到效应。

「可忽略性(ignorability)」是框架里的关键假设:在控制了混淆变量 X 之后,分配治疗与否与潜在结果独立,即 (Y(1), Y(0)) ⟂ T | X。满足它,才能用观测到的条件均值之差去逼近真实 ATE。

Pearl 的 do-operator 与因果图

Judea Pearl 用「因果图(DAG,有向无环图)」和「do-operator」给出另一套语言。因果图里每个变量是一个节点,箭头 -> 表示因果方向,例如:

混淆变量 X  ->  处理 T  ->  结果 Y
      \_______________/
      (X 同时影响 T 与 Y,形成后门路径)

do(T=1) 表示「人为把处理设为 1」的外生干预:它像一把剪刀剪断所有指向 T 的边,再强制 T 取 1,于是我们只看 T 对 Y 的纯粹拉动。这是和「条件概率 P(Y|T=1)」最本质的区别——后者只是观测筛选,前者是主动改变世界。

Pearl 据此提出「因果阶梯(Ladder of Causation)」,由低到高分三层:

第一层 关联 Association(见 seeing):   X 与 Y 是否相关?  工具:相关、回归
第二层 干预 Intervention(做 doing):   若 do(X),Y 如何变?  工具:do-calculus、后门准则
第三层 反事实 Counterfactual(想象 imagining): 若当时 X 不同,会怎样?  工具:结构因果模型 SCM

传统机器学习几乎全部停在第一层;因果推断的野心是从第二层往上走。

来源核验:Pearl 的因果阶梯三层划分(Association / Intervention / Counterfactual)及其对应的「see / do / imagine」能力,经维基百科 The Book of Why 词条核验(已核验);do-calculus 与 front-door criterion 用于第二层干预效应识别亦在该词条确认。Rubin 潜在结果框架(Rubin causal model / potential outcomes)作为社科与流行病学中推断因果性的标准,经维基百科 Causal inference 词条核验(已核验)。

三种因果识别策略:随机实验、工具变量、双重差分

当可忽略性不成立(存在未观测混淆)时,朴素的条件均值之差会偏。下面三种策略各自用一种「巧妙设计」来绕开混淆,得到可信的因果效应。

1. 随机实验(Randomized Experiment / RCT)

最干净的做法:用随机数把样本分到处理组与对照组,使得处理分配 T 与任何混淆(观测的或不可观测的)都独立。这样 E[Y|T=1] - E[Y|T=0] 直接等于 ATE,不需要调整任何变量。代价是贵、慢、有时不道德(不能随机让人吸烟)。它是因果效应的「黄金标准」,也是线上 A/B 测试的理论根基。

2. 工具变量(Instrumental Variable, IV)

当无法随机化、且存在未观测混淆时,找一个「只通过影响 T 来影响 Y、且不直接影响 Y」的变量 Z 作为工具。Z 必须与 T 强相关,但只能通过 T 作用于 Y(排除限制)。直观上:Z 造成的 T 的变动是「外生」的,像一次自然随机化,于是可以用 Z 对 T 的外生变异去识别 T 对 Y 的效应。

  • 典型例子:估计教育年限对收入的影响,用「就近学校的距离」或「出生季度」作工具——它们影响上学时长,却不直接影响收入。
  • 局限:有效工具很难找,弱工具会放大偏差。EconML 提供了 OrthoIVNonParamDMLIV 等基于机器学习的 IV 估计器。

3. 双重差分(Difference-in-Differences, DiD)

当只有「处理组 vs 对照组」且只在「政策前后」有观测(面板/纵向数据),且两组在若无处理时本就平行变化(平行趋势假设),可用两期相减再相减来消去不随时间变的混淆:

DiD 效应 = (处理组后 - 处理组前) - (对照组后 - 对照组前)
        = 处理组的变化量  -  对照组自发的变化量

核心假设是「平行趋势」:若没有处理,两组随时间的变化应当一致,于是对照组的变化量代理了处理组的「反事实」变化。它常用于评估政策、上线新功能对整体指标的影响。

三种策略一句话对比:随机实验靠「人为随机」、工具变量靠「外生工具」、双重差分靠「平行趋势」,本质都是用一个可信的「反事实构造法」替代观测不到的缺失状态。

实战:用 DoWhy 估计因果效应

下面用一个极小数据集演示端到端因果估计。场景:课外辅导 tutoring 是否提升期末成绩 exam_score,存在混淆变量「先验基础 prior_ability」。我们造数据时把真实 ATE 设为 3,看 DoWhy 能否把它估回来。DoWhy 的四步工作流是 model、identify、estimate、refute。

import numpy as np
import pandas as pd
from dowhy import CausalModel

  # 设定随机种子,保证结果可复现
np.random.seed(42)
n = 500

  # 混淆变量:学生的先验基础,同时影响是否参加辅导与考试成绩
prior_ability = np.random.normal(0, 1, n)

  # 处理变量:是否参加课外辅导,受先验基础影响(存在混淆)
tutoring = (prior_ability + np.random.normal(0, 1, n) > 0.5).astype(int)

  # 结果变量:期末考试成绩;真实平均处理效应 ATE = 3
exam_score = 3 * tutoring + 2 * prior_ability + np.random.normal(0, 1, n)

data = pd.DataFrame({
    "prior_ability": prior_ability,
    "tutoring": tutoring,
    "exam_score": exam_score,
})

  # 用 GML 描述因果图:prior_ability 同时影响 tutoring 与 exam_score
graph = """
digraph {
    prior_ability -> tutoring;
    tutoring -> exam_score;
    prior_ability -> exam_score;
}
"""

  # I. 建模:把数据、处理变量、结果变量与因果图喂给 CausalModel
model = CausalModel(
    data=data,
    treatment="tutoring",
    outcome="exam_score",
    graph=graph,
)

  # II. 识别:在给定因果图下求解因果效应的可识别估计量
identified_estimand = model.identify_effect()

  # III. 估计:用后门线性调整估计平均因果效应 ATE
estimate = model.estimate_effect(
    identified_estimand,
    method_name="backdoor.linear_regression",
)

print("估计得到的平均因果效应 ATE:", estimate.value)

  # IV. 反驳:用随机公共原因等稳健性检查验证估计是否可靠
refute = model.refute_estimate(
    identified_estimand,
    estimate,
    method_name="random_common_cause",
)
print(refute)

运行后你会看到估计的 ATE 接近 3,与造数据时埋入的真值吻合,说明后门调整正确地消去了 prior_ability 带来的混淆。如果把 method_name 换成 backdoor.propensity_score_matching,或用 EconML 的 backdoor.econml.dml.DML 估计条件效应 CATE,就进入了异质性处理效应分析。关键不是某个估计器,而是前面那张因果图与 identify 步骤——DoWhy 的与众不同之处在于「先把假设写清楚,再用 refute 去打自己的估计」。

来源核验:DoWhy 的「model / identify / estimate / refute」四步工作流、核心类 dowhy.CausalModel、以及支持 backdoor.propensity_score_matchingbackdoor.econml.dml.DML(集成 EconML)等估计方法,经 DoWhy 官方 GitHub 仓库 README 核验(已核验)。EconML 由微软研究院 ALICE 项目构建、现属 PyWhy 生态,专注异质性处理效应(CATE)估计,提供 Double Machine Learning、Causal Forest、Doubly Robust Learner 等估计器,经 EconML 官方 GitHub 仓库 README 核验(已核验)。

小结

回到开头两个问题,一句话收束:

  • 相关不等于因果:混淆会让「合并看」与「分层看」结论相反(辛普森悖论),相关性回答不了「做了 X 会怎样」。
  • 两大理论支柱:Rubin 潜在结果框架用 Y(1) - Y(0) 定义效应,难点是反事实永远观测不到一半;Pearl 用因果图与 do() 干预把这个问题变成「剪断入边后 Y 怎么变」,并给出从关联到反事实的三层因果阶梯。
  • 三种识别策略:随机实验靠人为随机、工具变量靠外生工具、双重差分靠平行趋势,本质都是可信地构造反事实。
  • 工程落地:DoWhy 把「先画因果图、再识别、再估计、最后用 refute 反驳」流程化,让你把机器学习的预测能力升级为可干预、可解释的因果效应估计。

什么时候该用?A/B 之外想量化「如果……会怎样」的任何场景:定价、补贴、推荐策略、政策评估、增长率归因。只要问题里出现「导致」「如果」「反事实」,你就该离开纯相关模型,换上因果这副眼镜。

参考与延伸阅读

  1. Pearl, J. 与 Mackenzie, D.《The Book of Why: The New Science of Cause and Effect》,Basic Books,2018(因果阶梯三层划分与 do-calculus 的出处;已核验,经维基百科 The Book of Why 词条核验)。
  2. Rubin, D. B. 潜在结果框架(Rubin causal model / potential outcomes),作为社科与流行病学因果推断标准(已核验,经维基百科 Causal inference 词条核验)。
  3. DoWhy 官方 GitHub 仓库(已核验):因果推断库,四步工作流 model / identify / estimate / refute,核心类 dowhy.CausalModel,支持后门调整、工具变量、DML 等估计方法。
  4. EconML 官方 GitHub 仓库(已核验):微软研究院 ALICE 项目构建、现属 PyWhy 生态,提供 DML、Causal Forest、Doubly Robust 等异质性处理效应估计器。
  5. Imbens, G. W. 与 Rubin, D. B.《Causal Inference for Statistics, Social, and Biomedical Sciences: An Introduction》,Cambridge University Press,2015(潜在结果框架的系统教材;待核实,本文未做 WebFetch 核验,建议引用前自行核对)。
  6. 辛普森悖论(Simpson’s paradox)的标准例子与分层反转机制(待核实,本文未做 WebFetch 核验,建议引用前自行核对)。
  7. Angrist, J. D. 与 Pischke, J. S.《Mostly Harmless Econometrics》,Princeton University Press,2009(工具变量与双重差分的计量经济学入门;待核实,本文未做 WebFetch 核验,建议引用前自行核对)。
本文累计阅读