
knowledge-work-plugins scvi-tools 技能详解基于 scVI 与 scANVI 的单细胞转录组批次效应校正与数据集整合实战【免费下载链接】knowledge-work-pluginsOpen source repository of plugins primarily intended for knowledge workers to use in Claude Cowork项目地址: https://gitcode.com/GitHub_Trending/kn/knowledge-work-plugins导读本文是 bio-research/skills/scvi-tools 技能中「scRNA-seq 整合scrna_integration」参考文档的深度展开系统讲解如何用 scVI无监督与 scANVI半监督、利用细胞类型标签实现单细胞转录组数据的批次效应去除与跨数据集整合。读者将掌握从数据预处理、HVG 选择、模型训练、隐空间提取到整合质量评估、差异表达分析的完整实操链路并学会复用仓库中scripts/下的命令行脚本如 integrate_datasets.py以最小化重复编码。背景单细胞数据为何需要整合单细胞测序数据几乎必然携带批次效应batch effects来源包括不同的供体/患者donor/patient不同的实验批次experimental batch不同的测序技术如 10x v2 与 v3不同的研究study之间采集与建库差异。scVI 与 scANVI 通过变分自编码器VAE学习一个共享隐空间shared latent space在该空间中批次效应被去除同时生物变异细胞类型差异得以保留。后续的聚类、UMAP 可视化、细胞类型标注与差异表达都可以基于这个干净的隐空间进行。模型选型scVI 还是 scANVI模型适用场景是否需要标签scVI无标签可用、探索性分析不需要scANVI已有部分/全部标签希望更好地保留生物学结构需要允许部分标注从 SKILL.md 的快速决策树也可以看到无标签 → 走 scVI有细胞类型标签且要做整合/标签迁移 → 走 scANVI。scANVI 本质上是 scVI 的扩展先训练 scVI再以细胞类型标签做半监督微调从而在去批次的同时用标签约束隐空间减少“过度校正”导致的生物学信号丢失。scVI 无监督整合工作流Step 1准备数据拼接与原始计数import scvi import scanpy as sc # Load datasets adata1 sc.read_h5ad(dataset1.h5ad) adata2 sc.read_h5ad(dataset2.h5ad) # Add batch annotation adata1.obs[batch] batch1 adata2.obs[batch] batch2 # Concatenate adata sc.concat([adata1, adata2], labelbatch) # Ensure we have raw counts # If data is normalized, recover from .raw if hasattr(adata, raw) and adata.raw is not None: adata adata.raw.to_adata() # Store counts adata.layers[counts] adata.X.copy()关键约束scvi-tools 的所有模型都要求整数原始计数raw integer counts而不是归一化后的浮点数据。因此必须在使用sc.pp.normalize_total等归一化之前先把原始计数存进adata.layers[counts]。仓库中的 data_preparation.md 给出了更完整的检验方法import numpy as np # X dtype 与整数性检查 print(fX dtype: {adata.X.dtype}) print(fX contains integers: {np.allclose(adata.X.data, adata.X.data.astype(int))})仓库的 validate_adata.py 会在数据非整数时报错Data does not contain integers (raw counts required)并推荐通过adata.raw.to_adata()恢复原始计数或显式指定包含原始计数的 layer。Step 2跨批次 HVG 选择# Select HVGs considering batch sc.pp.highly_variable_genes( adata, n_top_genes2000, flavorseurat_v3, batch_keybatch, layercounts ) # Subset to HVGs adata adata[:, adata.var[highly_variable]].copy()多批次数据推荐使用flavorseurat_v3并传入batch_key这样选出的高变基因是在各批次间都稳定的基因而不是被某个批次单独驱动的基因layercounts保证 HVG 选择基于原始计数。HVG 数量经验范围是 20004000见 data_preparation.md。值得注意scVI 训练本身并不强制要求 HVG但合理筛选能显著降低显存占用与训练时间并常带来更稳定的整合结果。Step 3注册数据并训练 scVI# Register data with scVI scvi.model.SCVI.setup_anndata( adata, layercounts, batch_keybatch ) # Create model model scvi.model.SCVI( adata, n_latent30, # Latent dimensions n_layers2, # Encoder/decoder depth gene_likelihoodnb # negative binomial (or zinb) ) # Train model.train( max_epochs200, early_stoppingTrue, early_stopping_patience10, batch_size128 ) # Plot training history model.history[elbo_train].plot()setup_anndata()是 scvi-tools 1.x 的核心 API0.x 中是scvi.data.setup_anndata已弃用它将countslayer 与batch列注册进模型。gene_likelihood决定基因表达的概率分布nb负二项分布是 scRNA-seq 的标准选择zinb零膨胀负二项适合额外建模过高比例的 dropout。若数据中存在大量全零细胞/基因会导致 NaN 损失需先过滤。仓库中的 train_model.py 将上述过程封装为可直接复用的函数train_scvi(adata, batch_key, n_latent, n_layers, max_epochs)默认开启early_stoppingTrue, early_stopping_patience10并在训练后把隐表示写入adata.obsm[X_scVI]、保存模型与训练曲线图。Step 4提取整合表示并聚类可视化# Get latent representation adata.obsm[X_scVI] model.get_latent_representation() # Use for clustering and visualization sc.pp.neighbors(adata, use_repX_scVI, n_neighbors15) sc.tl.umap(adata) sc.tl.leiden(adata, resolution1.0) # Visualize integration sc.pl.umap(adata, color[batch, leiden], ncols2)注意这里的 UMAP/Leiden 都是基于X_scVI隐表示而非原始基因表达或 PCA。若隐表示缺失cluster_embed.py 会自动按[X_scANVI, X_scVI, X_totalVI, X_PeakVI, X_MultiVI]的顺序探测可用表示全部缺失时回退到 PCA。Step 5保存与加载模型# Save model for later use model.save(scvi_model/) # Load model model scvi.model.SCVI.load(scvi_model/, adataadata)加载时必须传入与训练时一致的adata至少包含相同的基因集与 batch 信息因为模型的解码器维度与基因数绑定。scANVI 半监督整合工作流scANVI 在 scVI 基础上引入细胞类型标签用于更好地保留生物学结构也支持把标签从标注细胞迁移到未标注细胞。Step 1准备带标签的数据# Labels should be in adata.obs # Use Unknown for unlabeled cells print(adata.obs[cell_type].value_counts()) # For partially labeled data # Mark unlabeled cells adata.obs[cell_type_scanvi] adata.obs[cell_type].copy() # adata.obs.loc[unlabeled_mask, cell_type_scanvi] UnknownscANVI 天然支持部分标注未标注的细胞统一标记为Unknown模型会对这部分细胞做标签预测见 Step 3 的predict()。Step 2 Option A从头训练 scANVI# Setup for scANVI scvi.model.SCANVI.setup_anndata( adata, layercounts, batch_keybatch, labels_keycell_type ) # Create model scanvi_model scvi.model.SCANVI( adata, n_latent30, n_layers2 ) # Train scanvi_model.train(max_epochs200)Step 2 Option B从 scVI 初始化 scANVI推荐# First train scVI scvi.model.SCVI.setup_anndata(adata, layercounts, batch_keybatch) scvi_model scvi.model.SCVI(adata, n_latent30) scvi_model.train(max_epochs200) # Initialize scANVI from scVI scanvi_model scvi.model.SCANVI.from_scvi_model( scvi_model, labels_keycell_type, unlabeled_categoryUnknown # For partially labeled data ) # Fine-tune scANVI (fewer epochs needed) scanvi_model.train(max_epochs50)Option B 是文档推荐的路径也是仓库脚本的默认实现先让无监督的 scVI 收敛到合理的隐空间再叠加标签监督做微调。微调阶段只需少量 epoch仓库实现中为max_epochs // 4如 200 → 50因为模型已经接近解空间。注意from_scvi_model要求传入的 scVI 模型基于同一份adata且labels_key列必须存在于adata.obs。Step 3获取结果隐表示 标签预测# Latent representation adata.obsm[X_scANVI] scanvi_model.get_latent_representation() # Predicted labels for unlabeled cells predictions scanvi_model.predict() adata.obs[predicted_cell_type] predictions # Prediction probabilities soft_predictions scanvi_model.predict(softTrue) # Visualization sc.pp.neighbors(adata, use_repX_scANVI) sc.tl.umap(adata) sc.pl.umap(adata, color[batch, cell_type, predicted_cell_type])predict()返回每个细胞最可能的细胞类型softTrue返回概率矩阵可用于评估预测置信度。predicted_cell_type是 scANVI 完成标签迁移label transfer的直观产出也是 integrate_datasets.py 中plot_integration()自动识别的绘图列之一。整合质量评估视觉评估整合前后对比import matplotlib.pyplot as plt fig, axes plt.subplots(1, 3, figsize(15, 4)) # Before integration (on PCA) sc.pp.pca(adata) sc.pl.pca(adata, colorbatch, axaxes[0], titleBefore (PCA), showFalse) # After scVI sc.pp.neighbors(adata, use_repX_scVI) sc.tl.umap(adata) sc.pl.umap(adata, colorbatch, axaxes[1], titleAfter scVI, showFalse) # After scANVI sc.pp.neighbors(adata, use_repX_scANVI) sc.tl.umap(adata) sc.pl.umap(adata, colorbatch, axaxes[2], titleAfter scANVI, showFalse) plt.tight_layout()评估标准好的整合 各批次充分混合按 batch 着色无明显分群同时细胞类型结构保持按 cell_type/leiden 着色依然清晰。只满足前者可能是过度校正。定量指标scib-metrics# pip install scib-metrics from scib_metrics.benchmark import Benchmarker bm Benchmarker( adata, batch_keybatch, label_keycell_type, embedding_obsm_keys[X_pca, X_scVI, X_scANVI] ) bm.benchmark() bm.plot_results_table()embedding_obsm_keys同时传入 PCA整合前基线与 scVI/scANVI 隐表示即可横向对比整合前后及不同模型的 batch mixing 与 bio conservation 指标。仓库 model_utils.py 还提供了一套轻量自实现evaluate_integration()计算silhouette_label越高越好、silhouette_batch越低越好与基于 50 近邻的batch_mixingcompare_integrations()则用silhouette_label - silhouette_batch给出综合的integration_score适合在不引入额外依赖时快速横向比较多种嵌入。差异表达分析batch 感知scVI 的differential_expression基于生成模型推断天然扣除批次效应适合在整合后的隐空间模型上直接做组间差异分析# DE between groups de_results model.differential_expression( groupbycell_type, group1T cells, group2B cells ) # Filter significant de_sig de_results[ (de_results[is_de_fdr_0.05] True) (abs(de_results[lfc_mean]) 1) ] print(de_sig.head(20))结果列中is_de_fdr_0.05是 FDR 0.05 的显著性标记lfc_mean是平均 log2 倍数变化bayes_factor是贝叶斯因子也常作为排序依据。仓库的 differential_expression.py 封装了该能力支持三种用法# 一键对全部 cluster 做 one-vs-rest DE python scripts/differential_expression.py model/ adata.h5ad de_results.csv --groupby leiden # 指定两组比较 python scripts/differential_expression.py model/ adata.h5ad de_results.csv \ --groupby cell_type --group1 T cells --group2 B cells # 每个 cluster 只保留 top 50 python scripts/differential_expression.py model/ adata.h5ad de_results.csv \ --groupby leiden --n-genes 50 --plot其中--plot会额外生成火山图Volcano plot。model_utils.py 的get_marker_genes()则基于lfc_mean 0.5过滤并按lfc_mean降序提取每个群体的标记基因。进阶多分类协变量除batch_key外scVI 支持把donor、technology等更多分类变量作为协变量注册# Include additional covariates beyond batch scvi.model.SCVI.setup_anndata( adata, layercounts, batch_keybatch, categorical_covariate_keys[donor, technology] ) model scvi.model.SCVI(adata, n_latent30) model.train()典型用法是把供体donor作为额外分类协变量吸收batch只保留实验/技术层面的差异也可传入连续协变量continuous_covariate_keys如percent_mito详见 data_preparation.md。训练调优建议大数据集100k 细胞model.train( max_epochs100, # Fewer epochs needed batch_size256, # Larger batches train_size0.9, # Less validation early_stoppingTrue )大数据集收敛更快epoch 数可以缩减同时增大 batch size 以充分利用 GPU 吞吐。小数据集10k 细胞model scvi.model.SCVI( adata, n_latent10, # Smaller latent space n_layers1, # Simpler model dropout_rate0.2 # More regularization ) model.train( max_epochs400, batch_size64 )小数据集容易过拟合减小隐维度、减浅网络、提高 dropout 正则并适当增加 epoch。仓库 validate_adata.py 会在细胞数 1000 时给出警告提示深度学习模型在 5000 细胞时效果更稳。监控训练# Check training curves import matplotlib.pyplot as plt fig, ax plt.subplots() ax.plot(model.history[elbo_train], labelTrain) ax.plot(model.history[elbo_validation], labelValidation) ax.set_xlabel(Epoch) ax.set_ylabel(ELBO) ax.legend() # Should see convergence without overfitting理想曲线是训练与验证 ELBO 均单调收敛若验证曲线回升变差说明开始过拟合early stopping 会自动截断。仓库 model_utils.py 的plot_training_history()在 ELBO 之外还会绘制 reconstruction loss 曲线train_model.py 训练结束即自动保存training_history.png。完整整合管线可复用函数参考文档给出了一个完整的integrate_datasets()函数多数据集拼接 → HVG → scVI/scANVI 自动选型 → 隐表示 → 聚类仓库 integrate_datasets.py 将其扩展为生产级 CLI。函数签名与用法def integrate_datasets( adatas, batch_keybatch, labels_keyNone, n_top_genes2000, n_latent30 ): Integrate multiple scRNA-seq datasets. ... # 逐数据集打 batch 标签 - sc.concat 拼接 - 存 counts layer # - seurat_v3 batch_key 选 HVG - 按标签有无走 scANVI/scVI # - 写 X_scANVI / X_scVI - neighbors UMAP leiden return adata, model # Usage adatas { study1: sc.read_h5ad(study1.h5ad), study2: sc.read_h5ad(study2.h5ad), study3: sc.read_h5ad(study3.h5ad) } adata_integrated, model integrate_datasets( adatas, labels_keycell_type ) sc.pl.umap(adata_integrated, color[batch, leiden, cell_type])而仓库脚本integrate_datasets.py额外做了三件文档未覆盖的事体现了“实战可用”的完备性基因交集处理拼接前先对所有数据集取var_names交集common_genes避免不同研究间基因集不一致导致拼接错位batch 命名校验--batch-names数量必须与数据集数量一致否则抛ValueError完整产物落盘训练后自动保存integrated.h5ad、模型目录与integration.png拼图。其完整 CLI 用法# 基础整合自动分配 dataset_0, dataset_1, ... python scripts/integrate_datasets.py results/ data1.h5ad data2.h5ad data3.h5ad # 自定义批次名 python scripts/integrate_datasets.py results/ *.h5ad --batch-names ctrl,treat1,treat2 # 带细胞类型标签自动走 scANVI python scripts/integrate_datasets.py results/ *.h5ad --labels-key cell_type # 其他参数--n-hvgs 2000 --n-latent 30 --max-epochs 200端到端 CLI 工作流仓库 SKILL.md 把参考文档的每个步骤映射为独立脚本可串联成一条不写 Python 代码的完整流程# 1. 校验输入数据整数计数、batch 列、HVG、batch 规模--suggest 给出模型建议 python scripts/validate_adata.py raw.h5ad --batch-key batch --suggest # 2. 数据准备QC 过滤 HVG 选择 counts layer python scripts/prepare_data.py raw.h5ad prepared.h5ad --batch-key batch --n-hvgs 2000 # 3. 训练模型scvi / scanvi 等由 --model 决定 python scripts/train_model.py prepared.h5ad results/ --model scvi --batch-key batch # 4. 在隐空间上聚类与可视化 python scripts/cluster_embed.py results/adata_trained.h5ad results/ --resolution 0.8 # 5. 差异表达 python scripts/differential_expression.py results/model results/adata_clustered.h5ad results/de.csv --groupby leiden其中validate_adata.py的校验报告会覆盖数据是否为整数计数、是否含 NaN/负值、稀疏度、batch 数量仅 1 个 batch 时警告无需校正、50 细胞的 batch 建议合并、标签稀有度30 细胞的类型提示学习不充分、HVG 数量推荐 20004000等是进入训练前最有价值的“体检”步骤。常见问题排查问题原因解决方案批次不混合共有基因太少增加 HVG 数量检查各数据集基因重叠过度校正生物学变异被误删改用带标签的 scANVI训练发散学习率过高降低 lr增大 batch_sizeNaN loss数据质量差检查并过滤全零细胞/基因内存不足细胞数过多减小 batch_size使用 GPU从源码看train_model.py 的train_scvi与 model_utils.py 的train_scvi仓库脚本统一采用early_stoppingTruepatience10的组合能在一定程度上自动规避训练发散与过拟合而 NaN loss 的根本预防在于训练前用validate_adata.py排除全零细胞与 NaN。环境与 GPU 相关的坑CUDA 版本不匹配、PyTorch 与 CUDA 对应关系、显存不足可进一步参考 environment_setup.md。小结以 scrna_integration.md 为核心本技能提供了一条从「原始 h5ad 多数据集」到「干净隐空间 聚类 DE 结果」的完整整合链路无标签探索选 scVI有部分标签选 scANVI推荐从 scVI 初始化再微调用setup_anndata注册countslayer 与batch_key在X_scVI/X_scANVI隐表示上完成聚类与可视化并以 scib-metrics 或 silhouette 指标量化整合质量。仓库scripts/下 7 个脚本validate_adata→prepare_data→train_model→cluster_embed→differential_expression可将整条流程无代码落地而model_utils.py的函数级 API 则适合在自定义 Notebook 管线中直接调用。【免费下载链接】knowledge-work-pluginsOpen source repository of plugins primarily intended for knowledge workers to use in Claude Cowork项目地址: https://gitcode.com/GitHub_Trending/kn/knowledge-work-plugins创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考