跳至章节信息跳至正文
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

降维

🧠 关键要点
⚙️ 环境设置
步骤
yml
  1. 安装 conda:

    • 在创建环境之前,请确保 conda 已安装在你的系统中。

  2. 保存 yml 内容:

    • 将 yml 选项卡中的内容保存为文件 environment.yml。

  3. 创建环境:

    • 打开终端或命令提示符。

    • 运行以下命令:

      conda env create -f environment.yml
  4. 激活环境:

    • 创建好环境后,使用以下命令激活它:

      conda activate <environment_name>
    • 请将 <environment_name> 替换为 environment.yml 文件中指定的环境名称。该名称在 yml 文件中如下所示:

      name: <environment_name>
  5. 验证安装:

    • 通过运行以下命令,检查环境是否创建成功:

      conda env list
🗄️ 获取数据和笔记本

本书使用 lamindb 存储、共享和加载数据集与笔记本,托管实例为 theislab/sc-best-practices。感谢提供免费托管的 Lamin Labs。

  1. 安装 lamindb

    • 安装 lamindb Python 软件包:

    pip install lamindb
  2. 可选择创建 Lamin 账户

  3. 验证你的设置

    • 下面用 Python API 检查连接;命令行方式可使用 lamin connect:

    import lamindb as ln
    
    ln.Artifact.connect("theislab/sc-best-practices").df()

    运行后应显示最多 100 条已保存的数据集记录。

  4. 访问数据集(Artifact)

    import lamindb as ln
    af = ln.Artifact.connect("theislab/sc-best-practices").get(key="key_of_dataset", is_latest=True)
    obj = af.load()

    加载后的对象可直接在内存中分析。如需指定数据版本,可调整 lamindb.Artifact.connect("theislab/sc-best-practices").get("SOMEIDXXXX") 中的 ID。

  5. 访问笔记本(Transform)

    lamin load <notebook url>

    该命令将笔记本下载到当前工作目录。与 Artifacts 类似,可通过指定 ID 获取旧版本。

研究动机

表面蛋白的特征(feature)矩阵难以直接用表格理解,可通过降维(dimensionality reduction)构建通常为二维的嵌入(Embedding),展示抗体衍生标签(Antibody-Derived Tags, ADTs)数据。本章使用与 RNA 分析类似的方法,包括统一流形逼近与投影(Uniform Manifold Approximation and Projection, UMAP)。t 分布随机邻域嵌入(t-distributed stochastic neighbor embedding, t-SNE)、UMAP 的可视化局限同样适用:图中群体的距离、面积或分离程度不能直接等同于生物学差异大小。

ADT 面板中的 feature 通常已在实验设计时 预先 选定,因此常不需要复杂的高变 feature 筛选,但仍应去除不适用于下游分析的对照或低质量标记。对于含数百个蛋白或细胞较多的数据,可用主成分分析(Principal Component Analysis, PCA)压缩维度,降低近邻计算成本。

本章及随后的批次校正(batch correction)、注释章节聚焦 ADT。联合使用 RNA 与 ADT 的方法见 配对整合,两种模态可为更细致的细胞注释提供互补信息。

环境设置

import warnings

import muon as mu
import scanpy as sc

warnings.filterwarnings("ignore")
sc.settings.verbosity = 0
sc.set_figure_params(
    dpi=80,
    facecolor="white",
    frameon=False,
)

import lamindb as ln

ln.track()
→ connected lamindb: theislab/sc-best-practices
→ found notebook dimensionality_reduction.ipynb, making new version -- anticipating changes
→ created Transform('liGMVGre4G5H0008', key='dimensionality_reduction.ipynb'), started new Run('aPuKLGSFDouWhxAx') at 2026-07-29 11:09:07 UTC
→ notebook imports: lamindb-core==2.3.1 muon==0.1.9 scanpy==1.12.3
• recommendation: to identify the notebook across renames, pass the uid: ln.track("liGMVGre4G5H")

加载数据

加载前一章保存的 MuData 对象,参见 Doublet 检测:

af = ln.Artifact.connect("theislab/sc-best-practices").get(
    key="surface-protein/cite_doublet_detection.h5mu", is_latest=True
)
mdata = af.load()
mdata
Loading...

本例后续步骤不再使用原始 Count,因此删除当前对象中的 counts 层。若需要回查或重新归一化(normalization),仍应保留前面保存的原始数据文件。

del mdata["prot"].layers["counts"]

同型对照(isotype controls)主要用于估计非特异性背景,不作为目标蛋白参与本例的生物学降维。它们在 背景去噪与缩放(denoised and scaled by background, dsb) 中的用途见 归一化 章节;完成该步骤后,从用于降维的蛋白集合中移除这些对照。

mdata["prot"].var.index[:50]
Index(['CD86-1', 'CD274-1', 'CD270', 'CD155', 'CD112', 'CD47-1', 'CD48-1', 'CD40-1', 'CD154', 'CD52-1', 'CD3', 'CD8', 'CD56', 'CD19-1', 'CD33-1', 'CD11c', 'HLA-A-B-C', 'CD45RA', 'CD123', 'CD7-1', 'CD105', 'CD49f', 'CD194', 'CD4-1', 'CD44-1', 'CD14-1', 'CD16', 'CD25', 'CD45RO', 'CD279', 'TIGIT-1', 'Mouse-IgG1', 'Mouse-IgG2a', 'Mouse-IgG2b', 'Rat-IgG2b', 'CD20', 'CD335', 'CD31', 'Podoplanin', 'CD146', 'IgM', 'CD5-1', 'CD195', 'CD32', 'CD196', 'CD185', 'CD103', 'CD69-1', 'CD62L', 'CD161'], dtype='object')
isotype_controls = ["Mouse-IgG1", "Mouse-IgG2a", "Mouse-IgG2b", "Rat-IgG2b"]
temp = (
    mdata["prot"].var.loc[~mdata["prot"].var.index.isin(isotype_controls), :].index
)  # Select all proteins except isotype controls.

应用上述蛋白列表,去除同型对照。

mu.pp.filter_var(data=mdata["prot"], var=temp.tolist())

过滤后的蛋白模态不再包含这些同型对照。

mdata["prot"]
AnnData object with n_obs × n_vars = 105907 × 136 obs: 'donor', 'batch', 'n_genes_by_counts', 'log1p_n_genes_by_counts', 'total_counts', 'log1p_total_counts', 'n_genes', 'n_counts', 'outliers', 'doublets_markers' var: 'gene_ids', 'feature_types', 'n_cells_by_counts', 'mean_counts', 'log1p_mean_counts', 'pct_dropout_by_counts', 'total_counts', 'log1p_total_counts' uns: 'doublets_markers_colors'

PCA 与 UMAP

当前保留 136 个蛋白标记,下面使用 PCA 构建低维表示。

sc.pp.pca(mdata["prot"], svd_solver="arpack", random_state=0)

绘制各主成分(Principal Components, PCs)的解释方差比,参考肘部位置选择保留数量:

sc.pl.pca_variance_ratio(mdata["prot"], n_pcs=50)
<Figure size 320x320 with 1 Axes>

本例保留前 20 个 PC;图中后续主成分的方差贡献较小。这是结合该数据作出的选择,并非固定规则。接着基于这些 PC 构建邻接图,再计算 UMAP 以展示细胞。

sc.pp.neighbors(mdata["prot"], n_pcs=20, random_state=0)
sc.tl.umap(mdata["prot"], random_state=0)

二维 Embedding 可按供体和批次着色,用于初步检查批次效应(batch effect)。群体分离可能来自技术因素,也可能包含供体间真实生物学差异,需要结合标记和实验设计判断。

sc.pl.umap(mdata["prot"], color=["donor", "batch"])
<Figure size 772.8x320 with 2 Axes>

本例部分供体和批次的细胞形成分离群体,提示需要进一步评估批次校正。先绘制 CD3、CD4 和 CD8,检查已知 T 细胞群体的分布。

sc.pl.umap(mdata["prot"], color=["CD4-1", "CD8", "CD3"])
<Figure size 1159.2x320 with 6 Axes>

CD4 T 细胞分成多个供体相关的小群体,提示供体因素影响了表示。若分析目标是跨供体识别共有细胞类型,可尝试校正技术差异;但不能假定所有供体差异都是批次效应,也不应强行消除真实细胞状态差异。

af_dimensionality_reduction = ln.Artifact.from_mudata(
    mdata,
    key="surface-protein/cite_dimensionality_reduction.h5mu",
    description="CITE-seq data after dimensionality reduction",
)
af_dimensionality_reduction.save()
输出
→ creating new artifact version for key 'surface-protein/cite_dimensionality_reduction.h5mu' in storage 's3://lamin-eu-central-1/VPwcjx3CDAa2'
... uploading 9DWigMKiH7zGL1jy0005.h5mu:  0.0%
... uploading 9DWigMKiH7zGL1jy0005.h5mu: 100.0%
• replacing the existing cache path /var/cache/user/marchena/.cache/lamindb/lamin-eu-central-1/VPwcjx3CDAa2/surface-protein/cite_dimensionality_reduction.h5mu
Artifact(uid='9DWigMKiH7zGL1jy0005', key='surface-protein/cite_dimensionality_reduction.h5mu', description='CITE-seq data after dimensionality reduction', suffix='.h5mu', kind='dataset', otype='MuData', size=1406205468, hash='xlfiRsibE4hRwwkE6fVkTq', n_files=None, n_observations=105907, branch_id=1, created_on_id=1, space_id=1, storage_id=1, run_id=113, schema_id=None, created_by_id=7, created_at=2026-07-29 11:10:27 UTC, is_locked=False, version_tag=None, is_latest=True)
ln.finish()
输出
• please hit CTRL + s to save the notebook in your editor .... still waiting .....
.................. ✓
! returning transform  with same hash & key: Transform(uid='liGMVGre4G5H0007', key='dimensionality_reduction.ipynb', description='Dimensionality Reduction', kind='notebook', hash='9AXoWZ-LnjdIoeh_N7xjtQ', reference=None, reference_type=None, environment=None, plan=None, branch_id=1, created_on_id=1, space_id=1, created_by_id=7, created_at=2026-07-29 10:31:37 UTC, is_locked=False, version_tag=None, is_latest=False)
• new latest Transform version is: liGMVGre4G5H0007
→ finished Run('aPuKLGSFDouWhxAx') after 2m at 2026-07-29 11:11:09 UTC
→ go to: https://lamin.ai/theislab/sc-best-practices/transform/liGMVGre4G5H0007
→ to update your notebook from the CLI, run: lamin save /groups/nils/members/javier/single-cell-best-practices/jupyter-book/surface_protein/dimensionality_reduction.ipynb

贡献者

我们衷心感谢以下人员的贡献:

作者

  • Javier Marchena-Hurtado

  • Daniel Strobl

  • Ciro Ramírez-Suástegui

审阅者

  • Lukas Heumos

  • Anna Schaar