ComBat 的数学原理:位置尺度调整模型与经验贝叶斯估计

嗯,这一章是很多人觉得“劝退”的地方——数学原理。但我想说,你真不用怕它。我在早年做多中心转录组整合时,一开始也是硬着头皮调包,结果换了个数据集就崩了。后来才明白,不懂原理,你调参就是瞎蒙。

位置尺度调整模型:说白了就是“对齐均值、拉齐方差”

ComBat 的核心思想,其实很直观。每个批次都有自己的“风格”——有的批次整体表达量偏高,有的批次数据波动特别大。我们要做的就是:把每个批次的数据,拉到同一个“基准”上。

数学上,对于基因 \( g \) 在样本 \( j \)(属于批次 \( i \))中的表达值 \( Y_{ijg} \),ComBat 假设:

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

这里:

  • α_g:基因 \( g \) 的全局基线表达。可以理解为所有批次统一后的“理想水平”。
  • Xβ_g:生物学协变量的影响(比如疾病组 vs 对照组)。这部分要保留,不能校掉。
  • γ_{ig}:批次 \( i \) 的加法偏移——这是“位置参数”。说白了,就是批次导致整体上移或下移了多少。
  • δ_{ig}:批次 \( i \) 的缩放因子——这是“尺度参数”。数据太散或太紧,就靠它拉齐。
  • ε_{ijg}:随机误差,假设服从 \( N(0, σ_g^2) \)。

那么校正后的表达值就是:

Y*_{ijg} = (Y_{ijg} - α_g - Xβ_g - γ_{ig}) / δ_{ig} + α_g + Xβ_g

你看,减掉批次效应,再除以批次标准差,然后加回全局基线和生物学效应。简单说:去批次、保生物学。

实战要点:我在项目中遇到过一个问题——如果某个批次样本量特别小(比如只有 2 个样本),位置参数 γ 很容易被极端值带偏。这时候可以考虑用后面讲的经验贝叶斯来“收缩”它,不要只用简单平均。

经验贝叶斯估计:用数据本身来“借力”

位置尺度模型看起来简单,但问题在于:每个基因在每批次里都有独立的 γ 和 δ,参数太多了!如果批次少还好,批次一多(比如 10 个批次,2 万个基因),那就是 40 万个参数要估。直接估计会严重过拟合。

这时经验贝叶斯就派上用场了。它假设每个基因的批次参数不是孤立的,而是来自一个共同的“先验分布”。我用个不严谨但好懂的说法:

  • 先看所有基因的 γ 和 δ 在批次内的分布,得到一个“整体印象”。
  • 对于单个基因,如果它的 γ 离全体均值很远(可能是噪声),就把它往均值方向“拉”一点——这叫收缩。
  • 如果它的 γ 很稳定,就保留原始估计。

具体步骤分为两步:

  1. 先验估计:对每个基因 \( g \),用批次内数据粗糙地估计 \( \hat{γ}_{ig} \) 和 \( \hat{δ}_{ig}^2 \)。然后假设这些估计值服从某种分布(例如 γ 为正态分布,δ² 为逆伽马分布),通过矩估计或极大似然得到先验的超参数。
  2. 后验估计:对每个基因 \( g \),结合先验和当前基因的数据,计算后验均值和后验方差,作为最终的 γ 和 δ 估计。这里可以用迭代法(EM 算法)或直接公式。

个人习惯:我通常用 ComBat 时,默认用非参数先验(non-parametric),它对分布假设更宽松,鲁棒性更好。只有在样本量非常充足(每批次 > 30)时才考虑参数先验。

整体流程与关键参数

我把整个流程浓缩成一张图,你一看就明白ComBat是怎么把“数据输入”变成“校正输出”的:

ComBat 批次校正流程 原始表达矩阵 估计每基因每批次的 γ、δ 经验贝叶斯:先验→后验收缩 应用校正公式计算 Y* 校正后表达矩阵 先验分布从所有基因的批次参数中“借力”,防止小样本过拟合

注意:我曾经在 TCGA 数据上跑 ComBat,忘记把临床协变量放入 X 矩阵,结果把肿瘤 vs 正常的差异全部校掉了。后来检查发现,校正后的数据两组之间完全没差异…… 所以请务必确认你的生物学变量在模型中。

核心参数速查

参数 含义 典型取值
prior.plots 是否绘制先验密度图(诊断用) FALSE(不画,或 TRUE 调试)
par.prior 是否使用参数先验 FALSE(推荐非参数,更稳健)
mean.only 是否只校均值(不校方差) FALSE(一般要同时校)

调参小经验:如果你数据里某些批次方差差异特别大,可以试试把 mean.only=FALSE 但把非参数先验的迭代次数调高到 5 次(默认 3)。我试过,效果改善挺明显。

好了,数学原理就到这。你只需要记住两件事:位置尺度模型是“对齐+缩放”,经验贝叶斯是“借力防过拟合”。下次你在代码里看到 ComBat(dat, batch),心里就知道它在背后干了什么。