距离矩阵:选对距离,分析就赢了一半

批次效应可视化的第一步,其实是算距离。你想想看,不管PCoA还是UMAP,底层都是拿距离做文章的。距离一旦选错,后面画出的图再漂亮,也只是自欺欺人。这个坑我再三强调:距离的选择直接决定分析的有效性。

今天我们就来拆开三种最常用的距离——欧氏距离、Bray-Curtis距离、Jaccard距离。我会结合自己做微生物组和单细胞数据的经验,告诉你什么场景下该用哪个。

欧氏距离:直觉好用,但常有陷阱

欧氏距离是我们最熟悉的。中学就学过,两点之间的直线距离。公式很简单:

d(x, y) = sqrt( sum( (xi - yi)^2 ) )

它适合什么?连续型数值,且每个维度的量纲相同的数据。比如基因表达量(TPM、FPKM),或者代谢物浓度。我在做早期基因表达聚类时,就一直用欧氏距离,结果也不错。

但有个巨坑:它对离群点和量纲差异非常敏感。举个例子,你有一列基因表达高达10000,另一列只有0~10,欧氏距离会被大数维度支配。我有个项目,微生物丰度数据用欧氏距离做PCoA,结果第一个主成分几乎全是丰度最高的那个属在驱动,其它差异完全被淹没了。那次之后我学乖了:数据必须先标准化,或者考虑别的距离。

避坑提醒:欧氏距离假设各维度独立且等权重。如果你的数据含有大量零(比如微生物物种表),欧氏距离效果会很差。我曾经用欧氏距离处理稀疏矩阵,得到的距离几乎全是零的平方和,区分度为零——白算。

Bray-Curtis距离:生态学与微生物组的标配

Bray-Curtis距离在生态学和微生物组领域几乎人手一个。它不是严格意义上的“距离”,因为它不满足三角不等式,但它的设计非常巧妙:

BC(x, y) = 1 - 2 * sum( min(xi, yi) ) / ( sum(xi) + sum(yi) )

说白了,它比较的是两个样本之间共有的数量。如果两个样本的物种构成完全一样,BC值为0;完全不一样,BC值为1。

它最大的优势是:忽略联合缺失的零。两个样本都缺某物种,不影响距离。这对于微生物组这种高度稀疏的数据太重要了。我做过一个跨批次宏基因组的项目,两个批次的零比例高达90%,用欧氏距离完全分不开,换成Bray-Curtis后批次效应立刻显现出来。

我的习惯:只要涉及物种丰度、OTU/ASV表、功能基因拷贝数,我第一反应就是Bray-Curtis。它结合PCoA做批次效应可视化,是我个人最顺手的组合。

还有一点要注意:Bray-Curtis要求输入数据是非负的(丰度、计数)。如果你已经做了log转换或中心化,那就不能用Bray-Curtis了,得回退到欧氏距离或其他。

Jaccard距离:纯看有无,不管多少

Jaccard距离是处理二元数据的利器。公式也很直观:

J(x, y) = 1 - ( |x ∩ y| / |x ∪ y| )

它只关心某物种有没有出现,不关心丰度高低。两个样本共有的物种数除以总物种数,再用1减一下。所以它的取值范围是0到1。

什么时候用Jaccard?我自己的判断标准很简单:

  • 数据是0/1形式(存在/不存在)
  • 丰度信息不可靠或你不想用它
  • 你想强调“哪个物种出现”而不是“出现多少”

比如我在分析病毒组数据时,很多病毒丰度极低,技术误差很大,用Bray-Curtis反而引入噪声。这时我果断切到Jaccard,只看有无,批次效应立刻明朗。还有一个场景是菌株水平的pan-genome分析,基因存在/缺失矩阵天然就是0/1,Jaccard距离是最好的。

我做的一个对比实验:用同一套微生物组数据,分别用Bray-Curtis和Jaccard做PCoA。Bray-Curtis能看出丰度差异驱动的批次效应,Jaccard则突出稀有物种的有无变化——两者互补。各自揭示了批次效应的不同侧面。所以选择不是唯一的,取决于你想暴露什么问题。

三种距离快速对照表

距离类型 输入数据 是否处理零值 典型应用 我对它的评价
欧氏距离 连续数值(需标准化) 零会被当作值参与计算 基因表达TPM/FPKM、代谢物浓度 直白但容易翻车
Bray-Curtis 非负计数/丰度 忽略联合缺失的零 微生物物种丰度、功能基因计数 生态学第一选择
Jaccard 二元(0/1) 只关心是否出现 基因存在/缺失、病毒组、宏基因组bin评估 简洁有力,不怕稀疏

选距离的通用流程

我自己在实际项目中会走这样一个决策链。把它画成流程图,每次做分析时对着看一遍:

距离选择流程 数据与问题 数据是连续数值还是二元? 二元 (0/1) Jaccard 距离 连续数值 非负计数? Bray-Curtis 距离 欧氏距离(需标准化) 计算距离 → 可视化 提示:若丰度数据已中心化/标准化,Bray-Curtis不再适用,回退欧氏距离或其它
一个小技巧:如果你不确定该选哪个,可以同时计算Bray-Curtis和Jaccard两种距离,然后分别做PCoA,看哪个能更清楚地把你的批次效应或生物学分组分开。我经常这么干,既快又保险。

实战中的选择陷阱与避坑

讲几个我踩过的坑,你遇到了就绕开:

  1. 数据有负值?Bray-Curtis和Jaccard都不接受负数。如果你做过中心化对数比变换(CLR),数据出现了负数,那就只能选欧氏距离(基于CLR的Aitchison距离本质就是欧氏距离,我后面章节会细讲)。
  2. 维度灾难:欧氏距离在高维空间表现很差,所有点之间的距离都会变得差不多。这时候Jaccard or Bray-Curtis反而稳定些,因为它们关注的是集合的交集,不受维度膨胀影响。
  3. 批次效应的方向:我曾遇到一批样本,丰度整体偏高(比如测序深度差异),Bray-Curtis会把这种“总量差异”也纳入距离,导致批次效应被夸大。这时改用Jaccard只看有无,反而能消除测序深度的影响。
再强调一次:没有绝对的“最佳距离”。同一次分析,我可能会因为探索不同的批次效应来源而切换距离类型。核心思路是:你想从批次效应中看到什么?是丰度变化,还是物种出现/缺失的变化?想清楚这个,选距离就不纠结了。

好,本章到此。三种距离的公式、适用场景和选择逻辑都在这里了。下一次你拿到一个多样本-多特征的矩阵,先别急着用默认距离,停下来想一想:这批数据的零是怎么分布的?我需要标准化吗?我想揭示哪种差异?这种思考习惯比代码本身更重要——我自己的项目经验,70%的坏图都出在距离选错上。