作者按

本章节主要讲解了基于transformer的迁移注释方法TOSICA,该算法在迁移注释上达到了SOTA的水平,在注释这么卷的赛道愣是杀出了一条血路。本教程首发于单细胞最好的中文教程,未经授权许可,禁止转载。

全文字数|预计阅读时间: 3000|3min

——Starlitnightly(星夜)

1. 背景

迁移注释实际上是自动注释的一类,与我们在3-4中介绍的自动注释不同,迁移注释需要我们有一个已经注释好的单细胞测序数据文件,而不是训练好的模型或者marker。我们需要使用这个已经注释好的单细胞测序数据文件来训练一个新的模型,例如Cell-Blast或者是Tosica等。

此外,对于多个样本的单细胞测序文件,我们可以先主动注释好一个样本,然后使用迁移注释的方式,把剩下的样本也一起注释了。在这里,我们将介绍迁移注释的SOTA算法,TOSICA。TOSICA 实现了快速、准确的一站式注释和对批量不敏感的整合,同时为理解发育和疾病进展过程中的细胞行为提供了可解释的生物学见解。

import omicverse as ov
print(f'omicverse version: {ov.__version__}')
import scanpy as sc
print(f'scanpy version: {sc.__version__}')
ov.ov_plot_set()

omicverse version: 1.5.1
scanpy version: 1.9.1

2. 加载数据

需要注意的是,参考单细胞测序数据与要注释的单细胞测序数据要保持一致的归一化方法。归一化方法通常受sc.pp.normalize_totaltarget_sum参数的影响,在scanpy中,默认值为自适应,这会导致我们在迁移注释时出错,为了避免这种情况的出现,我们需要将其统一,不能留空。网上的教程包括seurat会将target_sum设置为1e4

而如果你是使用omicverse的preprocess函数进行的归一化,那么默认target_sum50*1e4。而在本教程中,我们将统一使用原始counts,然后使用omicverse的preprocess函数进行预处理与归一化

2.1 参考注释数据集

一个高质量的参考注释数据集对我们注释结果的影响是至关重要的,在这里,我们介绍Cell Blast参考注释数据集,Cell Blast收集了100+个高质量的单细胞注释数据集,我们从中下载了Zheng来注释我们的骨髓数据集。

需要注意的是,我们用来训练的参考数据集不能少于30,000个细胞,否则训练出来的TOSICA模型效果一般,如果参考数据集大于100,000个细胞,我们也可以随机选择30,000个细胞进行训练,效果是一样的。

!wget https://cblast.gao-lab.org/Zheng/Zheng.h5ad

--2023-08-31 19:21:26--  https://cblast.gao-lab.org/Zheng/Zheng.h5ad
Resolving cblast.gao-lab.org (cblast.gao-lab.org)... 159.138.49.219
Connecting to cblast.gao-lab.org (cblast.gao-lab.org)|159.138.49.219|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 500776712 (478M) [application/octet-stream]
Saving to: ‘Zheng.h5ad’ Zheng.h5ad 100%[===================>] 477.58M 3.85MB/s in 1m 56s 2023-08-31 19:23:23 (4.12 MB/s) - ‘Zheng.h5ad’ saved [500776712/500776712]

ref_adata = ov.utils.read('Zheng.h5ad')
ref_adata
AnnData object with n_obs × n_vars = 91789 × 32643
obs: 'cell_type1', 'lifestage', 'organism', 'dataset_name', 'platform', 'organ', 'data_type', 'cell_ontology_class', 'cell_ontology_id', 'n_genes', 'n_counts', '__libsize__'
var: 'variable_genes'
uns: 'cell_ontology_class_colors', 'cell_type1_colors', 'data_quality', 'known_markers', 'neighbors', 'umap'
obsm: 'X_umap', 'latent'
obsp: 'connectivities', 'distances'

随机选取30,000个细胞的方法,我们使用random.sample进行无放回采样

import random
cell_idx=list(random.sample(ref_adata.obs.index.tolist(),30000))
ref_adata=ref_adata[cell_idx]
ref_adata

View of AnnData object with n_obs × n_vars = 3000 × 2398
obs: 'cell_type1', 'lifestage', 'organism', 'dataset_name', 'platform', 'organ', 'data_type', 'cell_ontology_class', 'cell_ontology_id', 'n_genes', 'n_counts', '__libsize__'
var: 'variable_genes', 'n_cells', 'percent_cells', 'robust', 'mean', 'var', 'residual_variances', 'highly_variable_rank', 'highly_variable_features'
uns: 'cell_ontology_class_colors', 'cell_type1_colors', 'data_quality', 'known_markers', 'neighbors', 'umap', 'log1p', 'hvg'
obsm: 'X_umap', 'latent'
layers: 'counts'
obsp: 'connectivities', 'distances'

ref_adata.obs['cell_ontology_class'].cat.categories

Index(['B cell', 'T-helper 2 cell', 'cytotoxic T cell', 'dendritic cell',
'hematopoietic precursor cell', 'memory T cell', 'monocyte',
'naive thymus-derived CD4-positive, alpha-beta T cell',
'naive thymus-derived CD8-positive, alpha-beta T cell',
'natural killer cell', 'regulatory T cell'],
dtype='object')

我们检查其归一化程度

ref_adata.X.max()

这是一个较大的整数,表明其并未进行归一化,是原始counts,我们对其进行预处理(包括归一化与高可变基因的计算)。

ref_adata=ov.pp.preprocess(ref_adata,mode='shiftlog|pearson',n_HVGs=3000)

Begin robust gene identification
After filtration, 21666/32643 genes are kept. Among 21666 genes, 13971 genes are robust.
End of robust gene identification.
Begin size normalization: shiftlog and HVGs selection pearson
normalizing counts per cell The following highly-expressed genes are not considered during normalization factor computation:
['IGLL5']
finished (0:00:00)
extracting highly variable genes
--> added
'highly_variable', boolean vector (adata.var)
'highly_variable_rank', float vector (adata.var)
'highly_variable_nbatches', int vector (adata.var)
'highly_variable_intersection', boolean vector (adata.var)
'means', float vector (adata.var)
'variances', float vector (adata.var)
'residual_variances', float vector (adata.var)
End of size normalization: shiftlog and HVGs selection pearson

2.2 待注释数据集

我们还是使用之前的骨髓数据集,为了保持我们分析的一致性,但是我们需要从中先提取原始counts,因为我们在2-2的章节中对数据进行了归一化与高可变基因的筛选

adata = ov.utils.read('data/s4d8_manual_annotation.h5ad')
adata=adata.raw.to_adata()
ov.utils.retrieve_layers(adata,layers='counts')
print('raw count adata:',adata.X.max())

......The X of adata have been stored in raw
......The layers counts of adata have been retreved
raw count adata: 889.0

adata=ov.pp.preprocess(adata,mode='shiftlog|pearson',n_HVGs=3000)

Begin robust gene identification
After filtration, 20171/20171 genes are kept. Among 20171 genes, 20171 genes are robust.
End of robust gene identification.
Begin size normalization: shiftlog and HVGs selection pearson
normalizing counts per cell The following highly-expressed genes are not considered during normalization factor computation:
[]
finished (0:00:00)
WARNING: adata.X seems to be already log-transformed.
extracting highly variable genes
--> added
'highly_variable', boolean vector (adata.var)
'highly_variable_rank', float vector (adata.var)
'highly_variable_nbatches', int vector (adata.var)
'highly_variable_intersection', boolean vector (adata.var)
'means', float vector (adata.var)
'variances', float vector (adata.var)
'residual_variances', float vector (adata.var)
End of size normalization: shiftlog and HVGs selection pearson

2.3 高可变基因一致化

我们对ref_adataadata都提取了3000个高可变基因,但是这两个单细胞测序数据的高可变基因不一致,所以我们需要提取相同的高可变基因来进行分析。

#提取高可变基因
ref_adata = ref_adata[:, ref_adata.var.highly_variable_features] #提取共同高可变基因
ref_adata.var_names_make_unique()
adata.var_names_make_unique()
ret_gene=list(set(adata.var_names) & set(ref_adata.var_names))
len(ret_gene)

我们发现参考数据集的高可变基因与目标数据集的共同基因只有2132个,我们可以将前面3000个高可变基因调高来保证取到的高可变基因重复率较高

adata=adata[:,ret_gene]
ref_adata=ref_adata[:,ret_gene]

我们此时再看ref_adata与adata的最大值,发现其都在np.log1p(50*1e4)内,表明二者具有相同的归一化值。

print(f"The max of ref_adata is {ref_adata.X.max()}, query_data is {adata.X.max()}",)

The max of ref_adata is 11.416531562805176, query_data is 10.87752914428711

3. 下载通路注释集

TOSICA作为一个transformer模型,具有多头注意力机制,这意味我们除了注释以外,还可以分析细胞的注意力主要位于什么通路上,所以我们可以将通路数据作为输入给予TOSICA模型。

你可以使用ov.utils.download_tosica_gmt()来自动下载,也可以通过下面的链接手动下载:

当然对于国内的用户,也可以使用百度网盘手动下载

链接:

ov.utils.download_tosica_gmt()

4. 初始化 TOSICA 模型

我们首先需要在 He_Calvarial_Bone 数据集上训练 TOSICA 模型,omicverse 提供了一个简单的 pyTOSICA 类,所有后续操作都可以使用 pyTOSICA 完成。我们需要设置模型初始化的参数。

  • adata:参考 adata 对象
  • gmt_path:默认的预先准备的掩码,或者 .gmt 文件的路径。您可以使用 ov.utils.download_tosica_gmt() 来获取基因集。
  • depth:Transformer 模型的深度,设置为 2 时可能会发生内存泄漏。
  • label_name:在 adata.obs 中表示细胞类型的参考键。
  • project_path:TOSICA 模型的保存路径。
  • batch_size:表示在单次传递中传递给程序进行训练的细胞数量。
tosica_obj=ov.single.pyTOSICA(adata=ref_adata,
gmt_path='genesets/GO_bp.gmt', depth=1,
label_name='cell_ontology_class',
project_path='hGOBP_demo',
batch_size=8)
cuda:0
Mask loaded!

5. 训练 TOSICA 模型

训练 TOSICA 模型时需要设置 4 个参数。

  • pre_weights: 预训练权重的路径。
  • lr: 学习率。
  • epochs:epochs 的个数。
  • lrf: 最后一层的学习率。
tosica_obj.train(epochs=5)

Model builded!

[train epoch 0] loss: 1.300, acc: 0.485: 100%|██████████| 11504/11504 [01:54<00:00, 100.70it/s]
[valid epoch 0] loss: 0.429, acc: 0.817: 100%|██████████| 4930/4930 [00:14<00:00, 330.10it/s]
[train epoch 1] loss: 0.470, acc: 0.807: 100%|██████████| 11504/11504 [01:55<00:00, 100.01it/s]
[valid epoch 1] loss: 0.371, acc: 0.843: 100%|██████████| 4930/4930 [00:14<00:00, 330.79it/s]
[train epoch 2] loss: 0.390, acc: 0.842: 100%|██████████| 11504/11504 [01:54<00:00, 100.11it/s]
[valid epoch 2] loss: 0.338, acc: 0.864: 100%|██████████| 4930/4930 [00:14<00:00, 330.17it/s]
[train epoch 3] loss: 0.332, acc: 0.866: 100%|██████████| 11504/11504 [01:54<00:00, 100.22it/s]
[valid epoch 3] loss: 0.291, acc: 0.881: 100%|██████████| 4930/4930 [00:14<00:00, 330.55it/s]
[train epoch 4] loss: 0.284, acc: 0.888: 100%|██████████| 11504/11504 [01:54<00:00, 100.36it/s]
[valid epoch 4] loss: 0.273, acc: 0.891: 100%|██████████| 4930/4930 [00:14<00:00, 330.70it/s] Training finished!

我们可以使用 .save 来保存 TOSICA模型到 project_path

tosica_obj.save()
tosica_obj.load()

6. 细胞类型预测

在训练好TOSICA模型后,我们将其注释结果迁移到目标数据上

new_adata=tosica_obj.predicted(pre_adata=adata)
0
10000
14814
new_adata.obsm=adata[new_adata.obs.index].obsm.copy()
new_adata.obsp=adata[new_adata.obs.index].obsp.copy()
new_adata
AnnData object with n_obs × n_vars = 14814 × 299
obs: 'Prediction', 'Probability', 'n_genes_by_counts', 'log1p_n_genes_by_counts', 'total_counts', 'log1p_total_counts', 'pct_counts_in_top_20_genes', 'total_counts_mt', 'log1p_total_counts_mt', 'pct_counts_mt', 'total_counts_ribo', 'log1p_total_counts_ribo', 'pct_counts_ribo', 'total_counts_hb', 'log1p_total_counts_hb', 'pct_counts_hb', 'outlier', 'mt_outlier', 'scDblFinder_score', 'scDblFinder_class', 'leiden_res1', 'major_celltype', 'manual_celltype', 'minor_celltype'
obsm: 'X_mde', 'scaled|original|X_pca'
obsp: 'connectivities', 'distances'
ov.utils.embedding(
new_adata,
basis="X_mde",
color=['major_celltype', 'Prediction'],
frameon='small',
#ncols=1,
wspace=0.5,
#palette=ov.utils.pyomic_palette()[11:],
show=False,
)

我们可以看见,其注释效果一般,这是由于我们是用PBMC外周血的细胞类型进行迁移,而不是使用骨髓数据进行迁移。所以参考数据集的选取对于注释准确率的影响非常大,一般我们手动注释一个样本然后进行迁移的准确率是最高的。

7. 注意力机制

transformer作为一个注意力模型,我们可以找到每一类细胞注意力集中的通路,这听起来有点类似通路富集。我们首先将预测细胞类型数量小于5的细胞给过滤掉。

cell_idx=new_adata.obs['Prediction'].value_counts()[new_adata.obs['Prediction'].value_counts()<5].index
new_adata=new_adata[~new_adata.obs['Prediction'].isin(cell_idx)]

然后,我们使用 sc.tl.rank_genes_groups 计算出各细胞类型中注意力最高的差异通路。这种差异通路来源于之前计算所用的 gmt 基因组。

sc.tl.rank_genes_groups(new_adata, 'Prediction', method='wilcoxon')

ranking genes
finished: added to `.uns['rank_genes_groups']`
'names', sorted np.recarray to be indexed by group ids
'scores', sorted np.recarray to be indexed by group ids
'logfoldchanges', sorted np.recarray to be indexed by group ids
'pvals', sorted np.recarray to be indexed by group ids
'pvals_adj', sorted np.recarray to be indexed by group ids (0:00:00)

sc.pl.rank_genes_groups_dotplot(new_adata,
n_genes=3,standard_scale='var',)

如果想获取特定细胞的通路,可以使用 sc.get.rank_genes_groups_df 来获取。

例如,我们想获得细胞类型 B细胞 注意力最高的通路

degs = sc.get.rank_genes_groups_df(new_adata, group='B cell', key='rank_genes_groups',pval_cutoff=0.05)
degs.head()

我们发现注意力最高的通路是GOBP_REGULATION_OF_PROTEIN_BINDING,我们在umap图上观察通路的注意力情况,发现其确实位于B细胞区域

ov.utils.embedding(
new_adata,
basis="X_mde",
color=['Prediction','GOBP_REGULATION_OF_PROTEIN_BINDING'],
frameon='small',
#ncols=1,
wspace=0.5,
#palette=ov.utils.pyomic_palette()[11:],
show=False,
)

单细胞测序最好的教程(十):细胞类型注释迁移|万能的Transformer的更多相关文章

  1. 基于单细胞测序数据构建细胞状态转换轨迹(cell trajectory)方法总结

    细胞状态转换轨迹构建示意图(Trapnell et al. Nature Biotechnology, 2014) 在各种生物系统中,细胞都会展现出一系列的不同状态(如基因表达的动态变化等),这些状态 ...

  2. 单细胞测序技术(single cell sequencing)

    单细胞测序技术(single cell sequencing) 2018-03-02 11:02   来源: 一呼百诺  点击次数:6587关键词:   前言 单细胞生物学最近几年是非常热门的研究方向 ...

  3. 单细胞测序|单细胞基因组|单细胞转录组|Gene editing|

    单细胞测序 单细胞基因组学 测量理由是单细胞的时间空间特异性. Gene expression&co-expression 比较正常cell与疾病cell,正常organ与疾病organ,看出 ...

  4. 无废话ExtJs 入门教程十九[API的使用]

    无废话ExtJs 入门教程十九[API的使用] extjs技术交流,欢迎加群(201926085) 首先解释什么是 API 来自百度百科的官方解释:API(Application Programmin ...

  5. Unity3D脚本中文系列教程(十六)

    Unity3D脚本中文系列教程(十五) ◆ function OnPostprocessAudio (clip:AudioClip):void 描述:◆  function OnPostprocess ...

  6. Unity3D脚本中文系列教程(十五)

    http://dong2008hong.blog.163.com/blog/static/4696882720140322449780/ Unity3D脚本中文系列教程(十四) ◆ LightRend ...

  7. [转]PostgreSQL教程(十六):系统视图详解

    这篇文章主要介绍了PostgreSQL教程(十六):系统视图详解,本文讲解了pg_tables.pg_indexes.pg_views.pg_user.pg_roles.pg_rules.pg_set ...

  8. RabbitMQ入门教程(十四):RabbitMQ单机集群搭建

    原文:RabbitMQ入门教程(十四):RabbitMQ单机集群搭建 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://b ...

  9. 答读者问(1):非模式物种找marker;如何根据marker定义细胞类型

    下午花了两个小时回答读者的疑问,觉得可以记录下来,也许能帮到一部分人. 第一位读者做的是非模式物种的单细胞. 一开始以为是想问我非模式物种的marker基因在哪儿找,读者朋友也提到了blast 研究的 ...

  10. CRL快速开发框架系列教程十二(MongoDB支持)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

随机推荐

  1. 2024盘古石取证比赛(IPA+人工智能)

    前言 题目列表 IPA部分 1. 分析毛雪柳的手机检材,记账 APP 存储记账信息的数据库文件名称是: [ 答案格式:tmp.db ,区分大小写 ][ ★★★★☆ ] 通过icost软件可以定位rae ...

  2. 7.12考试总结(NOIP模拟12)[简单的区间·简单的玄学·简单的填数]

    即使想放弃,也没法放弃最想要的东西,这就是人 前言 这次应该是和 SDFZ 一起打的第一场比赛吧. 然而我还是 FW 一个... 这次考试也有不少遗憾,主要的问题是码力不足,不敢去直面正解,思考程度不 ...

  3. js 实现简易时钟效果

    大江东去,浪淘尽,千古风流人物.故垒西边,人道是,三国周郎赤壁.乱石穿空,惊涛拍岸,卷起千堆雪.江山如画,一时多少豪杰.遥想公瑾当年,小乔初嫁了,雄姿英发.羽扇纶巾,谈笑间,樯橹灰飞烟灭.故国神游,多 ...

  4. Redisson 限流器源码分析

    Redisson 限流器源码分析 对上篇文章网友评论给出问题进行解答:redis 的key 是否会过期 可以先阅读上篇文章: redis + AOP + 自定义注解实现接口限流 - 古渡蓝按 - 博客 ...

  5. 《python核心编程《第二版》》笔记章节索引

    本文章作为我的其它一系列关于<python核心编程<第二版>>的笔记的文章索引. 第一章:Python-快速入门:https://www.cnblogs.com/mrlayfo ...

  6. 类的阐述 package(包)

    类的阐述 同一个文件中可以定义很多类 编译后,每个类都会生成独立的.class文件 一个类中,只能有一个主函数,每个类都可以有自己的主函数 public修饰的类称为公开类,要求类名必须与文件名称完全相 ...

  7. minos 0 前(废)言(话)

    - 首发公号:Rand_cs minos 0 前(废)言(话) 从今天开始开启一个新的系列,讲述虚拟化的那些事儿.时隔上次发文又隔了好几个月了,主要是平时工作比较忙,没太多时间精力维护博客之类的. 前 ...

  8. 喜讯!INFINI Easysearch 在墨天轮搜索型数据库排名中荣登榜首

    近日,2023 年 9 月的 墨天轮中国数据库流行度排行 火热出炉,本月共有 287 个数据库参与排名,中国数据库行业竞争日益激烈.其中,极限科技旗下软件产品 INFINI Easysearch 在 ...

  9. Java中PDF的转换(图片)与展示

    解决的问题 有些时候我们需要在项目中展示PDF,但是直接在浏览器中加入PDF展示的插件,存在兼容性问题,某些浏览器显示效果不理想,所以我们可以将PDF转为图片,然后已图片的方式展示,效果很好. 那么怎 ...

  10. idea如何快速找到项目中待处理的TODO注释

    idea如何快速找到项目中待处理的TODO注释 idea菜单栏 View -> Tool Windows,可以打开TODO窗口