1. MOFA简介
多组学因子分析(Multi-Omics Factor Analysis,MOFA)是你做多组学整合时绕不开的一个方法。说白了,它能把转录组、蛋白质组、甲基化组这些不同模态的数据,投影到一组共享的低维因子上。
我最初接触MOFA是在一个肿瘤异质性项目里。当时手上有RNA-seq、DNA甲基化芯片和蛋白质组质谱三套数据,特征维度加起来快两万,却只有几十个样本。传统方法要么硬拼特征,要么分别降维再拼接,结果总是顾此失彼。后来换上MOFA,一次建模就把三组数据里的共同变异和模态特异变异分开了。
为什么需要多组学因子分析?
你想想看,单组学分析已经能看到一些生物信号了,但疾病机制往往跨多个分子层面。转录调控、表观修饰、蛋白丰度之间的交互,单靠一个组学很难串起来。
我见过不少团队用“拼接法”——把每个组学的差异基因/蛋白列表取交集,然后画个Venn图就完事了。嗯,这样会丢掉大量信息。MOFA的做法更优雅:它假设不同组学里存在共享的潜在因子,这些因子驱动了样本间的变异。
- 数据异构性:不同组学数据类型不同(连续值、计数、beta值),MOFA统一用概率模型处理。
- 缺失值:很多样本不会测全所有组学,MOFA天然支持部分缺失,不用丢掉样本。
- 可解释性:每个因子对应一组特征权重,你能直接看出哪些基因/蛋白/甲基化位点贡献最大。
MOFA核心原理
MOFA本质上是一种贝叶斯因子分解方法。它把每个组学的数据矩阵 Xm(n×pm)分解为:
Xm = Z WmT + εm
其中 Z 是共享因子矩阵(n×k),Wm 是第 m 个组学的权重矩阵(pm×k),εm 是噪声。模型通过自动相关性确定(ARD)自动选择因子数 k,你基本不需要手动调参。
为什么会这样?贝叶斯框架里每个因子有一个超参数 αk,如果某个因子在数据里解释力弱,它的 αk 会趋向无穷大,权重被压到接近零,因子就被“关掉”了。
主要应用场景
| 场景 | 描述 | 典型因子解释 |
|---|---|---|
| 疾病亚型发现 | 整合RNA+蛋白+甲基化识别亚型 | 因子1解释临床表型,因子2解释免疫浸润 |
| 药物响应预测 | 多组学特征投影到响应相关因子 | 因子权重高的基因可作为生物学标志物 |
| 跨模态数据融合 | 同一批样本的不同组学数据对齐 | 共享因子作为样本的低维嵌入 |
| 缺失值填充指导 | 利用其他组学辅助填充缺测组学 | 因子分解隐式完成矩阵补全 |
我个人觉得最有意思的是药物响应场景。以前做耐药分析,单看转录组总找不到稳定标志物。后来把同一批细胞系的RNA-seq、CRISPR screens和蛋白质组一起进MOFA,因子2上的高权重基因正好是已知耐药通路(比如EGFR-STAT3),而因子1全是细胞周期相关。这就清楚了:耐药其实是两群细胞在同时作用。
实际跑起来长什么样?
下面是一个最简单的Python调用示例(用MOFA2包):
import mofa2
import pandas as pd
# 三个组学的数据矩阵,行名统一为样本ID
rna = pd.read_csv("rna_log2.csv", index_col=0)
prot = pd.read_csv("prot_log2.csv", index_col=0)
meth = pd.read_csv("meth_beta.csv", index_col=0)
# 构建输入
data = {
"RNA": rna,
"protein": prot,
"methylation": meth
}
# 训练模型
model = mofa2.run_mofa(
data,
n_factors=10, # 最大因子数,ARD会自动剪枝
likelihoods=["gaussian", "gaussian", "beta"],
outfile="model.hdf5"
)
# 查看因子
factors = model.get_factors() # 样本 × 因子
weights = model.get_weights("RNA") # 基因 × 因子
variance = model.get_variance_explained()
嗯,这里要注意:likelihood参数要和数据类型匹配。如果甲基化是beta值但用了gaussian,模型会偏向保守;我个人习惯先用beta分布试一下,再对比结果。
variance_explained的总和,如果低于30%说明模型没学到多少信号,可能是数据噪声太大或者样本量太小。我一般会先把单组学PCA跑一遍,确保每个组学至少有一个主成分能解释>5%变异,再进MOFA。
什么时候不该用MOFA?
- 样本数小于50且组学数超过5:因子数估计极易过拟合。
- 各组学之间完全独立(生物学不相关):共享因子会拆成很多小因子,不好解释。
- 你的目的是做预测而不是解释:MOFA更擅长描述变异结构,分类/回归精度不一定比XGBoost高。
我最近处理一个代谢组+微生物组整合项目时就犯了第二个错误——两组数据在动物实验中确实不相关,结果MOFA跑出7个因子,每个只解释3%-5%变异,完全没法用。后来改成分别降维再做关联分析,反而更清楚。