168_单细胞空间deconvolution¶
一句话概述¶
空间转录组反卷积利用单细胞RNA-seq参考数据,将空间转录组(如10x Visium)每个spot中混合的多种细胞类型进行比例解析,常用方法包括cell2location(贝叶斯)、RCTD(robust回归)、Tangram(深度学习映射)和DestVI(变分推断)。
核心知识点总览¶
| 知识点 | 说明 |
|---|---|
| 空间spot混合问题 | 每个Visium spot含1-10个细胞的混合信号 |
| cell2location | 贝叶斯层次模型,估计每个spot中各细胞类型的绝对丰度 |
| RCTD | Robust Cell Type Decomposition,多参考robust回归 |
| Tangram | 将单细胞映射到空间位置的深度学习方法 |
| DestVI | 变分推断框架的空间反卷积 |
| 参考数据质量 | 单细胞参考的细胞类型注释质量决定反卷积上限 |
| 分辨率限制 | Visium ~55μm spot → 多细胞; Slide-seq ~10μm → 接近单细胞 |
各步骤详解¶
第一步:空间反卷积原理¶
白话解释: Visium空间转录组的每个"点"(spot)其实覆盖了约1-10个细胞。测到的基因表达是这些细胞的"混合物"。空间反卷积就是利用单细胞数据作为"字典",把每个spot的混合信号分解成各种细胞类型的贡献——告诉你这个spot里大概有多少T细胞、多少肿瘤细胞、多少成纤维细胞。
第二步:cell2location¶
代码示例:
import cell2location
import scanpy as sc
import numpy as np
# 1. 准备单细胞参考数据
adata_ref = sc.read_h5ad("scRNA_reference.h5ad")
# 需要: adata_ref.obs['cell_type'] - 细胞类型注释
# 2. 计算参考细胞类型的基因表达签名
from cell2location.models import RegressionModel
# 设置参考模型
RegressionModel.setup_anndata(adata_ref, labels_key="cell_type")
mod_ref = RegressionModel(adata_ref)
mod_ref.train(max_epochs=250, use_gpu=True)
# 导出签名
adata_ref = mod_ref.export_posterior(adata_ref)
inf_aver = adata_ref.varm["means_per_cluster_mu_fg"]
# 3. 准备空间数据
adata_vis = sc.read_h5ad("visium_data.h5ad")
# 4. 运行cell2location
from cell2location.models import Cell2location
Cell2location.setup_anndata(adata_vis)
mod = Cell2location(
adata_vis,
cell_state_df=inf_aver,
N_cells_per_location=10, # 每个spot的预期细胞数
detection_alpha=20 # 检测灵敏度超参数
)
mod.train(max_epochs=30000, batch_size=None, train_size=1, use_gpu=True)
# 5. 提取结果
adata_vis = mod.export_posterior(adata_vis)
# 每个spot中各细胞类型的绝对丰度
cell_abundances = adata_vis.obsm["q05_cell_abundance_w_sf"]
# 6. 可视化
mod.plot_spatial_QC_across_batches()
cell2location.utils.plot_spatial(
adata_vis, color=["T_cell", "Macrophage", "Cancer"],
img_key="hires", spot_size=1.3
)
第三步:RCTD¶
代码示例:
library(spacexr)
# 1. 准备参考数据
reference <- Reference(
counts = sc_counts, # 基因×细胞的counts矩阵
cell_types = sc_cell_types, # 细胞类型向量
nUMI = colSums(sc_counts) # 每个细胞的UMI数
)
# 2. 准备空间数据
coords <- data.frame(
x = spatial_coordinates$x,
y = spatial_coordinates$y,
row.names = colnames(spatial_counts)
)
puck <- SpatialRNA(coords, spatial_counts, colSums(spatial_counts))
# 3. 运行RCTD
myRCTD <- create.RCTD(puck, reference, max_cores = 8)
myRCTD <- run.RCTD(myRCTD, doublet_mode = "full")
# doublet_mode: "full"=每个spot多细胞类型; "doublet"=最多2种
# 4. 提取结果
results <- myRCTD@results
# 每个spot的细胞类型权重
weights <- as.matrix(results$weights)
# 归一化为比例
proportions <- sweep(weights, 1, rowSums(weights), "/")
# 5. 可视化
library(ggplot2)
plot_data <- cbind(coords, proportions)
ggplot(plot_data, aes(x = x, y = y, color = T_cell)) +
geom_point(size = 1.5) +
scale_color_viridis_c() +
theme_void() +
labs(title = "T cell abundance (RCTD)")
第四步:Tangram¶
代码示例:
import tangram as tg
import scanpy as sc
# 1. 准备数据
adata_sc = sc.read_h5ad("scRNA.h5ad") # 单细胞
adata_sp = sc.read_h5ad("spatial.h5ad") # 空间
# 2. 找到共有的高变基因
sc.pp.highly_variable_genes(adata_sc, n_top_genes=2000)
markers = adata_sc.var_names[adata_sc.var.highly_variable]
# 3. 预处理
tg.pp_adatas(adata_sc, adata_sp, genes=markers)
# 4. 训练映射模型
adata_map = tg.map_cells_to_space(
adata_sc, adata_sp,
mode="cells", # "cells" or "clusters"
density_prior="rna_count_based",
num_epochs=500,
device="cuda:0"
)
# 5. 投影细胞类型到空间
tg.project_cell_annotations(adata_map, adata_sp, annotation="cell_type")
# 6. 可视化
sc.pl.spatial(adata_sp, color=["T_cell", "Macrophage"], spot_size=1.5)
第五步:方法对比与选择¶
| 特征 | cell2location | RCTD | Tangram | DestVI |
|---|---|---|---|---|
| 框架 | 贝叶斯(Pyro) | 多元回归 | 深度学习 | 变分推断(scvi) |
| 输出 | 绝对丰度 | 比例 | 映射概率 | 比例+表达 |
| GPU需要 | 推荐 | 不需要 | 推荐 | 推荐 |
| 速度 | 中(30k epochs) | 快 | 快(500 epochs) | 中 |
| 不确定性 | 贝叶斯后验 | 置信区间 | 无 | 贝叶斯后验 |
| 推荐场景 | 绝对丰度+不确定性 | 快速稳健 | 细胞级映射 | scvi生态整合 |
实战命令¶
# === 环境安装 ===
pip install cell2location tangram-sc scvi-tools
# R: install.packages("spacexr")
# === cell2location完整流程 ===
python run_cell2location.py --sc_ref reference.h5ad --spatial visium.h5ad \
--cell_type_key celltype --n_cells_per_spot 10 --output results/
# === RCTD ===
Rscript run_rctd.R --sc_counts sc_counts.rds --spatial spatial.rds \
--cell_types celltypes.csv --output rctd_results/
面试常问点¶
Q1:为什么Visium数据需要反卷积?¶
A: Visium的spot直径55μm,通常包含1-10个细胞的混合信号。直接分析spot级别的基因表达无法区分是哪种细胞类型贡献了特定基因的表达。反卷积通过利用配对的scRNA-seq参考数据,将spot信号分解为各细胞类型的贡献,实现近似单细胞分辨率的空间细胞类型定位。
Q2:cell2location与bulk RNA-seq反卷积(如CIBERSORT)有什么本质区别?¶
A: (1) cell2location使用负二项分布建模counts(适合UMI数据),CIBERSORT假设正态/线性;(2) cell2location输出每个spot的绝对细胞丰度(不受其他类型影响),CIBERSORT输出相对比例;(3) cell2location利用空间信息(通过先验约束邻近spot应有相似组成);(4) cell2location提供贝叶斯不确定性估计。
Q3:参考scRNA-seq数据的质量如何影响空间反卷积?¶
A: 参考数据是反卷积的"字典"——字典有误则结果必然错误。关键要求:(1) 细胞类型覆盖完整——空间数据中存在但参考中缺失的类型会被错误分配;(2) 注释准确——错误标注的细胞会污染签名矩阵;(3) 组织匹配——同一组织/条件的参考最佳;(4) 样本量充分——每种细胞类型建议>50个细胞以获得稳定的签名。
Q4:如何验证空间反卷积的结果?¶
A: (1) 与已知生物学一致:如T细胞集中在肿瘤边界、上皮细胞在黏膜层;(2) 与免疫荧光/IHC空间定位一致(gold standard);(3) 已知marker基因在对应细胞类型丰度高的spot中高表达;(4) 不同反卷积方法的结果一致性;(5) 使用模拟数据(pseudo-spot, 混合已知比例的单细胞)做定量评估。
Q5:对于亚细胞分辨率的空间技术(如MERFISH/Xenium)还需要反卷积吗?¶
A: 不需要——这些技术已经在单细胞甚至亚细胞分辨率工作。MERFISH/MERSCOPE/Xenium/CosMx可以直接检测单个细胞中的RNA分子位置。这些平台的分析挑战不是反卷积,而是细胞分割(segmentation)、基因面板设计和细胞类型注释。Visium HD(2μm bin)也接近单细胞分辨率,反卷积需求减少。
易错点¶
1. scRNA-seq参考与空间数据来自不同条件¶
错误: 用正常组织的scRNA-seq参考去反卷积肿瘤空间数据。 正确做法: 参考和空间数据应来自尽可能相似的条件/组织。肿瘤空间数据应用肿瘤scRNA-seq参考(含肿瘤细胞+TME细胞)。
2. 未过滤低质量spot¶
错误: 包含组织边缘/空白区域的spot做反卷积。 正确做法: 先用Seurat/Scanpy进行空间数据QC,去除低UMI/低基因数的spot(通常是组织外或坏死区)。
3. 对所有spot报告相同细胞类型数¶
错误: 声称每个spot都包含所有8种细胞类型。 正确做法: 大多数spot只含2-4种主要细胞类型。设置丰度阈值(如cell2location的q05>5),低于阈值的细胞类型视为不存在。
4. 忽略批次效应¶
错误: scRNA-seq参考和空间数据有明显的技术差异(不同测序平台)。 正确做法: cell2location内置了技术效应校正;其他方法建议先做batch correction或使用共有高变基因减少技术差异影响。
补充知识¶
新一代空间技术分辨率¶
| 技术 | 分辨率 | 是否需反卷积 |
|---|---|---|
| Visium | 55μm (1-10细胞) | 需要 |
| Visium HD | 2μm (亚细胞) | 通常不需要 |
| Slide-seq | 10μm (~1细胞) | 可能需要 |
| MERFISH/Xenium | 单细胞/亚细胞 | 不需要 |
| STARmap | 单细胞 | 不需要 |
相关工具¶
- cell2location: 贝叶斯空间反卷积(推荐)
- RCTD/spacexr: R生态的robust方法
- Tangram: 深度学习细胞映射
- DestVI: scvi-tools生态
- SPOTlight: 基于NMF的简单方法
- stereoscope: 概率模型方法