2. DIABLO理论基础
为什么CCA不够用?
传统CCA说白了就是找两组数据投影后相关性最大的方向。思路很直接——但一碰到高维数据就露怯了。
你想想看,基因表达数据动不动上万维,样本才几十个(p >> n),CCA算出来的投影向量几乎全是噪声。我记得第一次做多组学整合时,兴冲冲跑了CCA,结果出来的载荷系数密密麻麻一长串,根本看不出哪些特征是真正相关的。后来我才意识到,传统CCA在高维场景下就是个"过拟合狂魔"。
sgCCA在这个基础上加了两点关键改进:
- 稀疏性——让大部分系数归零,只保留最关键的特征
- 广义性——从两组数据扩展到多组数据,真正为多组学设计
| 特性 | CCA | sgCCA |
|---|---|---|
| 数据组数 | 2组 | 多组(≥2) |
| 稀疏性 | 无 | L1惩罚(lasso) |
| 高维适用性 | 否(p >> n 失效) | 是,自带特征筛选 |
| 结果可解释性 | 低,载荷稠密 | 高,只保留关键变量 |
sgCCA的数学配方
数学上,sgCCA的目标函数长这样:
max ∑_{i<j} a_iᵀ X_iᵀ X_j a_j
约束条件有两组:
(1)a_iᵀ X_iᵀ X_i a_i = 1 (方差归一化)
(2)||a_i||₁ ≤ c_i (稀疏约束)
说白了,就是找一组投影向量 a_i,让各组学数据投影后的两两相关性总和最大,同时每个 a_i 只有少数非零元素。这里的 c_i 控制了稀疏程度——c_i 越小,投影向量越稀疏,选出的特征越少。
我见过不少人一上来就把 c_i 设得很小,结果丢掉了关键信号。嗯,这里要记住:稀疏不是越稀疏越好,得让数据说了算。
优化算法怎么跑? 实际求解用的是块坐标下降(block coordinate descent),每次固定其他投影向量,更新一个 a_i,交替迭代直到收敛。每一轮更新本质上是一个带L1约束的奇异值分解问题。
广义维度:多组学的自然握手
多组学数据有个特点——每个组学都有自己的数据结构(基因表达、蛋白丰度、代谢物浓度),但又共享同一批样本。sgCCA的"广义"就体现在它能同时处理 ≥2 组数据,并且为每组数据分配一个专属的投影向量。
DIABLO在这个基础上又加了一个"设计矩阵"。 这玩意儿用来指定哪些组学之间应该强相关,哪些可以弱一些。比如转录组和蛋白组往往关联紧密,设计矩阵里的权重就设高一点;蛋白组和代谢组的关联可能弱一些,权重就设低一点。
设计矩阵示例(3组学):
mRNA protein metabolome
mRNA 0 0.8 0.5
protein 0.8 0 0.3
metabol 0.5 0.3 0
这个矩阵是DIABLO的"秘密武器"。我曾经在一个肿瘤多组学项目里,因为没调好设计矩阵,结果蛋白组和代谢组被强行拉到一起,反而模糊了信号。后来我把权重调低了两档,模型一下子就稳了。
DIABLO中的sgCCA实战
在R语言里,用 mixOmics 包调用 DIABLO(也就是 sgCCA 的扩展版本)非常直接:
library(mixOmics)
# 假设你有三组数据:mRNA、蛋白、代谢
data_list <- list(
mRNA = mrna_data,
protein = protein_data,
metabolome = metabolome_data
)
# 构建DIABLO模型
model <- block.splsda(
X = data_list,
Y = sample_labels,
ncomp = 3,
keepX = list(
mRNA = c(50, 30, 20),
protein = c(30, 20, 10),
metabolome = c(20, 15, 10)
),
design = matrix(c(0, 0.8, 0.5,
0.8, 0, 0.3,
0.5, 0.3, 0),
nrow = 3, byrow = TRUE)
)
# 查看提取的典型成分(潜在变量)
head(model$variates$mRNA)
这里的 keepX 就是每个组学在每个成分上保留的特征数——说白了就是稀疏参数的直接体现。我习惯先用交叉验证扫一遍 keepX 的组合,而不是拍脑袋乱设。
sgCCA核心流程一览
下面这张图把 sgCCA 在 DIABLO 里的完整流程串起来了——从多组学数据输入,到稀疏投影,再到整合评估。
从输入到输出,五个节点依次递进。我个人觉得这张图最核心的就是"稀疏约束"那一步——它把CCA从"全变量参与"变成了"关键变量参与",这才是sgCCA能在高维场景下站稳脚跟的根本原因。
调参与避坑指南
跑DIABLO时,有几个参数需要特别上心:
- keepX(稀疏参数)——每个组学每个成分保留的特征数。我曾经因为keepX设得太大,结果第一个成分就塞进了上百个基因,可解释性一塌糊涂;后来设得太小,又把关键通路给过滤掉了。嗯,建议用交叉验证(perf函数)来选。
- 设计矩阵(design matrix)——控制组学间的连接强度。我见过很多人忽略这个参数,全设成1,结果所有组学被"强行绑定",反而模糊了各自的特异性。不同组学之间的关联强度本来就不同,这个参数值得花时间调。
- 成分个数(ncomp)——一般取2~3个就够了。我在多个项目中观察到,从第4个成分开始,解释力往往断崖式下降。