在单细胞分析里,基因表达矩阵通常包含几万个基因,但其中只有一小部分基因在不同细胞间表现出足够大的生物学差异,能够帮助我们区分细胞类型或状态。选取“高变基因”(Highly Variable Genes, HVGs)这一步,就是为了从海量基因中筛出那部分“最具信息量”的基因,避免噪声和低变基因拖累后续的降维、聚类和可视化。


高变基因选择的“做什么”——分步解析#

  1. 输入数据:归一化 & 对数化后的表达

    • 在此之前,已经做了 normalize_total(将每个细胞的总 UMI 统一到 1e4)和 log1p 转换,得到“log1p_norm_count”层。

    • 目的是让不同细胞的测序深度可比,同时压缩极端值、近似正态分布。

  2. 计算每个基因的平均表达(μ)和方差(σ²)

    • 对所有细胞,分别统计每个基因在多少细胞中被检测到(用于过滤),以及在这些细胞里的均值与方差。
  3. 拟合均值–方差关系曲线

    • 生物学上,表达量很低的基因方差往往也小;表达量很高的基因方差也大,这是一个“漂移”趋势。

    • 我们要找的,是“比同等级表达量下更高方差”的基因,因此先用曲线(如 loess 或 Seurat 的方差标准化方法)拟合全局的 μ–σ² 关系。

  4. 计算“标准化离散度”

    • 对每个基因,求出它的实际方差与拟合曲线上的预期方差之差,或更常见地,计算 “归一化后的离散度指标”(standardized dispersion/z-score)。

    • 这个值越大,说明该基因在同样表达水平下,离散得越厉害——更可能反映细胞间真实的生物学差异。

  5. (可选)按批次分组再汇总

    • 如果你指定了 batch_key(比如 BatchSample_Site),Scanpy 会先在每个组(批次)内独立做上面几步,得到每个基因在每个组内的标准化离散度;

    • 然后再取各组离散度的中位数或其它汇总指标,对基因做全局排名,以确保所选 HVG 既在各批次中都有表现,而不是被某一个批次“带跑偏”了。

  6. 按照“标准化离散度”从高到低取前 N 个基因

    • 最常见的做法是直接指定 n_top_genes=5000(或其它数字),把排名靠前的 5,000 个基因标记为 adata.var['highly_variable'] = True

    • 这些基因集合就是你后续做 PCA/UMAP/聚类时的 “特征基因集”。


为什么要做这一步?#

  • 去噪:排除那些在所有细胞里都表现“很平均”、或几乎不表达的基因,它们对分辨细胞类型毫无帮助。

  • 减维:基因维度从数万降到几千,不仅加快计算,也聚焦在最有信号的区域。

  • 提升可解释性:高变基因往往包含各细胞类型或状态的标志性基因,更容易在后续可视化图(如特征基因热图、DotPlot)中找到生物学意义。


小结#

sc.pp.highly_variable_genes 这一步,本质上是在问:

“在你给定的表达矩阵里,哪些基因的细胞间变异度,明显超出了它们自身平均表达量所能解释的那部分?”

通过拟合均值–方差关系、计算标准化离散度,再按批次(可选)汇总,Scanpy 就能帮你自动挑出那批“最会变”的基因,作为后续降维和聚类的高信息量特征。