mcpField
C
cell-type-annotation

cell-type-annotation

github.com/awslabsデータ・データベース6877 回インストール4 週間前に更新
リポジトリ

cell-type-annotation について

クラスタリング済みの AnnData または SingleCellExperiment を扱うユーザー向けの、シングルセル RNA-seq 細胞型アノテーションのパイプラインスキルです。自動、参照ベース、マーカー遺伝子、階層的な手法を案内し、信頼度の確認と検証も扱います。

主な機能

  1. 01CellTypistによる自動アノテーションの案内
  2. 02参照データからのラベル転送
  3. 03マーカー遺伝子による細胞型判定
  4. 04階層的なラベルの細分化
  5. 05信頼度の確認とラベルの検証

活用シーン

  1. 01クラスタリング済みシングルセルRNA-seqデータの注釈
  2. 02参照アトラスからの細胞ラベル転送
  3. 03不確かな細胞型判定の確認
  4. 04大分類ラベルからサブタイプへの細分化

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/awslabs/hcls-agent-skills --skill cell-type-annotation

インストール後、Claude Code で/cell-type-annotationを入力して読み込まれたか確認します。

詳細

細胞型アノテーション

概要

このパイプラインスキルは、シングルセル RNA-seq データの細胞型をアノテーションするコードを生成します。以下の4つの相補的なアプローチを扱います。

  1. 自動 — CellTypist(キュレーション済みアトラスで学習したロジスティック回帰分類器)。
  2. 参照ベース — SingleR(R)または scANVI/sc.tl.ingest(Python)によるラベル転送。
  3. マーカーベース — 標準的なマーカー遺伝子パネルに基づく手動での割り当て。
  4. 階層型 — 大まかなコンパートメントの割り当て後に、専門的で詳細なアノテーションを実施。

クラスタリング済みの AnnData(または SingleCellExperiment)があり、adata.obs に細胞型ラベルを追加する必要がある場合に使用します。

使用方法

決定木:アノテーション手法の選択

この決定木に従って、適切な手法を選択します。

  1. 組織と種に一致する CellTypist モデルがありますか?
    • はい → CellTypist を使用します(以下の手順 1~6)
    • いいえ → 手順 2 に進みます
  2. 同じ組織のラベル付き参照 AnnData がありますか?
    • はい、同じバッチ/テクノロジーです → sc.tl.ingest を使用します(手順 12)
    • はい、バッチが異なります → scANVI によるラベル転送を使用します(手順 13)
    • いいえ → 手順 3 に進みます
  3. R でバルクまたはソート済み細胞の参照データを使っていますか?
    • はい → SingleR を使用します(手順 7~9)
    • いいえ → 手順 4 に進みます
  4. 想定される細胞型の標準的なマーカー遺伝子パネルがありますか?
    • はい → マーカーベースのアノテーションを使用します(手順 10~11)
    • いいえ → CellTypist の最も広範なモデル(Immune_All_Low.pkl または Developing_Human_Brain.pkl)から始め、その後マーカーで詳細化します
アノテーションのワークフロー(15 ステップ)

ステップ 1 — 正規化を確認します。 CellTypist には log1p(CP10k) が必要です。adata.uns['log1p'] が存在することを確認するか、正規化を実行してください。データが adata.raw またはレイヤーにある場合は、適切にサブセットしてください。

ステップ 2 — 遺伝子シンボルを確認します。 adata.var_names が Ensembl ID ではなく、HGNC(ヒト)または MGI(マウス)のシンボルであることを確認してください。必要に応じて、sc.queries.biomart_annotations で変換してください。

ステップ 3 — CellTypist モデルを選択します。 種と組織に合ったものを選んでください。celltypist.models.models_description() を使用して選択肢を一覧表示します。判断に迷う場合は、該当するコンパートメントに対して最も幅広く対応するモデルから始めてください。

ステップ 4 — CellTypist によるアノテーションを実行します。 majority_voting=True と適切な p_thres(デフォルトは 0.5、厳密な判定には 0.7 に引き上げます)を指定して、celltypist.annotate() を使用してください。

ステップ 5 — to_adata() で結果を抽出します。 predictions.to_adata() を呼び出して、アノテーションを .obs に取得します。信頼度には adata_result.obs['conf_score'] でアクセスできます。

ステップ 6 — 信頼度の低い細胞をフィルタリングします。 conf_score < 0.5(またはユーザー指定のしきい値)となる細胞をマスクし、'Unknown' に設定してください。

ステップ 7 — (SingleR)参照データセットをインストールします。 BiocManager::install("celldex") を使用し、適切な参照データセットを読み込んでください。

ステップ 8 — (SingleR)予測を実行します。 assay.type.test = "logcounts" を指定して、SingleR(test, ref, labels) を呼び出してください。

ステップ 9 — (SingleR)品質の低い判定を除外します。 pruneScores(pred) を使用して信頼性の低い割り当てを特定し、それらを "Unknown" に設定してください。

ステップ 10 — (マーカーに基づく方法)パネルを定義します。 文献に基づき、細胞型ごとに 3 個以上のマーカーを指定してください。有益な場合はネガティブマーカーも含めてください。

ステップ 11 — (マーカーに基づく方法)スコアを計算して割り当てます。 sc.pl.dotplot を使用して可視化し、クラスターを細胞型に対応付けてください。曖昧なクラスターは 'Unknown' のままにします。

ステップ 12 — (Ingest)クエリを参照データに射影します。 共通の PCA 空間が必要です。sc.tl.ingest(adata_query, adata_ref, obs='cell_type') を実行してください。クエリと参照データで技術が同じで、バッチ効果が最小限の場合にのみ、良好に機能します。

ステップ 13 — (scANVI)半教師あり転移を行います。 参照データで SCVI を学習し、ラベルを付けて SCANVI に拡張した後、クエリに対して load_query_data を実行してください。バッチ効果をネイティブに処理します。

ステップ 14 — アノテーションを検証します。 割り当てた細胞型ごとにグループ化した、標準的なマーカーのドットプロットで確認してください。サンプルごとの割合が生物学的に妥当かどうかも確認します。

ステップ 15 — 階層的に詳細化します。 詳細なラベルが安定しない場合は、まず粗いコンパートメント(PTPRC/EPCAM/COL1A1 による免疫/間質/上皮)をアノテーションし、サブセット化してから、各コンパートメントを専用モデルまたはマーカーで再アノテーションしてください。

分岐点
  • ステップ 4:細胞の >30% で conf_score < 0.5 となる場合、モデルが適合していません → マーカーに基づく方法に切り替えるか、別のモデルを試してください。
  • ステップ 6:単一のラベルが予期せず細胞の >80% を占める場合、モデルが誤っているか、データが未正規化である可能性を疑ってください。
  • ステップ 12:Ingest 後にクエリの UMAP が参照データと整合しない場合、バッチ効果が強すぎます → scANVI(ステップ 13)に切り替えてください。
  • ステップ 14:割合が生物学的に妥当でない場合(例:PBMC の 60% が線維芽細胞)、正規化とモデルの選択を再確認してください。

回答形式

  • 必要なコマンドまたはコードを最初に示し、その後に説明してください。
  • 次の構成にしてください:入力の確認 → 動作するコード → 重要なパラメーターの説明 → 注意点。
  • 各タスクにつき、完全に動作する例を 1 つ示してください。すべての代替案を並べないでください。
  • コードコメントは最小限にし、実用的な内容にしてください。
  • 目安:コード 50~100 行と、簡潔な説明。
  • 信頼度スコアの抽出とフィルタリングの手順を必ず含めてください。

基本概念

1. CellTypist(自動、Python)
import scanpy as sc
import celltypist
from celltypist import models

# Input: log1p-normalized to 10,000 counts/cell
sc.pp.normalize_total(adata, target_sum=1e4)
sc.pp.log1p(adata)

# Download models (first run only)
models.download_models()
print(models.models_description())  # list available models

# Load tissue-matched model
model = models.Model.load(model='Immune_All_Low.pkl')

# Annotate with majority voting
predictions = celltypist.annotate(
    adata,
    model=model,
    majority_voting=True,       # smooth labels over neighborhood graph
    over_clustering='leiden',   # obs key for majority voting resolution
    p_thres=0.5,               # minimum probability threshold (raise for stringency)
)

# Extract results — modern API (CellTypist >=1.3)
adata_result = predictions.to_adata()
# Annotations now in adata_result.obs:
#   'predicted_labels'        — per-cell raw predictions
#   'majority_voting'         — smoothed labels
#   'conf_score'              — max probability per cell

# Transfer to original adata
adata.obs['cell_type'] = adata_result.obs['majority_voting']
adata.obs['cell_type_conf'] = adata_result.obs['conf_score']

# Filter low-confidence assignments
adata.obs.loc[adata.obs['cell_type_conf'] < 0.5, 'cell_type'] = 'Unknown'

celltypist.annotate() の主なパラメーター:

パラメーターデフォルト効果
majority_votingFalsekNN グラフ上でラベルを平滑化します。常に有効にしてください
over_clusteringNone投票の解像度に使う obs キー(例:'leiden')です。クラスターを細分化すると、解像度が向上します
p_thres0.5ラベルを割り当てる最小確率です。高信頼度のものだけにするには 0.7 に上げます
mode'best match'複数ラベルのシナリオでは 'prob match' を使います

一般的なモデル:Immune_All_Low、Immune_All_High、Healthy_COVID19_PBMC、Human_Lung_Atlas、Cells_Intestinal_Tract、Developing_Human_Brain、Adult_Mouse_Gut。種と組織を一致させてください。

2. SingleR(参照ベース、R)
if (!requireNamespace("BiocManager", quietly = TRUE))
    install.packages("BiocManager")
BiocManager::install(c("SingleR", "celldex", "SingleCellExperiment"))

library(SingleR)
library(celldex)
library(SingleCellExperiment)

# Choose reference matching species/tissue
ref <- celldex::HumanPrimaryCellAtlasData()
# ref <- celldex::MonacoImmuneData()       # sorted human immune
# ref <- celldex::ImmGenData()             # mouse immune
# ref <- celldex::BlueprintEncodeData()    # human stromal + immune

pred <- SingleR(
    test = sce,
    ref = ref,
    labels = ref$label.main,
    assay.type.test = "logcounts"
)

sce$cell_type <- pred$labels
table(pred$labels)

# Prune low-confidence calls (delta < median - 3*MAD)
sce$cell_type[is.na(pred$pruned.labels)] <- "Unknown"
3. マーカーに基づく方法(手動、Python)
import scanpy as sc

marker_genes = {
    'T cells':      ['CD3D', 'CD3E', 'CD2'],
    'CD4 T':        ['CD4', 'IL7R'],
    'CD8 T':        ['CD8A', 'CD8B'],
    'B cells':      ['CD79A', 'MS4A1', 'CD19'],
    'NK cells':     ['NKG7', 'GNLY', 'KLRD1'],
    'Monocytes':    ['CD14', 'LYZ', 'S100A8'],
    'Dendritic':    ['FCER1A', 'CST3', 'CLEC10A'],
    'Fibroblasts':  ['COL1A1', 'DCN', 'COL3A1'],
    'Endothelial':  ['PECAM1', 'VWF', 'CDH5'],
    'Epithelial':   ['EPCAM', 'KRT18', 'KRT19'],
}

sc.pl.dotplot(adata, marker_genes, groupby='leiden', standard_scale='var')

# Assign after reviewing the dotplot
cluster_to_celltype = {
    '0': 'T cells', '1': 'Monocytes', '2': 'B cells',
    '3': 'NK cells', '4': 'Unknown',
}
adata.obs['cell_type'] = adata.obs['leiden'].map(cluster_to_celltype).astype('category')
4. リファレンスアトラスからのラベル転送
# Quick path: sc.tl.ingest (PCA/UMAP projection, kNN labels)
# Only use when batch effects are minimal
import scanpy as sc
sc.pp.pca(adata_ref)
sc.pp.neighbors(adata_ref)
sc.tl.umap(adata_ref)
sc.tl.ingest(adata_query, adata_ref, obs='cell_type')

# Robust path: scANVI (semi-supervised, handles batch)
import scvi
scvi.model.SCVI.setup_anndata(adata_ref, batch_key='batch')
scvi_model = scvi.model.SCVI(adata_ref)
scvi_model.train()

scvi.model.SCANVI.setup_anndata(
    adata_ref, labels_key='cell_type', unlabeled_category='Unknown', batch_key='batch'
)
scanvi_model = scvi.model.SCANVI.from_scvi_model(scvi_model, unlabeled_category='Unknown')
scanvi_model.train(max_epochs=20)

scanvi_model = scvi.model.SCANVI.load_query_data(adata_query, scanvi_model)
scanvi_model.train(max_epochs=100, plan_kwargs={'weight_decay': 0.0})
adata_query.obs['cell_type_pred'] = scanvi_model.predict(adata_query)
5. 検証
# Confirm assigned labels express their markers
sc.pl.dotplot(adata, marker_genes, groupby='cell_type', standard_scale='var')
sc.pl.violin(adata, ['CD3D', 'MS4A1', 'CD14'], groupby='cell_type', rotation=90)

# Sanity-check proportions per sample
adata.obs.groupby(['sample', 'cell_type']).size().unstack(fill_value=0)

明確なマーカーの裏付けがないクラスターには、無理にラベルを付けず 'Unknown' を指定してください。

6. 階層的アノテーション
# Step 1: coarse compartments
compartment_markers = {
    'Immune':     ['PTPRC'],           # CD45
    'Epithelial': ['EPCAM', 'KRT8'],
    'Stromal':    ['COL1A1', 'PECAM1'],
}
# Step 2: subset and re-annotate each compartment
adata_immune = adata[adata.obs['compartment'] == 'Immune'].copy()
model = models.Model.load('Immune_All_Low.pkl')
preds = celltypist.annotate(adata_immune, model=model, majority_voting=True)
adata_immune_result = preds.to_adata()
adata_immune.obs['cell_type_fine'] = adata_immune_result.obs['majority_voting']

クイックリファレンス

タスクツール主な呼び出し
PBMC/免疫の自動アノテーションCellTypistmodels.Model.load('Immune_All_Low.pkl')
肺アトラスへのマッピングCellTypist'Human_Lung_Atlas.pkl'
腸/腸管CellTypist'Cells_Intestinal_Tract.pkl'
広範なヒト参照データ(R)SingleRcelldex::HumanPrimaryCellAtlasData()
ソート済み免疫参照データ(R)SingleRcelldex::MonacoImmuneData()
マウス免疫(R)SingleRcelldex::ImmGenData()
クエリから参照データへの転送scanpysc.tl.ingest(adata_q, adata_ref, obs='cell_type')
バッチを考慮した転送scvi-toolsSCANVI.load_query_data(...)
マーカーの確認scanpysc.pl.dotplot(adata, markers, groupby='leiden')
信頼度(CellTypist)CellTypistpredictions.to_adata().obs['conf_score']
信頼度(SingleR)SingleRis.na(pred$pruned.labels) は品質の低い結果を示します

必須入力:

  • CellTypist:adata.X は log1p(CP10k) で正規化し、adata.var_names の遺伝子名には HGNC シンボルを使います。
  • SingleR:logcounts アッセイを含む SingleCellExperiment。
  • scANVI:adata.layers['counts'] の生カウント、参照データの batch_key と labels_key。
数値しきい値
指標しきい値対応
CellTypist conf_score< 0.5'Unknown' とラベル付けします
CellTypist conf_score< 0.7手動確認が必要なものとしてフラグを付けます
CellTypist p_thres0.5(デフォルト)厳密なアノテーションには 0.7 に上げます
SingleR delta score< median - 3×MADプルーニングされます(NA に設定)
クラスターサイズ< 20 細胞希少なサブタイプは割り当てず、親ラベルを使います
マーカードットプロットの割合< 0.3マーカーの発現は信頼できません。割り当てに使わないでください
予測割合の逸脱> 文献上の範囲の 3×モデルまたは正規化に誤りがある可能性があります

よくある間違い

  1. 誤り: 生のカウント値をCellTypistに入力する 正しい方法: アノテーションの前に、必ず sc.pp.normalize_total(adata, target_sum=1e4) + sc.pp.log1p(adata) を実行します 理由: CellTypistは、1細胞あたり10,000に正規化したカウント値のlog1pを想定しています。生データやSCTransform済みデータを使うと、意味のないラベルが生成されます

  2. 誤り: 組織や種に合わない参照モデルを使用する 正しい方法: CellTypistモデルまたはSingleR参照データを選ぶ際は、種(Human_* と Mouse_*)と組織の種類を一致させます 理由: 上皮性腫瘍細胞に Immune_All_Low を使用したり、マウスデータに HumanPrimaryCellAtlasData を使用したりすると、確信度は高いものの誤ったラベルが生成されます

  3. 誤り: Ensembl IDまたは大文字・小文字が混在した遺伝子シンボルをCellTypist/SingleRに渡す 正しい方法: アノテーションの前に、adata.var_names をHGNC(ヒト)またはMGI(マウス)のシンボルに変換します 理由: Ensembl IDや誤った大文字・小文字表記(Cd3d と CD3D など)では、特徴量が警告なしに除外され、モデルの性能が低下します

  4. 誤り: 信頼度スコアの取得に predictions.probability_matrix.max(axis=1) を使う 正しい方法: CellTypist ≥1.3で安定したAPIとして提供されている predictions.to_adata().obs['conf_score'] を使います 理由: 確率行列を使う方法は脆弱で、バージョンに依存します。アップデートによって動作しなくなったり、誤った値を返したりする可能性があります

  5. 誤り: 20細胞未満のクラスターに希少なサブタイプのラベルを付ける 正しい方法: クラスターのサイズが20細胞未満の場合は、親細胞型にまとめるか、'Unknown' とします 理由: ごく小さなクラスターへの希少なサブタイプの割り当ては、統計的検出力が不足しており、明確な識別マーカーがない限り信頼できません

  6. 誤り: ドットプロットを確認して明確なマーカーがないクラスターに、無理にラベルを付ける 正しい方法: 次善の推測を選ぶのではなく、曖昧なクラスターは 'Unknown' のままにします 理由: 無理に付けたラベルは下流の解析(DE、軌跡解析)に誤りを伝播させ、誤った生物学的解釈につながります

  7. 誤り: majority_voting=False でCellTypistを実行し、細胞ごとのラベルをそのまま使う 正しい方法: 近傍グラフ上でラベルを平滑化するため、必ず majority_voting=True を有効にします 理由: 細胞ごとの予測にはノイズが含まれます。多数決はクラスター構造を活用し、一貫性があり安定したアノテーションを生成します

  8. 誤り: バッチ補正なしでラベル転送に sc.tl.ingest を実行する 正しい方法: まずクエリと参照データを統合するか、バッチをネイティブに処理するscANVIの load_query_data パスを使います 理由: ingest はクエリと参照データが同じ埋め込み空間を共有していると仮定します。バッチ効果があると位置合わせが崩れ、誤ったラベルが転送されます

  9. 誤り: 細胞型の割合を生物学的な想定と照らし合わせて検証しない 正しい方法: サンプルごとの細胞型の割合を、既知の組織構成と必ず照合します 理由: PBMCサンプルの線維芽細胞が80%を占める場合、モデルの選択ミス、正規化エラー、またはデータ品質の問題を示す警告サインです

  10. 誤り: 階層的な絞り込みをせず、1つの解像度だけでアノテーションする 正しい方法: まず大まかな区画(免疫系/間質系/上皮系)にアノテーションし、その後、各区画を専用モデルまたはマーカーで絞り込みます 理由: 分離が不十分なクラスターに対する詳細なラベルは不安定です。階層的なアノテーションにより、より信頼性の高い結果が得られます

参考文献

コメント