贝叶斯框架、位置与尺度参数调整、经验贝叶斯估计
很多朋友一上来就调 ComBat 函数,把 mod、batch 一堆参数填好,跑完拿到校正数据就觉得万事大吉。说实话,我当年也干过这事儿。结果有一次在 RNA-seq 数据上,样本量特别小,批次又特别乱,校正后的数据反而出现了奇怪的负值,后来才意识到:**不懂原理,出坑都不知道怎么爬**。
所以这一章,咱不急着写代码,先把这个校正的“脑子里那根弦”捋清楚。你只要能理解三个核心概念——贝叶斯框架、位置与尺度参数、经验贝叶斯——后面所有实战都会豁然开朗。
2.1 贝叶斯框架:让数据“互相借力”
ComBat 的核心思路,说白了就是:
**同一个基因在不同批次里,应该服从相似的分布,只是均值和方差被批次“扭曲”了。**
那怎么估计这些扭曲呢?传统方法就是每个批次单独算均值和方差——但遇到样本少的批次,估计就特别不准,甚至离谱。
这时候贝叶斯就把所有批次“拉在一起”看。它假设每个批次的调整参数(位置和尺度)都来自一个共同的分布——**先验分布**。然后拿每个批次自己的数据去“修正”这个先验,得到**后验分布**。
一句话: 贝叶斯让样本多的批次“帮”样本少的批次估计参数,同时防止过度平滑。
我记得有一次做代谢组学,一共5个批次,其中一个批次只有2个样本,传统方法算出的均值直接飞了。用ComBat的贝叶斯框架后,那个批次的参数被其他批次“拉”回了合理范围。这就是先验的力量。
2.2 位置与尺度参数调整
校正是两个动作的组合:
- 位置参数(location):矫正批次间的均值漂移。直观理解就是“加或减一个常数”。
- 尺度参数(scale):矫正批次间的方差差异。相当于乘一个缩放因子。
你想想看,如果两个批次均值差2个log2,但方差一模一样,那只需要平移;如果方差也不一样,就得先缩放再平移。ComBat就是把这两个参数分开估计。
| 参数类型 | 对应统计量 | 校正作用 | 举例(假设) |
|---|---|---|---|
| 位置参数 γ | 批次均值漂移 | 平移整个批次的表达水平 | 第2批基因A比第1批平均高2 → 减去2 |
| 尺度参数 δ² | 批次方差缩放 | 压缩或拉伸分布宽度 | 第3批变异度是参考批次的1.5倍 → 除以1.5 |
避坑提醒:我曾经在单细胞数据上遇到过一个坑——某个批次方差特别小(接近零),直接除尺度因子会导致数值爆炸。ComBat的经验贝叶斯会通过后验收缩把这个因子“拉”回来,避免除以零风险。
2.3 经验贝叶斯估计:参数从数据中来
说到“贝叶斯”,你可能觉得要用非得事先知道一个先验分布?其实不用。
经验贝叶斯的操作方式很巧妙:它先用所有批次的数据,估计出先验分布的参数(比如超参数:先验均值、先验方差),然后再跑常规的贝叶斯更新。
说白了就是:先拿数据本身“拟合”出一个先验,再用这个先验去约束每个批次的估计。这就是“经验”二字的意思——先验不是拍脑门定的,而是从数据中学来的。
ComBat 里具体的数学过程大致是这样(以位置参数 γ 为例):
假设:γ_batch ~ N(μ_γ, σ_γ²) # 先验:所有批次的位置参数服从同一个正态分布
然后:数据给出似然:X_batch | γ_batch ~ N(γ_batch, σ²_within)
后验:γ_batch | X_batch ~ N( (μ_γ/σ_γ² + 样本均值/σ²_within) / (1/σ_γ² + n/σ²_within) , ... )
注意这里的 μ_γ 和 σ_γ² 并不是固定死的——经验贝叶斯会从观测数据中估计它们(通常用矩估计或EM算法)。
参数数量很少时要注意:经验贝叶斯的“经验”依赖整个数据集。如果批次总数过少(比如只有2-3个),那么先验超参数估计本身就不稳定,校正效果可能打折扣。这时候我建议先尝试非参数版本 ComBat(..., par.prior=FALSE)。
我用 R 的 sva::ComBat 跑过很多项目,默认用的就是参数化先验(par.prior=TRUE)。但有一次在看 Alzheimer 的芯片数据时,遇到一个批次只有1个样本——那个批次全靠别的批次“撑”着。经验贝叶斯虽然能缓解,但校正效果肯定不如多样本批次好。**这提醒我们:数据质量永远比方法更重要。**
2.4 小结:从一个公式看“经验”的价值
你可能注意到了,后验均值的公式本质上是一个**加权平均**:
后验均值 = (先验均值权重 + 数据均值权重) / (总权重)
当批次样本数 n 很小时,数据均值权重小,估计更偏向**先验均值**(即其他批次的平均水平)。当 n 很大时,数据权重占主导,估计几乎等于本批次均值。这个自动调节的能力,正是ComBat稳健性的根源。
嗯,这一章的原理就这些。理解了这个框架,后面实战中调参、解读结果都会特别顺。千万别把ComBat当黑盒——你知道了它“在干啥”,就能判断它“干得对不对”。