阿泉是清水市的供水规划员。日常工作,是根据各水站水位数据推断城市管网的结构:哪个水站的水流到哪个水站、上游水量变化会传到哪里。但数据不会直接告诉他答案——夏天降雨量暴涨,全城水位齐涨,他差点以为东区管道和西区管道直接相连;调节站开闸放水,下游水压骤增,他又差点把“打开阀门”误当成“降雨增多”的原因。 后来阿泉学会了一个方法:把所有可能影响水位的变量画成一张图。圆圈代表水站(变量),箭头代表水流方向(因果方向)。这张图必须遵守两条铁律:管道有方向,不可倒流;管网没有环,水不会绕回同一水站。这就是“有向无环图”——DAG。 在因果推断的世界中,DAG是研究者关于因果结构的假设蓝图:哪些变量之间存在直接影响、箭头从谁指向谁、哪里有第三方变量在暗中搅局。掌握了DAG构建,你就能像阿泉一样,在庞杂的观测数据面前,清楚地指出——这背后真正的水管,到底是怎么接的。

岗位关联

DAG 是因果推断的第一块基石。掌握 DAG 构建,你就能仅凭研究设计和领域知识判断“谁因谁果”,识别混淆变量、选择调整集,让数据背后的因果链条清晰可见——这是每个 AI 从业者从“预测”走向“决策”的必修课。

目录
  1. 可视化演示
  2. DAG基本概念
  3. 节点与边定义
  4. 因果方向确定
  5. 混淆变量控制
  6. d分离判据
  7. 因果假设
  8. 领域知识构建
  9. 因果分析指导
  10. AI 应用场景
  11. Python 演示
  12. 常见误区
  13. 面试题

可视化演示

展示DAG节点与有向边结构、混杂变量后门路径控制、以及d-分离判据验证条件独立性。

本节配有交互动效(进入视口后自动加载,约 3KB)。

DAG有向无环图结构 有向边表示因果方向,无环保证无因果循环 X→Y: X causes Y DAG编码领域知识的因果假设

DAG基本概念

阿泉在白板上画清水市的供水管网时,先定了三件事:圆圈代表水站,箭头代表水管方向,水管绝不能围成一个圈。没有这三条,这张图就是一张“死图”——水会循环回流,阿泉永远说不清水到底流向哪里。DAG 的直觉,就是这么朴素:节点、有向边、无环,三个要素构成因果世界的骨架。

在因果推断中,DAG 把“变量之间如何互相影响”这个问题,转录成一张可计算、可推理的图。节点是研究涉及的变量;有向箭头表示一个变量对另一个变量的直接因果效应;“无环”则保证因果世界不会出现“先有鸡还是先有蛋”式的循环依赖。正是因为无环,因果才可以沿着箭头的方向一步一步向前传导。

形式化地看,一个 DAG 可以写作二元组:

阿泉把图纸贴在墙上,越看越明白:数据只是水位的读数,而 DAG 才是管网本身的结构图。有了结构,每一次水位跳动的“为什么”都有了答案。

G=(V,E)\displaystyle G = (V, E)
这张“图纸”由两类零件组成:V 是节点集合(所有变量),E 是有向边集合(所有因果箭头)。记住:没有 E,图就只是孤立的变量清单,谈不上因果。
  1. G 代表 DAG 本身G 是整个有向无环图的符号,相当于阿泉手中那张完整的供水管网图纸。
    G\displaystyle G
  2. V 是节点集合V 是图中所有变量的集合,每个变量(水站)都是图中的一个圆点。
    V={V1,V2,…,Vk}\displaystyle V = \{V_1, V_2, \dots, V_k\}
  3. E 是有向边集合E 是变量之间有向箭头的集合,每条边表示一对变量之间存在直接因果效应。
    E⊆{(Vi,Vj):Vi,Vj∈V}\displaystyle E \subseteq \{(V_i, V_j) : V_i, V_j \in V\}

节点与边定义

阿泉开始给水站分类:有从天上接雨水的源头站,有把水送到千家万户的终端站,还有夹在中间帮忙调节压力的传输站。分类清楚后,他还要标注每个水站的“入水口”——所有直接向它供水的上游管道。在 DAG 里,这组上游节点有个响当当的名字:父节点。

DAG 的节点并非千篇一律。在研究设计中,我们关注三类角色:处理变量 X(我们想操控的原因)、结局变量 Y(我们关心的结果)、以及第三变量(包括混淆因子、对撞因子、中间变量等)。边则是变量间的“直接因果效应”——注意“直接”二字:如果 X 通过 M 影响 Y,那么 X 和 Y 之间不需要画边,真正画的是 X→M 和 M→Y。

父节点集合是刻画“直接原因”的精确语言。给定一个节点 V_i,它的父节点就是所有存在一条有向边直接指向 V_i 的变量:

阿泉在图纸上给每个水站都写下一串“上游清单”。他后来发现,这份清单正是判断“如果上游停水,这个站会不会断水”的关键依据。

Pa(Vi)={Vj∈V:Vj→Vi}\displaystyle \text{Pa}(V_i) = \{V_j \in V : V_j \to V_i\}
父节点集就是 V_i 的“直接因果来源”清单。在因果分析中,一旦确定了父节点集,就等于确定了这个变量的所有直接原因,剩余的影响都被视为外部噪声。
  1. 左侧 Pa(V_i) 表示父节点集Pa(V_i) 是 V_i 的所有父节点组成的集合,也就是所有“直接原因”的集合,像水站上方所有直接连入的进水管。
    Pa(Vi)\displaystyle \text{Pa}(V_i)
  2. 条件 V_j ∈ V 说明候选范围能做父节点的变量必须先存在于整张图的节点集中,DAG 之外的变量不在考虑之列。
    Vj∈V\displaystyle V_j \in V
  3. 箭头 V_j → V_i 限定直接因果集合中每个 V_j 都有一条指向 V_i 的有向边,没有箭头就没有直接因果,只有间接路径。
    Vj→Vi\displaystyle V_j \to V_i

因果方向确定

给水站之间画箭头,是阿泉工作中最纠结的一步。他通常靠三个证据:看海拔——高处的水站一定是低处水站的上游;看试验——打开上游闸门,下游水位应声上涨;看图纸——规划局的老档案里白纸黑字写着管道走向。三条证据交叉验证,箭头方向才敢落笔。

DAG 构建中最容易出错、也最需要领域知识的环节,就是确定边的方向。数据只能告诉你两个变量“相关”,却无法告诉你“谁影响谁”。方向判断必须借助三个来源:时间先后(原因必在结果之前出现)、干预推理(操控原因会系统性改变结果)、理论机制(领域知识为因果路径提供物理解释或机制依据)。把方向画反,整个因果效应估计会颠倒黑白。

为了表达“干预”与“观测”的差别,因果推断引入了 do 算子。我们关心的因果量写为:

阿泉把这三条证据和 do 算子的理念记在笔记本上。他意识到:因果方向的确定不是统计技巧,而是工程判断——数据统计只负责告诉你“水管在震动”,方向要靠逻辑和知识去定位。

P(Y∣do(X=x))\displaystyle P(Y \mid \text{do}(X = x))
do(X=x) 读作“把 X 强制设定为 x”,它模拟随机对照试验中的物理干预。这与普通条件概率 P(Y | X=x) 截然不同——后者只是“看到 X=x 时 Y 的分布”,混入了太多混淆信息。
  1. do(X=x) 是干预操作符do 算子表示把 X 从系统外部强制固定为某个值 x,相当于阿泉亲手拧开水站的阀门,而不是坐等水位自己变化。
    do(X=x)\displaystyle \text{do}(X = x)
  2. P(Y | ·) 是干预后的结果分布该式刻画的是在施加干预之后,结果变量 Y 会呈现什么样的概率分布,所有因果机制会沿着图中的路径自然传导。
    P(Y∣⋅)\displaystyle P(Y \mid \cdot)
  3. 观测条件概率与干预概率完全不同观测 P(Y|X=x) 里混入了 X 与 Y 的共同原因的影响,而 do 表达式则切断了所有指向 X 的非因果路径。
    P(Y∣X=x)≠P(Y∣do(X=x))\displaystyle P(Y \mid X = x) \neq P(Y \mid \text{do}(X = x))

混淆变量控制

一个夏天的清晨,阿泉发现东区和西区的水位数据相关得离谱,可管网图上两区明明没有管道相连。排查了三天,罪魁祸首是降雨——一场暴雨同时抬高了两个区的水位。这就是混淆因子:一个同时影响原因和结果的第三变量,让两个本无因果的变量“看起来”被一根无形的水管连在一起。

混淆因子(confounder)是 DAG 中最危险的“地下渗水点”。只要存在一条非因果路径(如 Z→X 和 Z→Y)连接 X 与 Y,观测到的相关性就会与真实因果效应混合,产生偏差。更棘手的是对撞因子(collider):两个变量的箭头同时指向它,例如 X→C←Y。直观上你会觉得“把 C 控制住更干净”,但恰恰相反——条件于对撞因子会开放一条虚假路径,人为制造相关性。

控制混淆的标准武器是后门调整。给定混淆因子 Z,X 对 Y 的因果效应可以通过对 Z 分层加权来还原:

阿泉把降雨量数据从信号中“剥离”之后,东区与西区的“相关神话”不攻自破。混淆因子是幽灵般的地下渗水,看不见摸不着,但只要管网图(DAG)画得全,它的藏身之处就一览无余。

P(Y∣do(X))=∑zP(Y∣X,Z=z) P(Z=z)\displaystyle P(Y \mid \text{do}(X)) = \sum_{z} P(Y \mid X, Z=z) \, P(Z=z)
左边是要估计的因果效应,右边是把混淆因子 Z 分层(按每个取值)后,求各层效果按 Z 分布加权的平均。这就像阿泉把所有降雨量相同的历史时段归为一组,再比较“开闸”与“不开闸”的水位差异。
  1. 求和符号 Σ_z 表示对 Z 分层把混淆因子 Z 的每个可能取值都遍历一遍,每个取值对应一个子组。
    ∑z\displaystyle \sum_{z}
  2. P(Y | X, Z=z) 是层内条件概率在给定处理 X 和混淆因子取值 Z=z 的层内,结果 Y 的条件分布。
    P(Y∣X,Z=z)\displaystyle P(Y \mid X, Z=z)
  3. P(Z=z) 是加权权重乘以混淆因子取各值的边缘概率,把各层效果按真实分布合并成总效应。
    P(Z=z)\displaystyle P(Z=z)

d分离判据

阿泉在管网里装了水闸。他发现一个有趣现象:只要把中间某道闸门关上,上游水位无论怎么涨,下游的传感器都纹丝不动——信息被闸门切断了。在 DAG 世界里,这个“闸门”就是条件变量集合 Z,而“信息是否还能流通”的判定规则,就是 d 分离(d-separation)。

d 分离回答一个关键问题:给定变量集 Z 后,X 和 Y 还独立吗?如果 X 到 Y 的每一条路径都被 Z 阻断,那么 X 和 Y 在给定 Z 下条件独立,记作 X ⊥ Y | Z。判断路径是否被阻断,要看路径的三种结构:链(X→M→Y)、分叉(X←Z→Y)、对撞(X→C←Y)。链和分叉在没有条件时开放,条件于中间节点后阻断;对撞则相反——不开路时天然阻断,一旦条件于对撞节点(或其后代),反而开放。

d 分离的形式化表达:

阿泉靠着这套“闸门逻辑”,在图纸上快速排查:哪些传感器之间即使不看数据也知道彼此无关。d 分离把“独立性”从数据假设变成了一纸图论判据——省去了无数次瞎试回归的徒劳。

X⊥ ⁣ ⁣ ⁣⊥Y∣Z\displaystyle X \perp\!\!\!\perp Y \mid Z
读作“在给定 Z 的条件下,X 与 Y 条件独立”。d 分离是因果图的“电路通则”——它告诉你哪些节点之间还有电流(信息流),哪些已被闸门阻断。
  1. 左侧 X 与 Y 表示两个研究变量我们要判断这两个变量之间是否还存在开放的信息路径。
    X,Y\displaystyle X, Y
  2. 双垂线符号表示条件独立读作“垂直于”,是条件独立的数学记号,表示给定 Z 后二者在概率上互不影响。
    ⊥ ⁣ ⁣ ⁣⊥\displaystyle \perp\!\!\!\perp
  3. 竖线后的 Z 是条件集Z 是我们“关上的一批闸门”,它可以是单个节点,也可以是节点集合。
    ∣Z\displaystyle \mid Z

因果假设

阿泉的图纸要被市长采纳,还必须经受三问:第一,你是不是把所有可能影响水位的管线都画全了?第二,这些箭头方向有沒有画反?第三,依据这张图,能不能算出“调高闸门一尺,下游水压变化几许”?这三问,正是 DAG 构建必须承诺的三大因果假设。

第一问是充分性:图中必须包含所有共同原因。遗漏任何一个混淆因子,后门调整就无法闭合所有非因果路径。第二问是准确性:边的方向必须与真实因果方向一致。方向画反,等同于把水管接反,整个推导崩塌。第三问是可识别性:在给定数据和图结构的条件下,目标因果效应理论上可以从观测分布中分离出来。若不可识别,再完美的图也只是纸上谈兵。

可识别性的核心假设——条件可忽略性(无未观测混淆)——可写为潜在结果的形式:

阿泉在图纸右下角郑重写上三条假设,像工程师签署的验收承诺。他知道:DAG 不是对数据的描述,而是对世界如何运作的信念——信念对了,因果推断才站得住。

Y(x)⊥ ⁣ ⁣ ⁣⊥X∣Z\displaystyle Y(x) \perp\!\!\!\perp X \mid Z
它说:在给定混淆集 Z 后,潜在结果 Y(x) 与处理分配 X 相互独立。换句话说,Z 已经“吸收”了所有系统偏差,处理分组仿佛是随机发生的——阿泉可以安心地把观测数据当作一次“天然实验”。
  1. Y(x) 是潜在结果当处理变量 X 被外部强制设为 x 时,结局 Y 会呈现的值,这是反事实框架的语言。
    Y(x)\displaystyle Y(x)
  2. 条件独立符号表示无混淆在给定 Z 的前提下,潜在结果与实际处理分配独立,即不存在未观测到的共同原因。
    ⊥ ⁣ ⁣ ⁣⊥X∣Z\displaystyle \perp\!\!\!\perp X \mid Z
  3. Z 是充分调整集Z 必须包含所有共同原因,这正是充分性假设的量化表达,缺一个变量,独立性就被打破。
    Z\displaystyle Z

领域知识构建

阿泉的管网图不是电脑自动生成的,而是他顶着烈日巡查井盖、翻遍城市档案、和老工程师一顿顿午饭聊出来的。领域知识永远是 DAG 构建的第一原料:没有它,再精致的统计算法也不知道“吸烟”和“打火机”到底谁是肺癌的原因。

构建 DAG 的流程可归纳为四步。第一步,明确研究问题,写下目标处理变量 X 和结局 Y。第二步,利用文献、专家经验和机制理论,列出所有可能涉及的第三变量(混淆因子、对撞因子、中介变量)。第三步,逐一判断变量间是否存在直接因果效应,画出箭头。第四步,整体校验:检查无环性,审视每条边的方向依据,必要时删边、改向、增补变量,迭代修正。

构建过程中的合理性判据,可以用因果马尔可夫条件来表述:

阿泉的图纸最终贴满了整整一面墙。他微微一笑:一张好图胜过一千次盲目分析。领域知识是 DAG 的“图纸”,而 DAG 是因果推断的地基——没有地基,再多数据也是沙上筑塔。

Vi⊥ ⁣ ⁣ ⁣⊥NonDesc(Vi)∣Pa(Vi)\displaystyle V_i \perp\!\!\!\perp \text{NonDesc}(V_i) \mid \text{Pa}(V_i)
因果马尔可夫条件说:给定 V_i 的父节点后,V_i 与其所有非后代节点条件独立。这是 DAG 与实际数据分布保持一致性的桥梁,也是许多因果发现算法从数据中检验 DAG 结构的理论根基。
  1. NonDesc(V_i) 是非后代集合非后代节点是图中不受 V_i 因果影响的变量,好比“下游水站的水位不会倒过来决定上游源头的水量”。
    NonDesc(Vi)\displaystyle \text{NonDesc}(V_i)
  2. Pa(V_i) 是充分的原因集合父节点集必须包含 V_i 的全部直接原因,一旦遗漏,独立性就会被暗藏的共同原因打破。
    Pa(Vi)\displaystyle \text{Pa}(V_i)
  3. 整体条件独立表达因果可分解性给定父节点后变量与外界隔绝,这正是 DAG 能拆解为多个局部概率模型的根本原因。
    Vi⊥ ⁣ ⁣ ⁣⊥NonDesc(Vi)∣Pa(Vi)\displaystyle V_i \perp\!\!\!\perp \text{NonDesc}(V_i) \mid \text{Pa}(V_i)

因果分析指导

图纸完成的第三天,市长终于等到答案:“如果西区总闸调高 1 米,东区居民的水压会变化多少?”阿泉没有仓促做实验,而是先看图纸,选择“哪些闸门要关、哪些仪表要盯、哪些读数必须分层”。这就是 DAG 对因果分析的实际指导——识别策略与调整集选择。

有了 DAG,因果效应的估计就不再是“把所有变量塞进回归”的蛮力操作,而是基于图结构的精准动作。最常见的识别策略是后门准则:在 X 与 Y 之间找到一组变量 Z,使得 Z 阻断所有从 X 出发的“背道”路径(非因果路径),同时不误调对撞因子。这样的 Z 就是最小充分调整集——控制在最少的变量,却能达到无偏的估计。

在此基础上,平均因果效应(ATE)可以通过调整公式估计:

阿泉把报告递给市长,胸有成竹。DAG 不只是学术图纸,它是一台决策透镜——透过它,观测数据终于说出了“如果”,而不仅仅是“因为相关”。

ATE=∑z(E[Y∣X=1,Z=z]−E[Y∣X=0,Z=z])P(Z=z)\displaystyle \text{ATE} = \sum_z \left( \mathbb{E}[Y \mid X=1, Z=z] - \mathbb{E}[Y \mid X=0, Z=z] \right) P(Z=z)
ATE 比较了“所有人接受处理”与“所有人不接受处理”两种虚构世界的平均结果差异。公式内部先在同一混淆层内做减法(层内干净对比),再按混淆因子分布加权合并。
  1. E[Y | X=1, Z=z] 是处理组的期望结果在混淆因子固定为 z 时,处理组(X=1)的结果均值,相当于阿泉只观察“开闸且降雨量相同”的日子。
    E[Y∣X=1,Z=z]\displaystyle \mathbb{E}[Y \mid X=1, Z=z]
  2. 层内差值消除组间差异处理组与对照组的期望之差,在同一个混淆层内计算,剔除了因混淆因子造成的系统性差别。
    E[Y∣X=1,Z=z]−E[Y∣X=0,Z=z]\displaystyle \mathbb{E}[Y \mid X=1, Z=z] - \mathbb{E}[Y \mid X=0, Z=z]
  3. 按 P(Z=z) 加权得到全局效应把每一层的处理效应按混淆因子的自然分布加权求和,得到总体层面的平均因果效应。
    ∑z(⋯ ) P(Z=z)\displaystyle \sum_z (\cdots) \, P(Z=z)

AI 应用场景

医疗流行病学中的因果 DAG 构建

阶段:研究设计(因果结构建模)

解决的问题:观察性数据中,吸烟与肺癌的关系会被年龄、环境污染等因素扭曲。传统做法把所有可测变量一股脑塞进回归模型,但若其中混入对撞因子(如“肺部炎症标志物”是吸烟与肺癌共同指向的结果),反而会引入新偏差。研究者先构建 DAG:年龄→吸烟、年龄→肺癌、环境污染→吸烟、环境污染→肺癌、吸烟→肺癌,再用后门准则挑选最小充分调整集,得到更可信的效应估计。

具体案例:某项大型队列研究起初把“体检发现肺部阴影”作为协变量纳入回归,得出吸烟对肺癌的 OR 值约 0.9(反向偏倚);重新构建 DAG 后发现该变量是对撞因子,将其移出调整集后 OR 修正为 2.4。DAG 的介入直接扭转了研究结论。

电商平台促销策略的因果评估

阶段:策略评估(因果效应估计)

解决的问题:大促期间销量飙升,究竟是促销的功劳,还是旺季本身在涨?价格、销量、季节三者高度相关,直接做回归会高估促销效果。数据团队构建 DAG:季节→促销、季节→销量、竞品活动→销量、促销→销量,识别出季节是混淆因子,通过后门调整剔除其影响,最终得到促销带来的净增量。

具体案例:某电商平台在对“双十一”促销进行复盘时,用 DAG 指导调整集选择,估计出促销的真实 GMV 提升为 12%(而非原始对比的 35%),避免了把旺季红利误算成业绩。随后该结论被用于下季度预算分配的决策依据。

教育评估中的干预效果分析

阶段:因果识别(处理效应估计)

解决的问题:报名网课的学生本身自律性更强,直接对比网课组与线下组成绩,会把“选择效应”混入“教学效应”。教育数据团队构建 DAG:自律性→选课、自律性→成绩、家庭辅导→成绩、网课→成绩,通过后门调整分离出自律性的影响,估计网课教学的净效应,指导课程产品迭代。

具体案例:某在线教育平台用 DAG 方法分析 10 万学员的学习数据,发现网课平台的净效应为成绩提升 0.3 个标准差,而其中心里动机因素贡献了表面效应的一半以上。据此平台调整了课程推荐策略,将资源导向真正能提升学习效果的内容模块。

Python 演示

python49 行
"""DAG 构建与 d-分离判据演示"""import networkx as nx  def build_dag():    """构建因果 DAG: Z(基因)是混淆因子, X(吸烟)->M(肺部中介)->Y(肺癌)"""    dag = nx.DiGraph()    dag.add_nodes_from(['X', 'Y', 'Z', 'M'])    dag.add_edges_from([('Z', 'X'), ('Z', 'Y'), ('X', 'M'), ('M', 'Y')])    return dag  def path_blocks(dag, path, observed):    """判断一条无向路径是否被 observed 中的节点阻断"""    for i in range(1, len(path) - 1):        node = path[i]        left, right = path[i - 1], path[i + 1]        if dag.has_edge(left, node) and dag.has_edge(right, node):            descendants = nx.descendants(dag, node) | {node}            if not (descendants & set(observed)):                return True        else:            if node in observed:                return True    return False  def d_separated(dag, x, y, observed):    """检查 x 与 y 在给定 observed 条件下是否 d-分离"""    undirected = dag.to_undirected()    for path in nx.all_simple_paths(undirected, x, y):        if not path_blocks(dag, path, observed):            return False    return True  if __name__ == "__main__":    dag = build_dag()    print("DAG 节点:", list(dag.nodes))    print("DAG 边:", list(dag.edges))    print("是否无环:", nx.is_directed_acyclic_graph(dag))     test_z = ["Z"]    print(f"d分离 X 与 Y | {test_z}? ->",          d_separated(dag, "X", "Y", test_z))     test_zm = ["Z", "M"]    print(f"d分离 X 与 Y | {test_zm}? ->",          d_separated(dag, "X", "Y", test_zm))
目的:演示如何用 networkx 构建一个带混淆因子的因果 DAG,并通过 d 分离判据判断给定条件下两个变量是否条件独立。
  1. dag.add_edges_from([('Z', 'X'), ('Z', 'Y'), ('X', 'M'), ('M', 'Y')])添加四条有向边,Z 是同时指向 X 与 Y 的混淆因子
  2. nx.is_directed_acyclic_graph(dag)校验 DAG 的无环性,若有环会返回 False
  3. undirected = dag.to_undirected()将 DAG 转成无向图,用于枚举 X 与 Y 之间所有路径
  4. nx.all_simple_paths(undirected, x, y)逐一枚举 X 与 Y 之间的每一条简单路径
  5. if dag.has_edge(left, node) and dag.has_edge(right, node):识别路径中“对撞结构”(两条边都指向 node)
  6. descendants = nx.descendants(dag, node) | {node}对撞节点的后代也继承“阻断”属性
  7. if not path_blocks(dag, path, observed):只要存在一条开放路径,x 与 y 就没有被 d 分离

常见误区

误区“我在数据里看到 A 和 B 高度相关,时间上也是 A 在前 B 在后,那在 DAG 里直接画 A→B 总没错吧?很多人就是这么画因果图的。”

正解相关不等于因果。A 和 B 高度相关,可能是因为存在一个未观测的混淆因子 Z 同时影响两者——就像降雨量同时抬高了东区和西区的水位,让它们“假装”有管道相连。DAG 中的箭头必须基于因果机制和领域知识,而不是相关系数。正确做法是先把假想中的 Z 显式画出来(Z→A、Z→B),再用数据验证,而不是直接画 A→B。

为何常见:因为观察性数据只能提供关联信号,而人的直觉天然倾向于把“统计显著”脑补成“因果证据”,忽略了背后看不见的共同原因。

误区“先把所有可能的边都画上,跑一遍回归,显著的就保留,不显著的就删掉,这样构建出的 DAG 不就是数据驱动的吗?”

正解DAG 是因果假设的编码,不是统计模型选择的结果。用数据决定边的去留,会导致数据窥探(data snooping),把噪声当作信号,更致命的是——回归的显著性根本无法识别因果方向。DAG 的构建应优先依赖领域先验知识,数据只能用于校验已有的假设(例如做条件独立检验),不能反过来“发明”边。

为何常见:因为自动化建模的流行让人默认“数据说了算”,忽略了因果结构本质上属于外部知识,而非数据分布本身。

误区“为了排除干扰,我把所有能测到的变量都当作混淆因子塞进回归模型里,变量越多结果越‘全面’,总比漏掉混淆因子强吧?”

正解这是最危险的直觉。对撞因子是箭头汇聚的节点,条件于对撞因子反而会打开虚假路径、引入新的偏差;中间变量被调整后则会阻断真实的因果传导。DAG 的价值正是帮你区分“该调”与“不该调”。应基于后门准则选择最小充分调整集,只调整真正的混淆因子,而不是把能测的全加入。

为何常见:因为“变量越多越稳健”的直觉在预测任务中常常成立,但在因果调整中恰好相反——调错变量比漏调变量更难察觉。

误区“DAG 建好之后,因果效应马上就出来了——把数据跑一遍模型,结果就是因果效应,DAG 就是万能钥匙。”

正解DAG 解决的是识别问题(应该调什么),但估计环节还面临大量现实约束:数据是否覆盖了调整集中的所有变量?各处理组在混淆因子分层内是否都有足够样本(正性假设)?是否存在测量误差和缺失数据?即便 DAG 完全正确,坏的估计方法或不完整的数据仍会让结果偏颇。DAG 之后,还需要配套的估计方法、诊断检验和敏感性分析。

为何常见:因为人们倾向于把图当作最终答案,而忽略了 DAG 只是“从研究问题到估计量”链条上的第一步,后面还有一长串需要小心处理的工程环节。

面试题

Q1. 在 DAG 中,“有向”指的是什么?

单选题 · easy

  • A.节点只能朝一个方向移动
  • B.每条边都有箭头指明因果方向← 正确答案
  • C.节点按时间顺序排列
  • D.变量只能有一种取值

答案:B。有向图的核心是每条边带方向箭头,在因果 DAG 中箭头明确表示因果效应方向。选项 A 混淆了节点的移动概念,节点是变量本身无所谓移动;C 中时间顺序虽是判断因果方向的证据,但并非“有向”的定义;D 则完全无关,变量可以有多种取值。

Q2. DAG 中的节点代表什么?

单选题 · easy

  • A.观察到的变量← 正确答案
  • B.统计指标公式
  • C.数据集的维度
  • D.算法的参数

答案:A。DAG 节点表示研究涉及的变量,可以是观测变量也可以是潜在变量。B 中统计指标公式是计算方法不是变量;C 中数据集维度描述的是张量形状,与变量角色无关;D 中算法参数属于机器学习概念,不属于因果图的构成元素。

Q3. DAG 中箭头方向表示什么?

单选题 · easy

  • A.数据流动方向
  • B.因果效应方向← 正确答案
  • C.时间先后顺序
  • D.样本量的多少

答案:B。因果 DAG 中箭头从原因指向结果,表示直接因果效应的方向。A 中数据流动是机器学习管道的说法,不是 DAG 语义;C 中时间先后可以作为确定方向的证据,但箭头本身刻画的是因果而非时间;D 与节点含义完全无关。

Q4. 什么是混淆因子(混杂因素)?

单选题 · mid

  • A.同时影响原因与结果的变量← 正确答案
  • B.只影响结果不受原因影响
  • C.在分析中需要被剔除的变量
  • D.完全独立于研究变量的变量

答案:A。混淆因子是同时指向处理变量 X 和结局变量 Y 的第三变量,它会打开一条非因果路径,使 X 与 Y 出现虚假关联,如同降雨同时抬高两个水站的水位。B 只是单侧影响的预测因子;C 混淆因子应被“控制”而非盲目“剔除”;D 独立变量不会制造虚假关联。

Q5. 对撞因子在 DAG 中的结构特点是?

单选题 · mid

  • A.箭头汇聚于该节点← 正确答案
  • B.箭头从该节点发出
  • C.没有箭头连接的节点
  • D.与所有节点都有边相连

答案:A。对撞因子(collider)是路径中至少有两条有向边箭头共同指向的节点,如 X→C←Y 中的 C。条件于对撞因子(或其后代)反而会开放路径、引入偏差。B 描述的是分叉结构中的“源头”节点;C 是孤立节点;D 不符合 DAG 通常的稀疏边结构。

Q6. 在 d-分离判据中,给定条件集 Z 后,何时称 X 与 Y 被阻断?

单选题 · mid

  • A.所有路径被 Z 阻断← 正确答案
  • B.至少一条路径开放
  • C.Z 包含了对撞因子
  • D.不存在任何中间节点

答案:A。d 分离要求 X 到 Y 的每一条路径都被 Z 阻断,此时 X 与 Y 在给定 Z 下条件独立,信息流像被水闸全部切断。B 只要存在一条开放路径就不满足 d 分离;C 条件于对撞因子反而可能开放路径;D 没有中间节点也可能存在直接边或分叉路径。

Q7. DAG 构建依赖的三个基本因果假设通常包括哪些?

多选题 · mid

  • A.充分性——包含所有共同原因← 正确答案
  • B.准确性——箭头方向与真实因果一致← 正确答案
  • C.可识别性——从数据中能识别因果效应← 正确答案
  • D.简洁性——变量数目尽量少

答案:ABC。DAG 三假设为充分性(所有共同原因进入图中)、准确性(箭头方向保真)、可识别性(目标效应能从观测数据中分离)。D 的“简洁性”不是标准假设——虽然简约有助于沟通,但 DAG 允许根据需要包含任意数量的变量,不以数目多寡论好坏。

Q8. 后门调整公式的核心目标是解决什么问题?

单选题 · hard

  • A.消除混淆变量带来的偏差← 正确答案
  • B.计算所有路径的总效应
  • C.验证 DAG 是否真正无环
  • D.替代随机对照试验的结果

答案:A。后门调整通过对混淆因子 Z 分层并加权求和,封堵从 X 出发的背道路径(如 X←Z→Y),还原 X 对 Y 的因果效应。B 中多条路径的总效应需要更复杂的分解技术;C 无环性通过拓扑排序验证,与调整公式无关;D 观测研究即使经调整也无法完全媲美随机对照试验。

Q9. 判断两个变量之间因果方向时,可依靠哪些证据?

多选题 · hard

  • A.时间先后顺序因果在前← 正确答案
  • B.干预实验改变原因观察结果← 正确答案
  • C.领域理论与机制提供支持← 正确答案
  • D.统计相关性大小排序

答案:ABC。因果方向的证据链包括时间先后(原因先于结果)、干预实验(操控原因后结果系统性变化)、机制理论(领域知识为因果路径提供物理解释)。D 中的统计相关大小只能反映关联强度,相关性是对称的,无法指出方向,不能作为画箭头的依据。

Q10. 关于混淆因子与对撞因子的处理,下列说法正确的是?

多选题 · extreme

  • A.混淆因子需纳入调整控制← 正确答案
  • B.条件于对撞因子引入偏倚← 正确答案
  • C.两者都应放在 DAG 外部
  • D.对撞因子可用作修正调整

答案:AB。混淆因子是 X 与 Y 的共同原因,应纳入后门调整加以控制(A 对);对撞因子是箭头汇聚点,条件于它会开放虚假路径、引入偏倚(B 对),因此绝不能随手将其放入调整集。C 错误,混淆因子和对撞因子都是 DAG 内部节点,必须显式建模;D 是对撞因子的经典误用。