3. 参数 selection.method 详解:vst 方法归纳总结

好,咱们今天来聊聊 vst 这个方法。说白了,它就是 Seurat 里默认的高变基因选择方法。为什么选它做默认?因为它在多数场景下表现最稳定,尤其是处理 scRNA-seq 常见的“均值-方差”关系时,比 mvp 和 disp 更聪明。

3.1 vst 的核心思路

vst 的全称是 Variance Stabilizing Transformation(方差稳定化变换)。名字挺长,但逻辑不复杂。

  • 目标:找到那些在细胞之间表达波动最大的基因,排除掉单纯因为表达量高才显得离散的基因。
  • 怎么做:先拟合每个基因的表达均值与方差之间的经验关系(一般是幂律分布),然后对标准化后的方差进行打分。得分高的基因就是真正“高变”的。

我记得第一次上手 scRNA-seq 分析时,直接用原始方差排了个序,结果前几个全是线粒体基因。后来才明白,那是高表达带来的假象。vst 就是为了解决这个坑。

3.2 vst 的两步走流程

我个人习惯把 vst 理解成两步操作:拟合 → 打分。下面这张图帮你一眼看清全流程。

vst 高变基因选择流程 vst 参数选择方法:拟合 → 打分 → 选顶 原始表达矩阵 (RNA counts) 拟合均值-方差经验关系 计算标准化方差得分 排序,选 Top nfeatures 关键特点 • 自动去除高表达噪声 • 不需要预先标记基因 • 对dropout鲁棒 • 计算量比mvp稍大 • 默认参数适合90%场景
经验小贴士: vst 的拟合过程默认只用了前 2000 个基因(通过 nselection 参数控制),并不是遍历全部 2 万多个基因。这能大幅加速计算,而精度损失几乎可忽略。我曾在 6 万细胞的数据集上测试过,完全够用。

3.3 vst 的核心参数

你直接跑 FindVariableFeatures 默认就是 vst。但有些参数值得手动调一调。我整理了下面这个表格,方便你对照。

参数名 默认值 含义 我的建议
nfeatures 2000 最终保留的高变基因数 细胞数 >5000 时可升至 3000–5000
nselection 2000 用于拟合均值-方差关系的基因数 一般不动,增加会拖慢速度
loess.span 0.3 LOESS 回归的平滑参数 数据噪声大时可调到 0.5,不要低于 0.2
clip.max 'auto' 裁剪极端值的分位数上限 默认 auto 一般不必改;若有异常高表达基因,手动设 0.01 或 0.05
mean.cutoff c(0.1, 8) 均值筛选范围(log尺度) 想保留更多低表达基因可放宽下限到 0.05

3.4 代码实战:跑一次 vst

直接上代码。你会看到 vst 的调用极其简单,但背后做的工作不少。

# 加载 Seurat
library(Seurat)

# 假设你已经有了 scobj(一个 Seurat 对象)
scobj <- NormalizeData(scobj)

# 使用 vst 方法选择 2000 个高变基因
scobj <- FindVariableFeatures(
  scobj,
  selection.method = "vst",
  nfeatures = 2000
)

# 看看结果
head(VariableFeatures(scobj))
曾经踩过的坑: 有一次我忘记先对数据做 NormalizeData,结果 vst 警告了一堆 NaN。后来检查帮助文档才发现,vst 要求输入数据是经过标准化的。虽然 Seurat 内部会再处理一层,但保险起见还是先 normalize 为妙。

3.5 vst 的输出怎么看

Seurat 会在 scobj@assays$RNA@meta.features 里记录每个基因的 vst 得分。我们可以手动提取来检查。

# 提取 vst 得分表
vst_scores <- GetAssayData(scobj, assay = "RNA", slot = "meta.features")
# 查看得分最高的几个基因
vst_scores <- vst_scores[order(vst_scores$vst.variance.standardized, decreasing = TRUE), ]
head(vst_scores[, "vst.variance.standardized", drop = FALSE])

得分越高,代表该基因在细胞间表达波动越显著。你可以用这个列表去验证一下,list 里通常会有很多免疫相关的基因(如 CD3D, CD79A, LYZ 等)——这就是 scRNA-seq 里常见的信号。

3.6 什么时候该换其他方法?

vst 确实很通用,但也不是万能。我遇到过两个场景会选择避开它:

  1. 数据极其稀疏(比如 90% 以上的零)。vst 的 LOESS 拟合在低计数区域会不稳定,此时 disp 方法反而更鲁棒。
  2. 细胞类型差异非常小(比如都是同一细胞系的用药前后)。vst 可能把生物信号当作噪声滤掉,我会改用 mvp 并手动指定均值-方差阈值。
一句话总结 vst: 它是你日常分析里最省心的选择。除非遇到上述特殊情况,否则直接用默认参数跑,效果都不会太差。我个人的 pipeline 里,80% 的项目都是直接 selection.method = "vst" 完事。

3.7 避坑指南

  • 不要小看 loess.span:它控制着拟合曲线的光滑程度。设太小(比如 0.1)会导致过拟合,一部分低表达基因被错误地标记为高变。
  • 注意 nselection 和 nfeatures 的区别:前者决定用多少基因来拟合曲线,后者决定最终选出多少。如果 nselection < nfeatures,多余的基因只能靠外推排序,结果会变差。
  • 数据集太小时(比如不到 50 个细胞),vst 的方差估计会很不稳定。我一般会先凑够至少 200 个细胞再用 vst,不然就换成 disp 手动设参数。

好了,vst 的参数和方法就讲到这。你记住一个核心理念就够了:vst 通过拟合均值-方差关系把“高表达”和“高变”区分开,帮你找到真正有生物学意义的差异基因。下次跑 Seurat 的时候,不妨试试调一调 loess.span 看看变化——也许会有新发现。