想象你是城市水务局新来的工程师。你的辖区里,水从水库流向水塔,再从水塔通向千家万户;暴雨、管网压力、漏水报警之间的关系极其复杂。你手里没有管网图纸,只有一堆水表历史数据:压力高的时候,漏水报警也常常出现。这是相关。但如果有人问“把压力调低 10%,漏水能减少多少?”,历史数据不能直接回答——因为压力高可能只是暴雨带来的附带现象。你真正需要的是一张管网蓝图和一套物理定律说明书。管网蓝图叫 DAG(有向无环图),说明书叫 SCM(结构因果模型)。蓝图告诉你谁直接影响谁;说明书告诉你每段管道如何把上游变成下游;“拧阀门”就是干预操作 do();“如果刚才没拧这个阀门,现在会怎样”就是反事实推理。本篇文章会带你从这张蓝图出发,一步步学会用结构方程、干预、反事实和潜在结果回答真正的因果问题。
学会用 DAG/SCM 思考,你就能从观测数据中分离相关与因果,设计可识别策略,让 AI 不再只会预测,还能回答“做了某件事会怎样”。
可视化演示
动态演示DAG结构因果模型(SCM)的核心机制,通过基础/核心/应用/扩展四种模式展示关键概念与交互流程。
本节配有交互动效(进入视口后自动加载,约 3KB)。
DAG结构因果模型(SCM):DAG有 DAG有向无环图的结构与性质 结构因果模型SCM形式化定义 核心机制可视化 DAG结构因果模型(SCM)整体架构与关键组件
因果图基础
水务局的第一件事是画蓝图。你不直接看历史数据,而是先标出哪些水塔之间真正有管道直连:暴雨 Z 会抬高水塔 X 的水位,也会让管道 Y 更容易漏水;同时水塔 X 的压力还会直接影响漏水。这张蓝图上,每个水塔是一个节点,每条带箭头的管道是一条有向边,箭头永远从上游指向下游。水不可能自己倒流回去形成循环,所以这张图必须是“有向无环图”,简称 DAG。
DAG 不是从数据里自动长出来的,而是研究者根据领域知识预先画出的假设画布。数据只是用来检验这些假设带来的推论。如果蓝图本身画错,后面所有的因果计算都会失去依据。DAG 的价值在于把隐性的因果假设显式化:哪些变量是父节点,哪些路径应该存在,哪些不存在。
有了蓝图,我们还能判断条件独立性。如果想知道在固定 Z 的信息之后,X 和 Y 之间是否还存在关联,就可以用 d-分离的概念。直观地说,给定 Z 后,从 X 到 Y 的所有管道要么被中间阀门堵住,要么因为碰撞器结构而失去联系,那么 X 和 Y 在图中是条件独立的。
回到管网场景:DAG 上的每条边都是可质疑的假设。数据能帮你淘汰一些明显不合理的蓝图,但它不能凭相关矩阵凭空画出管道。先有蓝图,后有因果,这是整个因果推断的起点。
- \(X\) 与 \(Y\)两个待判断是否关联的水表节点,对应 DAG 中任意两个变量。
- \(\perp\!\!\!\perp\)统计上的条件独立符号,表示“互不流通”。
- \(\mid Z\)在已知 Z 取值的条件下,相当于把 Z 这个水闸固定住。
- d-分离含义若给定 Z 后 X 到 Y 的所有路径都被阻断,则称 X 与 Y 在 DAG 中 d-分离。
结构方程模型
蓝图只告诉我们谁连谁,还没告诉我们水位到底怎么变。结构因果模型(SCM)就是给每段管道配上物理公式。水务工程师不会只说“上游影响下游”,还会写清楚:水塔 X 的水位等于多少倍的上游水位加上多少随机扰动。这种“管道转换规则”就是结构方程。
在 SCM 中,每个变量都由两部分决定:它的直接父节点,以及未被写入模型的外生扰动。父节点是图中指向它的那些节点,外生扰动则像暴雨、管道老化、传感器噪声等一切“图纸外”的因素。我们用 \(U_i\) 保存这些外生信息,它们非常重要,因为反事实推理要依赖它们。
SCM 的结构方程可以统一写成下面的形式:
如果 \(f_i\) 是线性函数,结构方程就退化为我们熟悉的线性回归形式,但它的意义截然不同:回归方程描述的是条件期望,而结构方程描述的是物理机制。水塔之间的因果效应,就藏在管道函数 \(f_i\) 的参数里。
- \(X_i\)第 \(i\) 个内生变量,也就是蓝图中需要被解释的水塔。
- \(f_i\)第 \(i\) 根管道的转换规则,它决定了上游如何变成下游。
- \(PA_i\)\(X_i\) 的直接父节点集合,即所有直接指向 \(X_i\) 的节点。
- \(U_i\)外生扰动变量,代表所有未进入 DAG 的随机因素。
do干预
看到水表读数高,和亲手把阀门拧到高位,在因果推断中是两件完全不同的事。前者是“观察”,后者是“干预”。在 SCM 中,观察对应条件分布,干预对应 do 操作。假设我们想强制把 X 固定在某个值 \(x\),那么原来的管道图必须修改:所有指向 X 的入边都会被剪断,因为外部干预替代了自然机制,只有 X 的出边还保留着。
这个被剪过的管网模型叫 \(M_x\)。在 \(M_x\) 中,X 不再是内生变量,而是一个被外部设定的常数。于是 Y 的分布不再是“看到 X=x 时 Y 的分布”,而是“强制 X=x 时 Y 的分布”,记作干预分布:
回到暴雨的例子:暴雨 Z 会同时影响 X 和 Y,所以“观察到 X 高时 Y 也高”可能只是混杂造成的假象。但 do 之后,暴雨无法再通过 X 传递影响,我们就得到了真正的因果效应。这正是随机对照实验在观测数据中的数学化身。
- \(P(Y=y)\)下游水表读数为 \(y\) 的概率分布。
- \(\mid do(X=x)\)不是“观察到 X=x”,而是“人为把 X 固定为 x”。
- \(P_{M_x}\)经过删入边操作后的子模型分布,阀门被替换成外部设定。
- 等式整体干预后的 Y 分布等于剪断入边后的新管网中 Y 的分布。
反事实推理
反事实是因果推断中最具“平行世界”色彩的概念:同一场暴雨、同一段管道老化程度,如果当初把 X 阀门拧到另一个值,Y 的读数会是多少?SCM 保留了每个个体的外生扰动 U,因此我们可以把这些扰动固定住,只改变 X 的取值,重新做一次管道计算。
这个“重演历史”的结果记作 \(Y_{X=x}(u)\),读作“在外生状态下,把 X 干预为 x 时 Y 的结果”。它不是一个整体均值,而是个体层面的反事实结果。经典的因果推理三步法是:先根据观测数据和结构方程推断出这个个体的外生扰动 U,再执行 do(X=x) 修改结构方程,最后预测 Y 的值。
反事实推理不是“对新人做预测”,而是“对同一个老人重新拍一部电影”。这种个体层面的反事实表达,正是潜在结果框架的数学基础。
- \(Y_{X=x}\)反事实结果的记号,表示“干预 X 为 x 时 Y 的值”。
- \((u)\)固定同一个外生扰动状态,也就是同一个体的暴雨、管道老化等背景。
- \(f_Y\)Y 的结构方程,描述 Y 如何由 X 和外生扰动决定。
- \(x\)在结构方程中,把 X 替换成假设的干预值。
潜在结果框架
从反事实记号出发,自然能得到潜在结果框架。每个个体都有两个潜在结果:接受处理时的结果 \(Y_i(1)\),以及未接受处理时的结果 \(Y_i(0)\)。现实中我们只能观察到其中一个,另一个藏在平行世界里。若把两者的差在全体个体上取平均,就得到平均处理效应。
潜在结果和 SCM 通过一致性条件联系起来:如果个体实际接受了 \(X=1\),观察到的 Y 就是 \(Y_i(1)\);如果实际接受了 \(X=0\),观察到的 Y 就是 \(Y_i(0)\)。这个条件保证我们不会把观察值和反事实值张冠李戴。
潜在结果框架告诉我们:因果推断的困难,不是因为效应不存在,而是因为每个人只有一个可观测结果。DAG/SCM 的价值,就是用结构和干预规则帮我们补上另一条平行世界的数据。
- \(Y_i(1)\)第 \(i\) 个个体在接受干预 \(X=1\) 时的潜在结果。
- \(Y_i(0)\)第 \(i\) 个个体在对照状态 \(X=0\) 时的潜在结果。
- \(Y_i(1) - Y_i(0)\)个体层面的因果效应,也就是同一个水塔两个阀门位置的漏水差。
- \(\mathbb{E}[\cdot]\)对全部个体求平均,得到平均处理效应。
后门准则与识别
在实际数据中,我们通常不能真的做干预,只能靠观测数据识别因果效应。这时需要回答:控制哪些变量,才能让观测估计等价于 do 估计?如果 X 和 Y 之间存在一条“后门路径”,也就是不经过 X→Y 这条前门路径、但有一条边指向 X 的路径,那么混杂就可能通过这条路径溜进来。
后门准则说的是:如果我们能找到一组变量 Z,阻断 X 到 Y 的所有后门路径,并且 Z 不包含 X 的后代,那么通过 Z 进行分层调整,就可以把因果效应识别出来。调整公式如下:
后门准则把因果问题变成了可计算的统计问题。它提醒我们,控制变量不是越多越好,而是要精准地阻断后门路径;否则就像在管网里乱关阀门,可能打开新的泄漏通道。
- \(Z\)满足后门准则的调整变量集合,用来阻断所有后门路径。
- \(P(Y=y \mid X=x, Z=z)\)在 X 和 Z 都固定的情况下,Y 的分布。
- \(P(Z=z)\)调整变量 Z 在总体中的概率,相当于权重。
- \(\sum_z\)对所有 Z 取值加权求和,把混杂效应“摊平”。
因果效应估计
当后门调整集 Z 确定之后,下一步就是用数据估计因果效应。在常见的线性 SCM 中,Y 由 X、Z 和噪声线性生成,因此我们可以直接用带协变量的回归来估计。此时回归方程里的 \(X\) 的系数 \(\tau\),就对应结构方程中 X 对 Y 的因果效应。
需要注意,这里的回归并不是普通的相关回归,而是“带上后门调整集”的结构性回归。只有当 Z 满足后门准则时,\(\tau\) 才等于 \(do(X=x)\) 的效应;否则它只是又一个被混杂污染的相关系数。
估计完成不代表万事大吉。我们还要做敏感性分析:如果存在未观测混杂 U 没有进入 DAG,需要多强的 U 才能推翻当前的结论?这一步就像检查管网图纸是否漏画了一条地下暗管。只有把假设、识别和敏感性分析串起来,SCM 才能真正服务于因果决策。
- \(Y_i\)第 \(i\) 个观测个体的结果变量。
- \(X_i\)第 \(i\) 个观测个体的处理变量,我们关心它的因果效应。
- \(Z_i\)后门调整集中的协变量向量。
- \(\tau\)X 对 Y 的因果效应参数,是 do 干预下的斜率。
- \(\varepsilon_i\)剩余的随机扰动,对应结构方程中的外生噪声。
AI 应用场景
医疗中的因果效应识别
阶段:观察性数据下的因果效应估计
解决的问题:电子病历里记录了血压药使用 X 和心梗发生率 Y,但年龄、基础疾病等混杂因素 Z 同时影响用药和结局。传统预测模型只能回答“用了药的人风险多高”,无法回答“用药带来的风险变化是多少”。
具体案例:研究者用 DAG 画出“年龄 → 用药”“年龄 → 心梗”“用药 → 心梗”的因果结构,确定年龄和既往病史为后门调整集,再用调整公式从数万条病历中估计药物对心梗的平均处理效应。最终结论可为临床用药决策提供依据。
推荐系统里的纠偏
阶段:模型训练前的混淆控制
解决的问题:推荐系统中,用户是否点击广告 X 与是否购买 Y 都受用户历史偏好 Z 影响。直接统计点击与购买的相关会被偏好放大,导致高估推荐效果。
具体案例:算法团队用 SCM 建模“偏好 → 点击”“偏好 → 购买”“点击 → 购买”,通过后门调整估计“强制推送给用户”的干预效果,再结合小流量 A/B 实验校正偏差,让推荐策略评估更接近真实因果。
反事实客户挽留
阶段:个体层面反事实评估
解决的问题:客服团队想对不同用户回答“如果当初发送了优惠券,用户留存会提高多少”。传统模型只能预测“这批用户可能流失”,却无法给出同一个用户的平行结果。
具体案例:基于 SCM 建立“用户活跃度 X → 流失 Y”并保留用户特征作为外生扰动 U,对已流失用户做反事实推理:保持其历史特征不变,把优惠券状态从 0 改为 1,计算留存提升幅度,从而筛选出最值得挽回的用户。
Python 演示
import numpy as np def simulate_scm(n=20000, seed=42): rng = np.random.default_rng(seed) z = rng.normal(size=n) # 外生混杂变量:暴雨 x = 0.8 * z + rng.normal(size=n) # 处理变量:水压 y = 1.5 * x + 0.6 * z + rng.normal(size=n) # 结果:漏水 return z, x, y def naive_effect(x, y): return np.polyfit(x, y, 1)[0] def adjusted_effect(z, x, y): design = np.column_stack([x, z]) coefs, _, _, _ = np.linalg.lstsq(design, y, rcond=None) return coefs[0] def do_intervention(z, x_value, seed=1): rng = np.random.default_rng(seed) y = 1.5 * x_value + 0.6 * z + rng.normal(size=z.size) return y.mean() if __name__ == "__main__": z, x, y = simulate_scm() print("Naive slope:", naive_effect(x, y)) print("Adjusted slope:", adjusted_effect(z, x, y)) print("E[Y|do(X=1)] - E[Y|do(X=0)]:", do_intervention(z, 1) - do_intervention(z, 0))
z = rng.normal(size=n)生成外生混杂变量 Z,对应管网里的暴雨。x = 0.8 * z + rng.normal(size=n)X 的结构方程:X 受 Z 影响,也带随机扰动。y = 1.5 * x + 0.6 * z + rng.normal(size=n)Y 的结构方程:真实因果效应是 1.5,同时 Z 直接混杂。np.polyfit(x, y, 1)[0]朴素回归只拟合 X 和 Y,会把 Z 的混杂也算进斜率。np.linalg.lstsq(design, y, rcond=None)把 Z 加入回归,等价于后门调整,调整后斜率接近真实值 1.5。do_intervention固定 X 为某个值,再从结构方程生成 Y,得到干预分布下的期望。
常见误区
误区我用相关性矩阵就能画出 DAG,箭头方向就是相关系数方向,相关系数高就画一条边。
正解DAG 是因果假设的显式表达,不是数据自动挖掘的结果。箭头方向必须来自领域知识、实验设计或可检验的因果假设。数据只能帮忙证伪部分结构,不能无中生有画出管道。
为何常见:相关矩阵是对称的,初学者很容易把“变量一起变化”误当成“一个变量造成另一个变量”,于是把相关强度直接翻译成因果箭头。
误区回归里已经有 `E[Y|X=x]`,只要把 X 放进模型,系数就是干预效应,do 和条件没什么区别。
正解条件分布保留 X 的所有入边,X 仍然被上游混杂影响;do 操作会删除 X 的所有入边,并把 X 固定为 x。只有不存在混杂时,二者才相等。
为何常见:机器学习里我们常用 P(Y|X) 做预测,习惯了“看到 X 就预测 Y”,忽略了干预会改变整个数据生成机制的物理事实。
误区只要把能测到的人口学变量、行为变量全部加入回归,总能消除混杂。
正解因果图上不同节点角色不同。控制碰撞器会打开新的虚假路径,控制中介变量会阻断部分因果路径。变量选择必须根据 DAG 和后门准则,而不是“越多越好”。
为何常见:直觉认为信息越多越安全,但管网里有些阀门不能随便关:关错阀门不但不能堵漏,反而会制造新的泄漏通道。
误区`Y_{X=x}(u)` 就是机器学习模型输出的预测值 \( \hat{y} \)。
正解预测均值通常是对新样本的平均猜测,反事实则是对同一个体、同一个外生扰动 \(u\) 重新执行一次干预。保留个体层面的 \(u\) 是反事实区别于普通预测的核心。
为何常见:监督学习只关心条件期望,不需要维护个体级结构方程,因此容易把“换个 X 重新算 Y”与“同一个体重演历史”混为一谈。
面试题
Q1. DAG 中的一条有向边 X→Y 最可能表示什么?
- A.数据中的相关联系
- B.假设中的因果方向← 正确答案
- C.机器学习预测方向
- D.观测到的时间先后顺序
答案:B。DAG 里的有向边表示研究者假设的因果方向,也就是 X 直接导致 Y。相关关系没有方向,机器学习预测方向是反向的,时间先后也不等于因果。
Q2. 在 DAG 中,一个未观测变量 U 同时指向 X 和 Y,U 在 X→Y 研究中通常被称为?
- A.中介变量
- B.混杂变量← 正确答案
- C.碰撞因子
- D.工具变量
答案:B。U 同时影响 X 和 Y 时,U 是常见的混杂变量。它会让 X 与 Y 产生虚假关联,就像暴雨同时抬高压力和漏水,导致压力与漏水看起来相关。
Q3. 关于后门准则,下列说法正确的是?
- A.需要阻断所有后门路径← 正确答案
- B.不能包含 X 的后代节点← 正确答案
- C.一定包含所有可测变量
- D.只需控制中介变量即可
答案:AB。后门准则要求调整集 Z 阻断 X 到 Y 的所有后门路径,并且不包含 X 的后代节点。控制所有变量或只控制中介都可能引入偏倚,因此 C、D 错误。
Q4. do(X=x) 的含义最准确的是?
- A.只保留 X 等于 x 的样本
- B.强制每个个体取 X 为 x← 正确答案
- C.用模型预测 X 得到 x
- D.删除 X 的所有出边
答案:B。do(X=x) 是人为干预,把每个个体的 X 强制设定为 x,同时删除指向 X 的入边。它不等于筛选样本,也不等于预测,更不是删除出边。
Q5. 关于反事实 \(Y_{X=x}(u)\),正确的理解是?
- A.同一单位在干预下的结果← 正确答案
- B.需要保留外生变量 U← 正确答案
- C.等于条件期望 E(Y|X=x)
- D.需要替换 X 的结构方程← 正确答案
答案:ABD。反事实是同一个体在外生状态 u 下,把 X 干预为 x 后的结果。它需要保留 U,并替换 X 的结构方程。条件期望是聚合层面的预测,不保留个体扰动,因此 C 错误。
Q6. 结构方程 \(X_i=f_i(PA_i,U_i)\) 中 PA_i 表示什么?
- A.变量 X_i 的父节点集合← 正确答案
- B.变量 X_i 的子节点集合
- C.模型中的全部外生变量
- D.模型中的全部内生变量
答案:A。PA_i 是直接指向 X_i 的父节点集合。结构方程的意思是 X_i 由它的父节点和外生扰动 U_i 共同生成,与子节点和外生总集无关。
Q7. 在 DAG 中,Z 是碰撞器(X→Z←Y),若回归时控制 Z 会怎样?
- A.消除 X 与 Y 的混杂
- B.引入虚假的相关关系← 正确答案
- C.使 X→Y 因果效应增大
- D.让估计结果更无偏
答案:B。碰撞器是两个变量的共同结果。控制 Z 会把原本独立的 X 和 Y 变成条件相关,打开一条虚假路径,导致偏倚。因此不能随意把碰撞器放入调整集。
Q8. 关于 \(P(Y|X=1)\) 与 \(P(Y|do(X=1))\),哪些说法正确?
- A.后者删除了 X 的入边← 正确答案
- B.前者可能受混杂变量影响← 正确答案
- C.两者在任何情况下都相等
- D.后者模拟随机对照试验← 正确答案
答案:ABD。do 操作删除 X 的入边,模拟随机对照试验;普通条件分布仍保留入边,所以可能受混杂影响。两者只在无混杂时相等,C 的“任何情况”太绝对。
Q9. 潜在结果记号 \(Y_i(1)\) 表示什么?
- A.第 i 个个体接受干预 1 的结果← 正确答案
- B.第 i 个个体未接受干预的结果
- C.第 i 个个体实际观察到的结果
- D.第 i 个个体预测误差
答案:A。\(Y_i(1)\) 表示第 i 个个体在接受处理 \(X=1\) 时的潜在结果。它不一定能被观察到,但可以借助 SCM 和反事实来推演。
Q10. 在结构因果模型中,要识别 X 对 Y 的因果效应,最基本的要求是?
- A.模型包含全部混淆因子
- B.后门路径全部被阻断← 正确答案
- C.数据样本量足够大
- D.变量间不存在相关
答案:B。根据后门准则,只要有合适的调整集 Z 阻断 X 到 Y 的所有后门路径,因果效应就能从观测数据中识别。样本量大不等于无混杂,变量完全无相关也无法估计效应。