跳转至

单细胞整合Harmony

一句话概述:Harmony和scVI是单细胞多样本整合(去批次效应)的两大主流方法,Harmony快速且校准好,scVI适合复杂整合任务,两者都在Seurat v5中有原生支持。

核心知识点速览

概念白话解释
批次效应不同实验批次/平台/时间产生的技术差异,不是真正的生物差异
数据整合消除批次效应,让来自不同批次的相同细胞类型聚在一起
Harmony基于PCA的迭代软聚类方法,快速且保守
scVI基于变分自编码器(VAE)的深度学习方法
CCASeurat的典型相关分析整合方法(v3引入)
RPCAReciprocal 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 memoryGPU显存不够减少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默认使用原始数据,这是正确的做法。