全世界只有三个零件
这是本书最省力的一章:不管一张因果图上有几百个变量、几千条箭头,它都只由三种三节点的小结构拼成。学会这三个,你就学会了看图。
下面三种结构里,A 和 C 之间在不做任何控制的情况下,哪些会呈现出相关?
提示:B 和 D 描述的是同一件事,区别只在于你有没有把第三种也考虑进去。
三个零件
任取因果图上的一条路径,看它中间的任意一个节点,那里只可能是三种情形之一——因为两条边相对这个节点只有「进」和「出」两种朝向,两条边一共四种组合,其中两种(进出、出进)是同一回事:
# 零件一:链(chain / mediator) A → B → C B 是【中介】:A 通过 B 影响 C # 零件二:叉(fork / confounder) A ← B → C B 是【混淆】:B 同时影响 A 和 C # 零件三:撞(collider) A → B ← C B 是【对撞机】:A 和 C 共同影响 B
就这三个。没有第四个。
现在关键的问题:A 和 C 之间会不会有相关?条件化 B(也就是「控制住 B」)之后又会怎样?
按一下那个按钮,三张图会同时变。数字是这样的(两万个样本,每台机器的结构系数都是 1):
零件 不控制 B 时 r(A,C) 控制 B 后的偏相关 ──────── ────────────────── ────────────────── 链 +0.585 +0.010 ← 断了 叉 +0.503 −0.008 ← 断了 撞 −0.004 −0.501 ← 通了!
前两行完全符合直觉:控制中间那个,路就断了。这正是第 2 章「控制混淆」在做的事。
第三行是反过来的。本来断着的,一控制就通了。
| 零件 | 不控制 B | 控制 B |
|---|---|---|
A → B → C 链 | 通 | 断 |
A ← B → C 叉 | 通 | 断 |
A → B ← C 撞 | 断 | 通 |
「通」的意思是:A 和 C 之间会呈现相关(哪怕它们之间没有因果)。「断」的意思是:这条路径贡献不了任何关联。
对撞机那一格还有一条附加规则:控制对撞机的任何一个后代,效果和控制它本身一样——路一样会通。这条附加规则是很多现实中翻车的原因,第 11 章会看到一个。
为什么对撞机是反的
直觉解释在第 4 章已经出现过了,那道门就是一个对撞机。这里换个更小的例子。
假设 B = A + C,A 和 C 是两个独立的随机数。知道 B 之前,A 的取值对 C 一点信息都没有。
现在我告诉你 B = 10。这时候如果你又知道 A = 8,你立刻就知道 C = 2。A 和 C 之间产生了完美的负相关——因为它们的和被钉住了。
A、C 独立同分布,方差都是 1,B = A + C。给定 B 之后 A 和 C 的协方差:
Cov(A, C | B) = Cov(A, C) − Cov(A,B)·Cov(C,B) / Var(B)
= 0 − (1 × 1) / 2
= −0.5
相关系数 = −0.5 / √(0.5 × 0.5) = −1.0 ... 在无噪声的极端情形
本书的 demo 里 B 还带一份自己的噪声(B := A + C + 噪声,三者方差都是 1),所以负相关没有那么极端:偏相关是 −0.501,与解析值 −1/√(2×2) = −0.5 吻合。
这里有一个哲学上很好玩的点:信息可以「往回流」。A 不能影响 C,但知道了 B 之后,A 的取值确实告诉了你关于 C 的事。因果只往下游走,信息两头都走。
《意外》那本书里的说法是同一件事:观察到 B 之后,A 和 C 之间产生了互信息。因果的方向和信息的方向不是一回事——这是两本书能拼在一起的一个接口。
把三个零件拼起来
现在你可以读任何一张图了。方法是逐条路径地走:
# 一条路径 X ← A → M → Y # 拆成两个零件看: X ← A → M 叉,中间是 A A → M → Y 链,中间是 M # 这条路径「通」,当且仅当它上面【每一个】中间节点都是通的。 # 只要有一个节点是断的,整条路径就断了 —— 像串联电路。
一条路径是通的(在给定条件集 Z 下称为「活跃」),当且仅当:
- 路径上每一个非对撞机节点,都不在 Z 里;并且
- 路径上每一个对撞机节点,它自己或它的某个后代在 Z 里。
只要有一个节点不满足,整条路径就断了。串联,一处断则全断。
而两个变量之间可能有很多条路径。它们之间有没有相关,取决于是否还剩至少一条通的路径——这是并联。
串联加并联。整套逻辑就这么多。下一章先把对撞机单独拎出来讲透,第 8 章再把这套逻辑变成一个算法。
用这三个零件去读你见过的说法,非常顺手:
- 「早餐吃得好的孩子成绩好」——大概率是叉:家庭条件同时影响两者。
- 「代码 review 严格的团队线上事故少」——可能是链(review 真的减少了 bug),也可能是叉(工程文化好的团队两件事都做得好)。这两种结构对「我们也开始严格 review」这个决定给出完全不同的预测。
- 「我认识的所有会写 Rust 的人都很难相处」——大概率是撞:你的社交圈是一道门。
第三条不是玩笑。「在我认识的人里」几乎总是一个对撞机——因为「认识」这件事同时被双方的很多特质影响。凡是以「我见过的 X 都……」开头的句子,先怀疑对撞机。
上面第三行就是证据:−0.004 → −0.501。生成 A 和 C 的代码里没有任何联系,是「控制」这个动作把它们绑在了一起。
这意味着「多控制几个变量总归更保险」是一条危险的经验。它在只有混淆的世界里成立,在有对撞机的世界里会毁掉你的结论——而你事先并不知道自己在哪个世界。
D第一、二种会,第三种不会。
数字上:链 +0.585,叉 +0.503,撞 −0.004。前两个通,第三个断。
(B 和 D 说的是同一件事,都算对。挑 B 的话,你可能只是没把第三种放在心上——而这本书接下来一直在提醒你放在心上。)
A 「只有链会」——漏掉了叉。而叉恰恰是第 2、3 章那两章的全部内容:混淆制造相关,是这门学问最先要处理的事。 C 「三种都会」——把对撞机也算进来了。对撞机在不控制的时候是断的,这一点非常重要:它意味着你什么都不做的时候,对撞机不会害你。害你的是你伸手去控制它。这一章的一句话
因果图只有三个零件;链和叉控制了就断,对撞机控制了才通——这一个例外是全书最贵的一句话。
下一章把对撞机单独摆上台。你会亲手把两个独立变量之间的相关,从 −0.004 拧到 −0.501,而且是三种不同的拧法:只看一部分人、把它放进回归、以及最隐蔽的那种——连它的后代都不能碰。