单细胞整合Harmony¶
一句话概述:Harmony和scVI是单细胞多样本整合(去批次效应)的两大主流方法,Harmony快速且校准好,scVI适合复杂整合任务,两者都在Seurat v5中有原生支持。
核心知识点速览¶
| 概念 | 白话解释 |
|---|---|
| 批次效应 | 不同实验批次/平台/时间产生的技术差异,不是真正的生物差异 |
| 数据整合 | 消除批次效应,让来自不同批次的相同细胞类型聚在一起 |
| Harmony | 基于PCA的迭代软聚类方法,快速且保守 |
| scVI | 基于变分自编码器(VAE)的深度学习方法 |
| CCA | Seurat的典型相关分析整合方法(v3引入) |
| RPCA | Reciprocal PCA,Seurat的快速整合方法 |
| 过度校正 | 批次效应去太多了,把真正的生物差异也抹掉了 |
| LISI分数 | 评估整合效果的指标(iLISI评估混合程度,cLISI评估保留) |
| Benchmark | 基准测试,比较不同整合方法的效果 |
一、为什么需要整合?¶
假设你从3个医院收集了PBMC样本做单细胞测序:
不整合的问题:
医院A的T细胞 ——和—— 医院B的T细胞
虽然是同一种细胞,但在UMAP上可能分成两堆
原因:不同的试剂批次、操作人员、测序平台等
整合的目的:
把技术差异"抹掉",让相同细胞类型聚在一起
同时保留真正的生物差异(如疾病vs正常)
关键挑战:
去太少 → 批次效应仍在
去太多 → 生物差异也被消除了(过度校正)
二、Harmony整合¶
2.1 原理¶
Harmony的策略(迭代软聚类):
1. 先在PCA空间中做软聚类
2. 计算每个cluster中不同批次的比例
3. 如果某batch在某cluster中占比异常 → 调整该batch细胞的坐标
4. 重复步骤1-3直到收敛
5. 输出校正后的低维嵌入(harmony坐标)
特点:只校正低维嵌入,不修改原始表达矩阵
优点:快速、保守、校准好(不太会过度校正)
2.2 Harmony实操¶
# 安装Harmony
install.packages("harmony") # 安装
library(harmony) # 加载
library(Seurat) # 加载Seurat
# 假设已有合并的多样本Seurat对象
# seurat_obj包含多个样本的数据,meta.data中有"batch"列
# 标准预处理
seurat_obj <- NormalizeData(seurat_obj) # 归一化
seurat_obj <- FindVariableFeatures(seurat_obj) # 找高变基因
seurat_obj <- ScaleData(seurat_obj) # 缩放
seurat_obj <- RunPCA(seurat_obj, npcs = 30) # PCA
# ===== 运行Harmony =====
seurat_obj <- RunHarmony(
seurat_obj,
group.by.vars = "batch", # 批次变量名
reduction = "pca", # 基于PCA结果
dims.use = 1:30, # 使用的PC数
max.iter.harmony = 20 # 最大迭代次数
)
# Harmony结果存储在reduction中
Reductions(seurat_obj) # 查看可用的降维:"pca", "harmony"
# 用Harmony嵌入做后续分析(不用PCA)
seurat_obj <- FindNeighbors(seurat_obj,
reduction = "harmony", # 用harmony而非pca
dims = 1:30)
seurat_obj <- FindClusters(seurat_obj, resolution = 0.5)
seurat_obj <- RunUMAP(seurat_obj,
reduction = "harmony", # 基于harmony
dims = 1:30)
# 可视化:按批次着色(应该混合良好)
DimPlot(seurat_obj, group.by = "batch") # 看批次是否混合
DimPlot(seurat_obj, group.by = "cell_type") # 看细胞类型是否保留
2.3 Seurat v5中的Harmony整合¶
# Seurat v5简化了整合接口
# 先按样本分层
seurat_obj[["RNA"]] <- split(seurat_obj[["RNA"]],
f = seurat_obj$batch)
# 标准预处理
seurat_obj <- NormalizeData(seurat_obj)
seurat_obj <- FindVariableFeatures(seurat_obj)
seurat_obj <- ScaleData(seurat_obj)
seurat_obj <- RunPCA(seurat_obj)
# 一行搞定Harmony整合
seurat_obj <- IntegrateLayers(
seurat_obj,
method = HarmonyIntegration, # 使用Harmony方法
orig.reduction = "pca", # 基于PCA
new.reduction = "harmony" # 输出到"harmony"
)
# 合并层
seurat_obj <- JoinLayers(seurat_obj)
# 后续聚类和UMAP用harmony
seurat_obj <- FindNeighbors(seurat_obj, reduction = "harmony", dims = 1:30)
seurat_obj <- FindClusters(seurat_obj, resolution = 0.5)
seurat_obj <- RunUMAP(seurat_obj, reduction = "harmony", dims = 1:30)
三、scVI整合¶
3.1 原理¶
scVI(single-cell Variational Inference):
1. 训练一个变分自编码器(VAE,深度学习模型)
2. 编码器把每个细胞的表达向量压缩成低维潜在变量
3. 在训练过程中,批次信息作为条件变量输入
4. 模型学会"什么是批次差异,什么是生物差异"
5. 输出的潜在空间就是去批次后的嵌入
特点:修改/重建表达矩阵(可以输出校正后的表达值)
优点:适合复杂整合任务、跨物种、多模态
缺点:需要GPU加速、参数较多、有时会过度校正
3.2 scVI实操¶
# scVI在Python中运行(通过scvi-tools)
# pip install scvi-tools
import scvi
import scanpy as sc
# 读取数据(AnnData格式)
adata = sc.read_h5ad("merged_data.h5ad")
# 设置scVI模型
scvi.model.SCVI.setup_anndata(
adata,
layer="counts", # 使用原始计数
batch_key="batch" # 批次变量
)
# 训练模型
model = scvi.model.SCVI(adata, n_latent=30) # 潜在维度30
model.train(max_epochs=400) # 训练400轮
# 获取潜在表示(去批次后的嵌入)
adata.obsm["X_scVI"] = model.get_latent_representation()
# 用scVI嵌入做聚类和UMAP
sc.pp.neighbors(adata, use_rep="X_scVI")
sc.tl.umap(adata)
sc.tl.leiden(adata, resolution=0.5)
# 可视化
sc.pl.umap(adata, color=["batch", "cell_type"])
3.3 在R中调用scVI¶
# 通过reticulate在R中调用scVI
library(reticulate)
library(Seurat)
library(SeuratDisk)
# 导出Seurat对象为h5ad
SaveH5Seurat(seurat_obj, filename = "data.h5seurat")
Convert("data.h5seurat", dest = "h5ad")
# 在Python中运行scVI(见上面的Python代码)
# 然后导入结果
# 或使用SeuratDisk导入scVI嵌入
adata <- ReadH5AD("scvi_result.h5ad")
scvi_embed <- adata@obsm$X_scVI
# 添加到Seurat对象
seurat_obj[["scvi"]] <- CreateDimReducObject(
embeddings = scvi_embed,
key = "scVI_",
assay = "RNA"
)
四、整合方法比较与选择¶
| 方法 | 速度 | 适用场景 | 过度校正风险 |
|---|---|---|---|
| Harmony | 最快 | 简单/中等批次效应 | 低(推荐首选) |
| scVI | 较慢 | 复杂/跨物种整合 | 中等 |
| Seurat CCA | 中等 | 适量数据,效果稳定 | 中等 |
| Seurat RPCA | 较快 | 大数据集 | 低 |
| fastMNN | 快 | 轻度批次效应 | 低 |
| scANVI | 较慢 | 有参考标签的半监督 | 低 |
选择建议¶
1. 首先试Harmony(快速、保守、校准好)
2. 如果Harmony效果不好 → 试Seurat CCA
3. 如果涉及跨物种或很复杂的整合 → 用scVI
4. 如果有参考注释想迁移学习 → 用scANVI
5. 多方法比较取交集 → 最稳健的结果
五、评估整合效果¶
# 方法1:目视检查
p1 <- DimPlot(seurat_obj, group.by = "batch") + ggtitle("By Batch")
p2 <- DimPlot(seurat_obj, group.by = "cell_type") + ggtitle("By Cell Type")
p1 | p2 # 并排显示
# 好的整合:batch颜色混合良好,cell_type颜色分离清晰
# 方法2:LISI分数(定量评估)
# install.packages("lisi")
library(lisi)
harmony_embed <- Embeddings(seurat_obj, "harmony")
meta <- seurat_obj@meta.data
lisi_scores <- compute_lisi(
harmony_embed,
meta,
c("batch", "cell_type") # 评估的变量
)
# iLISI(batch): 越高越好(批次混合程度)
# cLISI(cell_type): 越低越好(细胞类型保留程度)
常见报错与解决¶
| 报错信息 | 原因 | 解决方案 |
|---|---|---|
Harmony: convergence not reached | 迭代次数不够 | 增加max.iter.harmony |
group.by.vars not found | 列名不在meta.data中 | 检查meta.data列名 |
IntegrateLayers: no layers | 数据没有分层 | 先用split()分层 |
scVI: CUDA out of memory | GPU显存不够 | 减少batch_size或用CPU |
Over-correction suspected | 不同细胞类型混在一起 | 降低整合强度或换方法 |
速查表¶
# Harmony快速流程
NormalizeData() → FindVariableFeatures() → ScaleData()
→ RunPCA() → RunHarmony(group.by.vars="batch")
→ FindNeighbors(reduction="harmony")
→ FindClusters() → RunUMAP(reduction="harmony")
# Seurat v5整合流程
split() → NormalizeData() → FindVariableFeatures()
→ ScaleData() → RunPCA()
→ IntegrateLayers(method=HarmonyIntegration)
→ JoinLayers() → FindNeighbors() → FindClusters() → RunUMAP()
# 整合方法选择
简单批次: Harmony(首选)
中等复杂: Seurat CCA/RPCA
复杂/跨物种: scVI
有参考标签: scANVI
# 评估指标
iLISI: 批次混合程度(越高越好)
cLISI: 细胞类型保留(越低越好)
kBET: 批次混合统计检验
ASW: 平均轮廓系数
面试高频问题¶
Q1:什么是批次效应?为什么需要整合?¶
答:批次效应是由实验技术因素(不同时间、平台、操作人员、试剂批次)导致的系统性差异,不代表真正的生物学差异。如果不校正,同一种T细胞可能因为来自不同批次而在UMAP上分成两群。整合的目的是消除技术差异,让相同细胞类型不论来自哪个批次都聚在一起,同时保留真正的生物差异(如疾病vs健康)。
Q2:Harmony的原理是什么?¶
答:Harmony在PCA空间中工作,通过迭代软聚类校正批次效应。每轮迭代中:①对所有细胞做K-means软聚类;②计算每个cluster中各批次的比例;③如果某批次在某cluster中过多/过少,调整该批次细胞的PCA坐标使其更均匀分布;④重复直到收敛。关键优势是只修改低维嵌入不改原始数据,速度快且校准好——2024年基准测试显示Harmony是唯一可以安全推荐使用的批次校正方法。
Q3:如何判断整合是否过度校正?¶
答:过度校正的表现:①已知不同的细胞类型在UMAP上混在一起;②不同生物条件(如疾病vs健康)的差异被消除;③已知的稀有细胞群消失了。检测方法:①目视检查——按细胞类型着色看是否保持分离;②cLISI分数——如果细胞类型的LISI增高说明类型混淆了;③标记基因检查——看每个cluster是否仍有清晰的标记基因表达。
Q4:Harmony和scVI的区别是什么?怎么选?¶
答:Harmony是基于PCA的线性方法,只校正低维嵌入,快速且保守。scVI是基于深度学习(VAE)的非线性方法,可以重建表达矩阵。选择建议:简单/中等批次效应用Harmony(快、稳、不过度校正);复杂整合(跨平台、跨物种、大量批次)用scVI(能力更强但要注意过度校正)。2025年Federated Harmony还扩展支持了保护隐私的联邦学习场景。
Q5:整合后还能做差异分析吗?¶
答:可以但要注意方法选择。整合只校正了低维嵌入(Harmony)或潜在空间(scVI),用于聚类和可视化。做差异分析应该用原始的、未校正的表达值,同时在统计模型中把批次作为协变量或用伪批量方法。如果用校正后的表达值做差异分析,可能引入统计偏差。Seurat的FindMarkers默认使用原始数据,这是正确的做法。