跳转至

377_单细胞批量注释自动化


一句话说明

自动注释就是用已知的参考图谱或机器学习模型,自动判断"每个细胞是什么类型",省去手动查marker基因的大量时间。


核心知识点

要点1:手动注释 vs 自动注释

  • 手动注释:UMAP上看cluster→查文献marker基因→人工判断细胞类型
  • 优点:专家经验,可信度高
  • 缺点:耗时,主观性强,难以处理几十个cluster
  • 自动注释:用参考数据集训练的分类器预测细胞类型
  • 优点:快速、可重现、可扩展
  • 缺点:参考数据集不匹配时准确率下降

要点2:主流自动注释工具

工具方法参考来源特点
SingleR相关性打分体外、内置数据库不需要训练,快速
sctype标记基因打分自定义标记基因表无需参考数据集
Azimuth监督学习人类参考图谱适合人类常见组织
CellTypist逻辑回归可训练自定义速度快,模型丰富
scANVI深度学习VAEscRNA-seq参考与批次校正结合

要点3:SingleR 工作原理

  • 对每个测试细胞,与参考数据集中所有细胞做相关性计算
  • 找到最相似的参考细胞,取其细胞类型标签
  • 经过多轮"精细调优"(fine-tuning)消除歧义
  • 输出置信度分数(score),score高=注释可信

要点4:scType 工作原理(轻量级)

  • 不需要参考数据集,只需要marker基因表(Excel即可)
  • 计算每个cluster中marker基因的加权表达分数
  • 选分数最高的细胞类型作为注释
  • 适合有自己领域marker基因知识的研究者

要点5:注释质量控制

  • 置信度阈值:低置信度(如SingleR的 pruned.labels 为NA)的细胞标记为"未定义"
  • 与手动核对:对自动注释结果,用已知marker基因做交叉验证
  • Marker基因验证DotPlotFeaturePlot 展示各类型的marker表达

实战代码

SingleR 自动注释

library(SingleR)      # 自动细胞类型注释
library(Seurat)       # 单细胞分析
library(celldex)      # 内置参考数据集

# ============================================================
# 方法A:使用内置参考数据集(免下载,适合快速注释)
# ============================================================
# 加载 HumanPrimaryCellAtlasData(人类原代细胞图谱)
ref_hpca <- HumanPrimaryCellAtlasData()    # 自动下载参考数据
# 其他可选参考:
# ref_blueprint <- BlueprintEncodeData()  # BLUEPRINT免疫细胞
# ref_monaco <- MonacoImmuneData()        # 免疫细胞精细分类

# 提取测试数据的表达矩阵(使用log-normalized counts)
test_matrix <- GetAssayData(seurat_obj, layer = "data")  # Seurat v5用layer

# 运行 SingleR 注释
singler_results <- SingleR(
  test = test_matrix,           # 测试数据矩阵(基因×细胞)
  ref = ref_hpca,               # 参考数据集
  labels = ref_hpca$label.main, # 使用粗粒度标签(也可用label.fine精细标签)
  num.threads = 4               # 4线程加速
)

# 查看注释结果统计
table(singler_results$labels)

# 将注释结果整合回 Seurat 对象
seurat_obj$SingleR_labels <- singler_results$labels
seurat_obj$SingleR_scores <- apply(singler_results$scores, 1, max)  # 最高置信度得分

# 过滤低置信度注释(pruned.labels为NA表示注释不可靠)
seurat_obj$SingleR_pruned <- singler_results$pruned.labels

# 可视化注释结果
DimPlot(
  seurat_obj,
  group.by = "SingleR_labels",   # 按SingleR标签着色
  reduction = "umap",
  label = TRUE,
  repel = TRUE,
  pt.size = 0.5
) + ggtitle("SingleR 自动注释结果")

# ============================================================
# 方法B:scType(只需marker基因表,无需参考数据集)
# ============================================================
# 安装 sctype(GitHub包)
if (!require("sctype")) devtools::install_github("IanevskiAleksandr/sc-type/R")
source("https://raw.githubusercontent.com/IanevskiAleksandr/sc-type/master/R/sctype_score_.R")

# 下载内置marker数据库(也可自定义)
db_url <- "https://raw.githubusercontent.com/IanevskiAleksandr/sc-type/master/ScTypeDB_full.xlsx"
download.file(db_url, "ScTypeDB_full.xlsx", quiet = TRUE)

# 加载marker基因(选择组织类型)
library(openxlsx)
gs_list <- gene_sets_prepare("ScTypeDB_full.xlsx",
                              tissue_type = "Immune system")   # 选择组织类型

# 计算每个细胞对各类型的得分
es.max <- sctype_score(
  scRNAseqData = seurat_obj[["RNA"]]@scale.data,  # 使用scaled data
  scaled = TRUE,
  gs = gs_list$gs_positive,    # 正向marker基因
  gs2 = gs_list$gs_negative    # 负向marker基因
)

# 按cluster汇总得分,选最高得分的细胞类型
cL_results <- do.call("rbind", lapply(unique(seurat_obj@meta.data$seurat_clusters), function(cl) {
  es.max.cl <- sort(rowSums(es.max[, rownames(seurat_obj@meta.data[seurat_obj@meta.data$seurat_clusters == cl, ])]),
                    decreasing = TRUE)
  data.frame(cluster = cl, type = names(es.max.cl[1]),
             scores = es.max.cl[1], ncells = sum(seurat_obj@meta.data$seurat_clusters == cl))
}))

# 添加到 Seurat 对象
seurat_obj@meta.data$customclassif <- ""
for (j in unique(cL_results$cluster)) {
  cl_type <- cL_results[cL_results$cluster == j, ]
  seurat_obj@meta.data$customclassif[seurat_obj@meta.data$seurat_clusters == j] <- cl_type$type[1]
}

CellTypist 自动注释(Python)

import celltypist       # 轻量级自动注释工具
import scanpy as sc

# 加载预处理好的 AnnData
adata = sc.read_h5ad("preprocessed.h5ad")

# 下载预训练模型(人类免疫细胞)
celltypist.models.download_models(
    model="Immune_All_Low.pkl",     # 低粒度免疫细胞模型
    force_update=False              # 已下载则不重复下载
)

# 自动注释(over_clustering=True:先细粒度聚类再注释)
predictions = celltypist.annotate(
    adata,
    model="Immune_All_Low.pkl",    # 指定模型
    majority_voting=True,           # 对每个cluster投票取多数标签
    over_clustering="leiden"        # 使用已有的leiden聚类结果
)

# 整合注释结果
adata = predictions.to_adata()     # 将预测结果写回 adata
print(adata.obs["majority_voting"].value_counts())  # 查看各类型细胞数

# 可视化
sc.pl.umap(adata, color="majority_voting",
           legend_loc="on data",   # 标签显示在图上
           title="CellTypist 自动注释",
           save="_celltypist.pdf")

面试常问点

  1. SingleR和CellTypist哪个更准? 取决于参考数据集;SingleR用相关性更保守,CellTypist用逻辑回归对大规模数据更快
  2. 自动注释结果如何验证?DotPlot 检查各细胞类型的已知marker基因表达是否符合预期
  3. 遇到低置信度细胞怎么办? SingleR的 pruned.labels 为NA的细胞标为"Unknown",可能是稀有细胞类型或双细胞

速查表

场景推荐工具优势
快速初步注释SingleR无需训练,内置参考
只有marker基因表scType无需参考数据集
人类免疫细胞Azimuth/CellTypist专门优化
与批次校正整合scANVI深度学习,同时解决两个问题