第一次认真看系统发育树的时候——一堆分叉的线条,像冬天窗户上的霜花。然后有人指着它说:这代表亲缘关系。接着就很自然地推出一句更狠的话:你的数据不独立。
(我当时的反应大概是:我怎么就不独立了?我每个物种都只记录了一行数据啊。很独立,很孤独,甚至。)
但这句话——“不独立”——其实是整套 phylogenetic comparative methods(系统发育比较方法)的门把手。你要进去,得先承认门在那儿。
今天我想把这件事说得朴素一点:树不是装饰,它在记账;而相关性这东西,会从历史里长出来。
树在用什么货币记账
系统发育树最核心的两件东西:
- 拓扑(topology):谁和谁更近,分叉顺序是什么
- 分支长度(branch length):每条边"有多长"
拓扑像族谱:你是我表弟还是堂弟,这种事不关心你长多高。
分支长度像时间或变化量:这才开始关心"隔了多久"“变了多少”。
问题是:分支长度到底是什么?
常见两种含义:
- 按时间计:单位可能是百万年(Myr)。这类树往往是 ultrametric(所有叶子到根的距离相同),因为"都活到今天"。
- 按替换数计:单位更像"每位点多少替换"。这类树不一定 ultrametric。
我更愿意把这件事叫做:树在用两种货币记账。你拿时间树去算替换、拿替换树去当时间,都会"余额不对"。
后面做 PGLS(Phylogenetic Generalized Least Squares,系统发育广义最小二乘)的时候,这个"货币单位"会悄悄进入协方差矩阵里,影响你认为"相关性该有多强"。所以它不是细节,是地基。
根、外群,以及方向感
没有根的树(unrooted tree)只告诉你"相对关系",不告诉你"谁先谁后"。
有根的树(rooted tree)才有方向:从祖先走到后代。
现实里我们常用外群(outgroup)来定根:找一个确定在研究对象之外的物种(或类群),把根放在它和其他物种之间。
这里的直觉是:根不是为了更好看,是为了让时间的箭头出现。
而一旦时间出现,很多事情就不再是统计上的巧合,而是历史造成的相似。
别站队,先说实话
这两者的矛盾,很多时候不是理论问题,是现实问题:你手里有什么,就用什么,然后你就会担心自己是不是在骗人。
- 基因树(gene tree):用某个基因或某段序列推出来的树
- 物种树(species tree):物种分化历史的更理想描述(通常需要多基因、多信息整合)
它们不一致很常见:不完全谱系排序(ILS,Incomplete Lineage Sorting)、基因流、水平转移……这些词你以后会越来越熟,熟到有点麻木。
我先给一个"写作上的诚实原则"(也算一种自我保护):
你用什么树都可以,但你必须写清楚你用的是什么树,以及你为什么这么做。
PGLS 对"树代表相关结构"非常认真。你用错树,它不会骂你,它只会很安静地给你一个看起来很像真的 p 值。
(这就是我最怕的那种错:它不痛,只是悄悄偏离。)
走过同一条路而已
在普通线性回归(OLS,Ordinary Least Squares,普通最小二乘法)里,你经常默认:每个样本的误差互不相关。
翻译成人话:你这个物种的"偏差",不应该能预测另一个物种的"偏差"。
但如果两个物种共享很长一段进化历史,它们的性状(或者更准确地说:性状里那些你没解释掉的部分)就可能一起漂。
你可以把它想成:
- 两个人从同一个起点出发走路
- 走到某个路口才分开
- 分开之前,他们走过的路完全一样
你说他们最后的位置会不会更像?会的。
不是因为他们商量过,是因为他们共同经历过。
这就是系统发育相关性最朴素的来源:共享祖先的时间越长,性状越相关(在某些模型假设下,比如 Brownian motion,我们下一篇会讲)。
所以"非独立"不是一句道德指控,它只是你对世界的一种承认:历史会留下惯性。
先偷看一眼 PGLS 在修什么
先不讲公式,只讲一句话:
- OLS(普通最小二乘法)假设误差协方差矩阵是
I(单位矩阵,对角的,互不相关) - PGLS(系统发育广义最小二乘)允许误差协方差是一个由树导出的
Σ(协方差矩阵)
你可以把 PGLS 理解成:在你承认"亲缘导致相关"之后,回归也得跟着换一种更诚实的听法。
(我说"更诚实",不是说 OLS 不诚实。OLS 只是天真。天真在统计里不是罪,但你得知道它天真在哪里。)
系统发育树最麻烦的地方,不是它长得复杂,而是它逼你承认一件很不方便的事:
你研究的对象不是随机抽出来的豆子。它们有家谱。
一旦有家谱,“样本独立"这件事就不再是默认前提,而变成一个需要解释、需要辩护的假设。PGLS 之所以存在,并不是要给你加难度,它只是把"历史"请回了统计模型里——哪怕只请回来一点点。
下一篇我会从一个最小的性状演化模型(Brownian motion)讲起:为什么在这个假设下,协方差矩阵会长成那样;以及 Pagel’s λ 这种看起来很神秘的东西,到底是在调什么。
附录 A:R 示例
library(ape)
library(phytools)
set.seed(1)
tree <- rtree(n = 25)
x <- fastBM(tree)
plot(tree, cex = 0.7)
tiplabels(round(x, 2), frame = "none", adj = c(1.1, 0.5), cex = 0.6)
Sigma <- vcv(tree)
R <- cov2cor(Sigma)
hist(R[upper.tri(R)], breaks = 20,
main = "Pairwise correlations implied by the tree",
xlab = "correlation")
附录 B:树的数学与相关矩阵
下面是一份硬核补充。如果你只是想用 PGLS,这些可以先跳过;但如果你曾经好奇"树到底在算什么”,这里有一些可以摸到的地方。
树作为图论对象
从数学上讲,一棵树是这样一个东西:
$$T = (V, E)$$其中 $V$ 是节点集合(包括内部节点和叶子),$E$ 是边集合。每条边 $e \in E$ 有一个权重,通常就是分支长度。
几个衍生概念:
- 邻接矩阵 $A$:$A_{ij} = 1$ 如果节点 $i$ 和 $j$ 直接相连,否则为 0
- 距离矩阵 $D$:$D_{ij}$ 是节点 $i$ 和 $j$ 之间沿树的最短路径长度(所有边权重之和)
- 最近共同祖先(MRCA):两个叶子 $i, j$ 的 MRCA 是树中同时是两者祖先、且路径最短的那个节点
这三个矩阵的关系大概是:$A$ 告诉你"谁和谁紧挨着",$D$ 告诉你"谁和谁隔了多远"。
有根树 vs 无根树
无根树(unrooted tree)只定义拓扑和距离,不定义时间方向。
有根树(rooted tree)额外指定一个根节点 $root$,从而引入"从根到叶子"的路径长度:
$$d(root, leaf_i)$$这个方向一旦出现,很多统计性质就跟着出现——包括 ultrametric。
Ultrametric 条件
如果一棵有根树满足:
$$d(root, leaf_i) = d(root, leaf_j) \quad \text{对所有 } i, j$$它就是一棵 ultrametric 树。这等价于说:从根到所有叶子的距离都相等。
这个条件在生物学里的意义是:所有物种都"演化到现在",所以它们共享的时间长度是一样的。
你大概已经猜到了:时间树经常就是 ultrametric 树。
相比之下,用替换数做分支长度的树通常不满足 ultrametric 条件——因为不同分支的替换率可以不同。
分支长度的两种记账单位
| 类型 | 分支长度含义 | 典型用途 | Ultrametric? |
|---|---|---|---|
| 时间树 | 百万年(Myr) | 物种分化时间推断 | 通常满足 |
| 替换树 | 期望替换数/位点 | 序列比对建树 | 通常不满足 |
这两种单位会进入 $\Sigma$ 的计算:时间树给出"共享演化时间",替换树给出"共享变化量"。它们的量纲不同,但最后都会变成协方差矩阵里的数字。
(我当年在这里卡了很久。现在回头看,这种卡壳其实很值——因为它强迫你去想"我到底在测量什么"。)
$\Sigma$ 矩阵的显式含义
在 Brownian motion 假设下,树的协方差矩阵 $\Sigma$ 是这样构造的:
$$\Sigma_{ij} = \text{从根到 } i \text{ 和 } j \text{ 的最近共同祖先的路径长度}$$也就是说:两个物种的协方差,等于它们共享的那段历史的长度(或者长度的某种线性函数)。
这直接意味着:
- 对角线 $\Sigma_{ii}$ = 从根到物种 $i$ 的总长度
- 非对角线 $\Sigma_{ij}$ = 共享祖先之后的那段长度
在 R 里,vcv(tree) 做的就是这件事——它把树的结构翻译成一个你可以直接用的数字矩阵。
相关矩阵:为什么 cov2cor(Sigma) 有用
协方差矩阵 $\Sigma$ 的量纲是分支长度的平方(时间平方,或者替换数的平方)。这在比较不同物种或不同树的时候不太方便。
相关矩阵 $R$ 通过标准化消掉了这个量纲:
$$R_{ij} = \frac{\Sigma_{ij}}{\sqrt{\Sigma_{ii} \cdot \Sigma_{jj}}}$$cov2cor() 函数做的就是这件事:它把"协方差"变成"相关系数"。
从直观上:$R_{ij}$ 告诉你,在控制了两个物种各自的总演化时间之后,它们之间的相关性是多少。$R_{ij} = 1$ 意味着完全共享历史(它们在根节点就分开了,也就是整个演化历史都是共享的——但这在真实树里基本不会出现);$R_{ij} = 0$ 意味着没有共享历史(最近共同祖先就是根)。
3 物种树的 $\Sigma$ 计算
假设一棵有根树:
root
/ \
A B---C
设分支长度:root→A = 1,root→B = 1,B→C = 0.5。
按 Brownian motion 模型:
$$\Sigma = \begin{pmatrix} \sigma^2 \cdot 1 & \sigma^2 \cdot 0 & \sigma^2 \cdot 0 \\ \sigma^2 \cdot 0 & \sigma^2 \cdot 1.5 & \sigma^2 \cdot 1 \\ \sigma^2 \cdot 0 & \sigma^2 \cdot 1 & \sigma^2 \cdot 2 \end{pmatrix}$$其中约定顺序为 (A, B, C)。
- $\Sigma_{AA} = 1$:A 到根的距离
- $\Sigma_{BB} = 1.5$:B 到根的距离 = root→B + B→C(但这里 C 是 B 的后代)
- $\Sigma_{CC} = 2$:C 到根的距离 = root→B + B→C
- $\Sigma_{AB} = 0$:A 和 B 的最近共同祖先就是 root,所以共享路径长度为 0
- $\Sigma_{BC} = 1$:B 和 C 的最近共同祖先是 B,所以共享路径长度为 root→B = 1
(这是手动算的。但其实只要一行 R 代码就能验证:vcv(tree)。)