4. 常用批次校正方法介绍:ComBat、Harmonization 等
说到批次校正,我最早接触的是基因表达芯片数据,当时不同批次间的差异大到能让你怀疑人生。你以为找到的生物标志物,其实只是批次效应。后来做 ADMET 预测,同样的化合物换个实验室测,结果直接漂移一个数量级。嗯,批次校正不是「锦上添花」,是「不做就完蛋」。
这一章咱们就聊聊几个主流的批次校正方法。我自己的项目经验里,ComBat 和 Harmonization 是出场率最高的两位主角,它们背后原理不一样,调参重点也不同。你会看到有人直接跑默认参数就信了结果——我劝你别这么干。
4.1 ComBat:贝叶斯框架下的老兵
ComBat(Combining Batches)最初是生信圈为了整合基因芯片数据搞出来的,后来被我们做 ADMET 的顺手拿来用。它的核心思路是:对每个特征(比如 logD, 清除率),建立线性模型,将批次均值和方差分别做贝叶斯调整。
公式我就不全列了,你记住两个关键参数就好:
- prior.plugs(或 Python 版的
prior_std等):控制先验强度。值越大,校正后批次之间越「平滑」,但可能抹掉真实生物学信号。我调过一个清除率预测项目,把prior.plugs从 0.5 改到 2,RMSE 直接降了 8%——但小心,那也可能是在过校正。 - 非参数模式(nonparametric):当批次内样本数太少(比如少于 5),参数估计会崩。这时候走非参数版本会更稳。
下面是一个我在 R 中常用的 Combat 调用,配合一点调参建议:
library(sva)
# edata: 特征矩阵 (特征 x 样本)
# batch: 批次标签向量
# mod: 协变量矩阵 (如年龄、性别,ADMET中常放化合物结构指纹PC1等)
adjusted <- ComBat(
dat = edata,
batch = batch,
mod = mod,
par.prior = TRUE, # TRUE用参数先验,FALSE用非参数
prior.plots = FALSE, # 先验图,调试时可以打开看看
mean.only = FALSE # TRUE只校正均值,方差不变
)
mean.only = TRUE 先试一版。
4.2 Harmonization(NeuroCombat):线性混合模型路线
Harmonization 家族(像 NeuroCombat)本质上是 ComBat 的变体,但引入了线性混合模型(LMM),对协变量的处理更灵活。举个例子,当你需要保留 dataset 间的协变量效应(比如两种不同的 ADMET 测定平台)时,Harmonization 能显式建模随机截距和随机斜率。
我个人在跨平台代谢稳定性数据校正时试过 NeuroCombat 的 Python 实现,对比原版 ComBat,它的优势体现在:
- 对样本量极不平衡的批次(比如 A 批次 1000 个,B 批次 3 个)更鲁棒。
- 可以处理连续型协变量(比如实验日期,温度)与非线性的批次关系。
调用方式(Python 版 neurocombat):
from neurocombat import combat as neurocombat
# data: 样本 x 特征的 numpy 数组
# batch: 批次列表
# mod: 包含协变量的矩阵,第一列通常为截距
adjusted = neurocombat(
data = data.T, # neurocombat 要求特征 x 样本
batch = batch_vector,
mod = covariate_matrix,
eb = True, # Empirical Bayes 开关
parametric = True # 参数先验
).T # 转回样本 x 特征
eb = True 在小样本下先验估计失真。改成 eb = False(等同于固定效应)才正常。所以,小批次数据(总样本 < 30)我建议先关掉 Empirical Bayes。
4.3 其他常用方法一览
除了 ComBat 和 Harmonization,你还会在实际项目中遇到:
| 方法 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| limma(线性模型+经验贝叶斯) | 微阵列或小样本 ADMET | 实现简单,统计检验成熟 | 不能显式校正方差,只做均值校正 |
| PCA/ICA 去批次 | 可视化、降维后分析 | 直观,不需要批次标签 | 可能混入生物学变异,谨慎使用 |
| Per-batch Z-score | 快速审核,粗筛 | 零参数,几行代码搞定 | 只调整均值和方差,无法保留批次间结构差异 |
| MNN(互近邻) | 单细胞或多模态数据 | 处理复杂批次结构 | 对 ADMET 多批次整合计算量大 |
说实话,Per-batch Z-score 是我在临时检查时最常用的——用一行 (x - mean(x)) / sd(x) 就够了。但它只能作为基线,正式建模时我几乎不用。
4.4 方法选择的核心逻辑图
为了帮你快速决策,我画了一张流程框架图。你可以直接对照自己的数据情况走一遍:
4.5 避坑指南:我翻过的车
- 把验证集也一起校正了:这是最经典的错。记得先在训练集上拟合成份(先验参数),然后用同一组参数转换验证集。我见过有人直接对整个数据集做 ComBat,然后做交叉验证——结果指标虚高得像假药。
- 忽略协变量中的实验设计:比如你研究的是肝微粒体 vs 肝细胞,两种基质本身就有差异。如果在 mod 里不放这个因子,ComBat 会把生物学差异也当批次去掉。你想想看,最后模型对真实基质差异的预测能力就没了。
- 对离散值过分校正:ADMET 数据里的异常值(比如清除率为 0.001),校正后可能被拉回正常范围。但你得先确认那个值是不是测量错误。我自己的做法是先做 Winsorize 再跑校正,不行再去看原始记录。
4.6 小结
ComBat 和 Harmonization 是目前批次校正的黄金搭档。ComBat 适合 3 个以上且样本量相对均衡的批次,Harmonization 在处理高度不平衡或含有复杂协变量时更灵活。别忘了,方法选得再好,不验证就是白做。我个人习惯是:校正完成后,立即画 PCA 散点图 + 计算每个特征的批次内 RSD 中位数。如果 RSD 中位数比校正前下降了 30% 以上,才算初步通过。