高变基因选择概述:什么是 HVG,为什么重要

最开始接触单细胞分析时,我一度觉得「找高变基因」这一步可有可无。不就是把表达量高的基因拎出来吗?直到我手头一个 10X 数据跑完 PCA,所有细胞扎堆成一团,怎么调参数都分不开。后来一位前辈提醒我:你试试只拿前 2000 个高变基因重跑。结果聚类瞬间清晰了。嗯,从那时起,我再也不敢忽视这个步骤了。

什么是高变基因(HVG)?

高变基因,全称 Highly Variable Genes,指的是在细胞之间表达水平差异最大的那些基因。说白了,就是那些「有的细胞高表达、有的细胞低表达」的基因。为什么它们重要?因为真正能定义细胞类型、驱动生物学差异的,正是这些浮动剧烈的基因——而那些在所有细胞里都差不多的「管家基因」,对区分细胞几乎没有贡献。

我见过很多新手直接把全部两万个基因塞进 PCA。结果是什么?信号直接被平均掉了。举个例子:你在噪声很大的集市里想听一个人的声音,你能把所有背景噪音都一起放大吗?不行,你得先过滤掉那些没变化的背景声。HVG 选择就是这个滤声器。

为什么 HVG 选择如此关键?

从维度惩罚的角度看:单细胞数据通常是 细胞数 << 基因数(比如 5000 个细胞 vs 20000 个基因)。如果不对基因做降维,后续聚类和可视化会被大量无关基因稀释。HVG 选择把维度降到 1000~3000,同时保留了生物学差异最大的信息。

从计算效率上看:我经历过一个 10 万细胞的骨髓数据集,全基因跑 PCA 花了一个多小时,HVG 筛选后只要十分钟。说白了,时间就是成本。

从生物学意义上讲:很多关键 marker 基因(如 CD3D、CD14、CD19)本身就在高变基因列表里。如果不做 HVG 筛选,这些信号的权重会被沉默基因拉低,导致你根本看不到想看的细胞亚群。

核心总结: HVG 选择是单细胞分析中「性价比」最高的步骤——花最少的时间,解决最大的信号稀释问题。

Seurat 中 HVG 选择的基本流程

在 Seurat 中,我们通过 FindVariableFeatures 函数完成这一步。默认方法 vst(方差稳定变换)是目前最常用的。下面是最简单的调用模板:

seurat_obj <- FindVariableFeatures(
  seurat_obj,
  selection.method = "vst",
  nfeatures = 2000
)

这行代码会从你的基因表达矩阵里挑选出 2000 个表达量变异最大的基因,并存入 seurat_obj@assays$RNA@var.features。之后你跑 ScaleData、RunPCA 时,Seurat 默认只对这些高变基因做计算。

三种主流选择方法对比

Seurat 提供了三种方法,我过去在不同数据集上踩过坑,给你一个对比表:

方法 原理 适用场景 我的个人建议
vst 方差稳定变换,拟合基因的均值-方差关系 大多数常规 10X 数据;尤其细胞数 > 3000 时 首选,稳定且快
mvp 基于均值-变异系数(CV)的排名 数据噪声较大、捕获效率不均时 我曾在 T 细胞数据上用过,效果略好于 vst
disp 基于离散度(方差/均值)的直接排序 小样本数据或快速预览时 不太推荐,容易选中线粒体基因

注意: 不要一上来就用 nfeatures = 5000 追求高数量。我在一个 PBMC 数据集上试过,5000 个基因里混入了大量核糖体蛋白基因(RPL/RPS),导致聚类结果完全被翻译基驱动。一般 2000~3000 就足够覆盖生物学信号了。

HVG 选择在单细胞分析流程中的位置

下面这张图你一看就明白了——HVG 选择是连接「数据标准化」和「PCA 降维」的桥梁。跳过它,后面的降维就是在白费功夫。

单细胞分析标准流程中的 HVG 选择 原始表达矩阵 标准化 HVG 选择 (本课程重点) PCA/LSI 聚类 UMAP / 注释 为什么不能跳过 HVG? • 全基因信号被稀释,PCA 失效 • 计算慢 10~50 倍 • 低质量基因会引入批效应

一个我踩过的坑

曾经有个项目需要分析一批 10X 单细胞数据,细胞数只有 800 左右(太少)。我直接用了默认 nfeatures = 2000 和 vst 方法,跑出来的 HVG 里面居然有一半是线粒体基因和核糖体基因。聚类结果被污染得不成样子。后来我改了参数:

seurat_obj <- FindVariableFeatures(
  seurat_obj,
  selection.method = "vst",
  nfeatures = 1500,
  mean.cutoff = c(0.1, 3),
  dispersion.cutoff = c(0.5, Inf)
)

加上 mean.cutoff 和 dispersion.cutoff 之后,那些异常高表达的线粒体基因被过滤掉了。这件事告诉我:参数不是死的,要结合实际数据的表达量分布来调。更多关于这些参数的含义和调优方法,我会在第 3~5 章详细讲。

小技巧: 在选 HVG 之前,先用 FeatureScatter 看看基因的均值-方差图,你能直观判断出哪些基因是真正的「高变」。如果看到一条长长的尾巴全是线粒体基因,你就该调参数了。

小结

高变基因选择,说简单点就是「从两万个基因里挖出那两三千个最能代表生物差异的」。它决定了你的降维、聚类、可视化能不能看到真正的细胞群体。我见过太多同学在这步敷衍了事,结果后期调聚类参数调到头秃——其实问题往往出在起点。

后面的章节,我会带你一个一个参数拆解。我们先搞定概念,再动手调代码。