常见批次效应校正方法分类:参数、非参数与深度学习

做批次效应校正好几年了,我翻过不少车。
刚入行时总以为套一个 ComBat 就万事大吉,后来发现数据分布一复杂,效果就崩。
说白了,方法选型才是真正的门槛。

目前主流方法能分成三大阵营:参数方法、非参数方法、深度学习方法。
区别在于对数据分布做了多少假设,以及能不能处理非线性模式。

参数方法:快,但有前提

参数方法假定数据服从某个已知分布(比如正态分布)。
最经典的当属 ComBat,它假设每个特征的均值和方差都能通过线性变换对齐。

我的习惯:单组学、小批次(5个以下)时,我优先用 ComBat。速度快,解释性强。

举个例子,一个标准的 ComBat 调用在 R 里长这样:

library(sva)
adjusted <- ComBat(dat = expression_matrix, batch = batch_vector, mod = NULL, par.prior = TRUE)

参数方法的核心优势是统计框架成熟,结果可重复。
但代价也明显:如果实际分布偏了,校正反而引入假信号。

避坑:我曾经在一个蛋白质组学项目里直接用 ComBat,没检查特征分布。结果 30% 的蛋白校正后差异方向都反了。后来加了正态检验才定位到问题。

非参数方法:灵活,但吃样本量

非参数方法不假定分布形态,靠秩次或核密度估计对齐批次。
典型代表是 Harmony(基于模糊聚类)和 limma 的 removeBatchEffect。

Harmony 在单细胞领域用得特别多,因为它能处理非线性漂移:

import harmony
harmony_out = harmony.Harmony(
    X_scaled, meta_data, vars_use=['batch']
)
corrected = harmony_out.fit_transform()

非参数方法的好处是鲁棒,不怕分布错配。
但需要足够样本量来估计密度——少于 20 个样本容易过拟合。

我记得有一次做多中心临床数据整合,每个批次只有 12 个样本。Harmony 跑完,检验集上的方差反倒扩大了。降到参数方法后反而稳了。

深度学习方法:上限高,下限也低

深度学习用神经网络隐式学习批次间的映射关系。常见的有 Autoencoder + 对抗训练、VAE 解耦、CycleGAN 等。

一个简单的对抗去偏框架大致长这样:

# 伪代码示意
encoder = Encoder(input_dim, latent_dim)
classifier = BatchClassifier(latent_dim, n_batches)
reconstructor = Decoder(latent_dim, input_dim)

for batch, data in dataloader:
    z = encoder(data)
    loss_rec = MSE(data, reconstructor(z))
    loss_adv = CrossEntropy(classifier(z), batch_label)
    # 梯度反转:让 encoder 骗过分类器
    total_loss = loss_rec - lambda_adv * loss_adv

深度学习的优势是能捕捉高度非线性的批次效应,尤其在多模态数据上效果惊人。
但代价也大:训练不稳定,数据量要求高,调参成本大。

我曾经翻过的车:用 CycleGAN 做两个平台转录组校正,跑了三天。结果发现生成器学会了把低表达基因全抹零——因为那是区分批次最“容易”的方式。后来加了表达先验损失才解决。

三大方法对比(一张表说清楚)

维度 参数方法 非参数方法 深度学习方法
分布假设 强(如正态) 弱(秩/核) 无(端到端学习)
样本量需求 低(>5/批) 中(>20/批) 高(>200/批)
非线性处理 差 中等 强
可解释性 高 中 低(黑盒)
计算资源 低(秒级) 中(分钟级) 高(GPU 小时)
典型代表 ComBat, limma Harmony, MNN scVI, VAE + 对抗

你想想看,选方法其实是在效率、灵活性和可解释性之间做权衡。
我个人的经验是:
先跑参数方法做基线,如果效果不好再切非参数;深度学习放最后,只有前两者都失败或者数据量很大时才上。

本类知识图谱

批次效应校正方法分类 校正方法 参数方法 ComBat (正态假设) limma removeBatch 非参数方法 Harmony (模糊聚类) MNN (最近邻) 深度学习方法 VAE + 对抗 CycleGAN 选型原则 样本量大、复杂非线性 → 深度学习 样本适中、分布稳定 → 参数/非参数

我的几点避坑总结

  • 参数方法做个分布检验(Shapiro–Wilk)再上,别闭眼跑。
  • 非参数方法至少 5 个批次、每批 20+ 样本再来,否则波动大。
  • 深度学习方法准备一份简单独立测试集,防止模型“偷懒”。
  • 不管你选哪个,留一部分数据不校正做验证——这是底线。
嗯,最后说一句:我做了这么多年,发现没有万能方法。最好的策略是:先小规模跑几种方法,挑一个在验证集上指标最稳的放生产环境。