第4章:ComBat的假设条件——什么时候适用

ComBat不是万能的,这我一开始就踩过坑。

你拿一组数据,跑完ComBat一看,嗯,批次效应没了,但生物学差异也快没了。这时候你才意识到——它背后藏着几个硬性假设,数据不符合,结果就失真。

说白了,ComBat是一个线性位置-尺度模型。它假设批次效应是可加的,而且每个批次内的样本独立同分布。你以为它做的是神奇校正常数,其实它做的是均值平移和方差缩放。

4.1 核心假设一:每个批次内样本独立且同分布

这是最基础的一条。ComBat会假设同一批次内的样本,来自相同的分布——均值相同,方差相同。

但现实数据呢?很多时候batch内部本身就有异质性。比如一个测序批次里混了不同组织类型的样本,那分布必然不同。你强行用ComBat,它会强行把所有样本往一个均值上拉,结果就是——真正的高表达被压下去,低表达被抬起来。这不是校正,是扭曲。

我曾经遇到过一个单细胞数据,同一个batch里有tumor和normal两种细胞。跑了ComBat之后,原本显著的tumor marker全部消失。我检查了两个月,最后发现是假设一被直接打破。从那以后,我每次都会先分群检查batch内的分布是否够“同质”。

如何检查? 我常用的手段是看每个batch内样本的表达量密度图。如果同一个batch的密度曲线形状差异很大,那就不适合直接用ComBat。或者更简单——跑一个PCA,按batch染色,如果batch内样本在PC1上还分散得很开,那你就要警惕了。

4.2 核心假设二:批次效应是位置+尺度的可加模型

ComBat的模型是这样的:

Y_{ijg} = α_g + Xβ_g + γ_{ig} + δ_{ig} ε_{ijg}

这里的 \(\gamma\) 是位置参数(均值偏移),\(\delta\) 是尺度参数(方差缩放)。

这个模型假设批次效应只影响均值和方差的线性部分。如果你碰到的是非线性批次效应——比如批次A的低表达基因普遍被压了一个比例因子,而高表达基因不受影响——那ComBat就无能为力了。

个人习惯:在跑ComBat前,我会先用Levene检验或者Flipper-Killeen检验看不同批次的方差是否齐性。如果方差差异不是简单的比例缩放关系,那我会考虑先用log2变换拉回尺度再跑ComBat。

4.3 核心假设三:批次和生物学条件正交

这才是ComBat使用中最容易被忽略的陷阱。

ComBat回归时会做一个设计矩阵,把批次和生物学变量分开拟合。但如果你设计了两个batch分别对应不同的实验条件——比如batch1全是control,batch2全是treatment——那批次和生物学效应就完全混淆了。

这时候ComBat会怎么做?它会把treatment效应的一部分当作批次效应给“校正”掉。你的差异分析结果直接废掉。

情形 批次与条件 ComBat有效性 建议
理想 每个批次包含多个条件 ✔ 有效 直接使用
部分重叠 某个批次缺失某个条件 ⚠ 可能有效 谨慎使用,检查残差
完全混淆 batch1只有条件A,batch2只有条件B ✘ 无效 不要用ComBat,改用其他方法

这个表是我自己总结的。你如果项目数据里batch和condition完全一一对应,那我就直接告诉你——别跑了,跑完也是错的。

4.4 核心假设四:基因数量足够大(大样本渐近)

ComBat的贝叶斯框架里,它要用所有基因的方差信息去“借用强度”,来估计每个基因的\(\delta\)参数。如果基因数量太少(比如<100个),这张借的牌就不够打。

为什么会这样? 因为每批次内的方差估计需要足够多的数据点来做贝叶斯收缩——基因少了,收缩没有意义,方差估计反而会恶化。

你想想看:如果你的数据只有50个基因,那ComBat的稳定性会很差。我建议至少500个基因以上再用ComBat。如果是蛋白质组学数据,只有200个蛋白,那我会选择limma的 removeBatchEffect 代替ComBat。

4.5 核心假设五:设计矩阵满秩(可逆)

这是一个数学细节,但很致命。ComBat在拟合\(\gamma_{ig}\)和\(\delta_{ig}\)的时候要计算最小二乘解,如果设计矩阵奇异(秩亏),那正则方程就解不出来。程序会报错,或者更糟——悄悄给你一个错误结果。

我建议跑ComBat前,先做一个诊断:

# 假设你有batch和condition两个变量的设计矩阵
design_matrix <- model.matrix(~ batch + condition)
qr(design_matrix)$rank == ncol(design_matrix)

如果结果是 FALSE,那就说明有问题。你要么合并某些level,要么删除冗余列。

4.6 一张图看懂ComBat的假设生态

ComBat 假设体系 ComBat 校正 样本独立同分布 (i.i.d. within batch) 位置-尺度可加模型 (linear location–scale) 批次与条件正交 (no full confounding) 基因数量足够大 (≥500 基因) 设计矩阵满秩 (可逆 / 无多重共线) 假设违背的后果 • i.i.d. 被打破 → 批次内存在异质性子群 → 过度校正 • 模型不可加 → 非线性批次效应无法消除 → 残差仍含批次 • 完全混淆 → 生物学差异被当作批次去掉 → 假阴性 • 基因太少 / 秩亏 → 估计不稳定或直接报错

4.7 实战检查清单

每当我拿到一个新数据集,我通常按下面几步检查:

  1. 分布检查:每个batch内样本的箱线图和密度曲线是否一致。
  2. 方差齐性检验:Levene检验判断batch间方差是否成比例。
  3. 混淆检查:做一张批次×条件的列联表,确认没有完全混淆。
  4. 基因数量检查:确认基因数 > 500;若 < 500,考虑不跑贝叶斯版本。
  5. 共线性诊断:用QR分解检查设计矩阵的秩是否等于列数。

避坑指南:我曾经接手过一个同事的半成品,他的数据只有200个基因,batch和condition完全一一对应,还强行跑了ComBat。结果差异分析P值全部被抹平。我后面花了三天重写分析流程,改用limma批次作为随机效应才挽救回来。你记住这句话:数据不满足假设,ComBat就是一把劣质的刀,切什么都没准头。

4.8 什么时候可以放心用ComBat?

简单总结一下:

  • 数据批次内同质,生物学结构清晰
  • 批次效应主要是均值偏移+方差缩放
  • 每个批次都包含多个生物学条件(正交)
  • 基因数量充裕(千级或万级)
  • 设计矩阵没有冗余参数

满足这五点,你就可以放心用ComBat了。有一条不满足,我建议你先想办法解决——比如合并批次、增加基因、重新设计实验——再跑校正。