4、单细胞数据整合方法分类:基于锚点(CCA)、基于贝叶斯(scVI)、基于匹配(MNN)等

做单细胞数据分析的朋友都知道,批次效应是个绕不开的坎。不同批次、不同平台、甚至不同实验室的数据放在一起,技术差异往往比生物学差异还大。怎么把这些数据整合到一起?目前主流的方法大致能分成三类:基于锚点、基于贝叶斯和基于匹配。

我个人习惯先把方法分类理清楚,再去选工具。这样遇到实际问题时,心里才有底。这三种方法背后各有各的数学假设,适用场景也不太一样。下面我挨个拆开来讲。

1. 基于锚点的方法——CCA 与 Seurat

这类方法的代表是 Seurat 的整合流程。核心思想是通过典型相关分析(CCA)把不同数据集投影到一个共享的低维空间,然后在这个空间里识别"锚点"——也就是跨数据集配对的细胞。

说白了,CCA 就是在找两个数据集的线性组合,让它们投影后的相关性最大。我最初接触这个概念时,总觉得它跟 PCA 有点像。其实区别在于:PCA 是找一个数据集内部方差最大的方向,而 CCA 是找两个数据集之间相关性最大的方向。这个差异很关键。

Seurat 的标准流程大致是这样的:

# Seurat CCA整合流程
library(Seurat)

# 创建对象列表
obj_list <- list(sample1, sample2, sample3)

# 标准化和找高变基因
obj_list <- lapply(obj_list, function(x) {
    x <- NormalizeData(x)
    x <- FindVariableFeatures(x, selection.method = "vst")
    return(x)
})

# 寻找锚点
anchors <- FindIntegrationAnchors(object.list = obj_list, 
                                  dims = 1:30)

# 整合数据
integrated <- IntegrateData(anchorset = anchors, dims = 1:30)

我在项目中用过很多次这套流程。说实话,对于细胞类型差异明显的数据集,它表现很好,速度快,结果也稳定。但我发现它对数据量特别大的情况——比如几十万个细胞——内存消耗会飙升。有一次我处理 8 个样本、共 30 万细胞的数据,16GB 内存根本跑不动,最后不得不抽稀样本才跑完。

优点:计算效率高,流程成熟,文档丰富。
缺点:线性方法,对非线性批次效应处理有限;锚点质量直接影响整合效果。

2. 基于贝叶斯的方法——scVI

scVI 走的是另一条路——深度生成模型。它用变分自编码器(VAE)来学习数据的潜在表示,并把批次信息作为条件变量输入模型。你想想看,这本质上是在做一个假设:每个细胞的表达谱是由一个低维的潜在变量(代表生物学状态)和一个已知的批次变量共同决定的。模型通过优化变分下界来学习这个映射关系。

之前处理一个包含 10 种组织、5 个批次的数据集时,我用了 scVI。它在捕捉复杂非线性关系方面确实有优势,尤其是不同组织之间的差异很大时,scVI 的整合效果比 CCA 要好不少。

# scVI 整合示例 (Python)
import scvi
import anndata

# 加载数据
adata = anndata.read("combined_data.h5ad")

# 设置批次信息
adata.obs["batch"] = adata.obs["sample_id"]

# 初始化模型
scvi.model.SCVI.setup_anndata(adata, batch_key="batch")
model = scvi.model.SCVI(adata)

# 训练
model.train()

# 获取校正后的潜在表示
latent_representation = model.get_latent_representation()

不过 scVI 也有让人头疼的地方。训练时间比较长,而且超参数调起来有点玄学。我曾经为调一组参数,在 GPU 上跑了整整两天……最后还是没比默认参数好多少。所以我的建议是:先用默认参数跑一轮,看看结果再决定要不要调。

优点:处理非线性关系强,可扩展性好,能应对复杂批次结构。
缺点:训练耗时,超参数多,解释性不如传统方法。

3. 基于匹配的方法——MNN

MNN(Mutual Nearest Neighbors)是 2018 年由 Haghverdi 等人提出的。它的思路很直观:在低维空间中,找到跨批次的相互最近邻对。这些 MNN 对被认为代表了生物学上最相似的细胞,然后基于这些对计算批次校正向量。

我特别喜欢 MNN 的一个特点:它不需要假设两个数据集之间有全局的对应关系。说白了,它只关心局部匹配。这对于部分细胞类型在不同批次中分布不均衡的情况特别有用。

业界有段时间特别迷信 MNN,因为它做校正时很"温柔",不会过度扭曲数据。但后来我在实践中发现,MNN 对低维空间的选择比较敏感,降维的质量直接影响匹配效果。

# MNN 整合示例 (Python, mnnpy)
import mnnpy

# 两个批次的数据
batch1 = np.array(...)  # shape: (n_cells_1, n_genes)
batch2 = np.array(...)  # shape: (n_cells_2, n_genes)

# 运行MNN校正
corrected = mnnpy.mnn_correct(
    batch1, batch2,
    k=20,            # 近邻数
    sigma=0.1,       # 带宽参数
    cosnorm=True     # 使用余弦归一化
)
# corrected[0] 是校正后的批次1
# corrected[1] 是校正后的批次2
优点:无需全局对应假设,校正温和,生物学解释性强。
缺点:对降维质量敏感,计算量大,近邻数 k 需要调参。

4. 三种方法对比与选型

下面这张表我把三个方法的核心维度放在一起对比,方便你快速做技术选型:

维度 基于锚点 (CCA) 基于贝叶斯 (scVI) 基于匹配 (MNN)
核心原理 典型相关分析 变分自编码器 相互最近邻
线性 / 非线性 线性 非线性 线性(在低维空间)
计算成本 低 高 中
内存需求 中 高 中
处理复杂批次 一般 强 较好
可解释性 强 弱 强
代表工具 Seurat scVI, scANVI MNN, FastMNN

我个人选型经验:如果数据集细胞类型差异明显、批次效应不太复杂,用 Seurat 的 CCA 整合就够用了。如果数据结构很复杂、批次多且非线性效应明显,scVI 更合适。如果你特别关心局部匹配质量、不希望过度校正,MNN 是个好选择。

避坑指南:我曾经踩过一个坑——用 CCA 整合两个差异很大的数据集(一个 PBMC,一个组织样本),结果锚点识别得不好,整合后反而引入了伪影。后来先用 MNN 做了一轮预对齐,再用 CCA 整合,效果好多了。注意,千万不要把不同方法的结果直接平均或混合使用。每种方法的假设空间不同,混合使用可能导致不可预测的结果。建议根据数据特点选择一种方法,或者在充分验证的基础上分阶段使用。

三种方法的核心逻辑讲清楚了。下面我用一张图把它们的分类体系总结一下:

单细胞数据整合方法分类体系 单细胞数据整合方法 基于锚点 (CCA) CCA降维 锚点识别 ← 上一章 📖 返回目录 下一章 →