イメージング型 空間トランスクリプトーム:細胞レベルの QC と正規化 ─ 切り方の痕跡をどこまで消すか

Spatial transcriptome
📚 この記事について
セグメンテーションが済んだあとの工程を扱います。面積という指標をどう使うのか、正規化で何が消えるのか、パネルが小さいときに特徴選択をどう考えるのかを整理します。これで前処理は完結します。
🔙 前の記事:イメージング型 空間トランスクリプトーム:セグメンテーション手法の選び方
🔜 次の記事:イメージング型 空間トランスクリプトーム:パネル制約下でのアノテーション
📌 前提scRNA-seq解析:データの読み込みと品質管理(QC)セグメンテーション手法の選び方

空間トランスクリプトーム解析(spatial transcriptomics)のうちイメージング型(Xenium・CosMx・MERSCOPE など顕微鏡で1分子ずつ数える方式)は、細胞に切ったあとの QC が、scRNA-seq とは違う意味を持ちます。細胞の分子数が少ないとき、それは発現が低い細胞かもしれませんし、切り方が悪くて取りこぼした細胞かもしれません。この2つを区別できないまま先に進むと、計算の産物を生物学として解釈することになります。

1. 3つの指標を作る


計算する指標は scRNA-seq の QCに近いのですが、面積と、そこから作る面積あたりの分子数が加わります。

python
import scanpy as sc
import squidpy as sq
import numpy as np

adata = sdata["table"].copy()
adata.layers["counts"] = adata.X.copy()
sc.pp.calculate_qc_metrics(adata, inplace=True, log1p=False)

# 3つ目の指標をここで作る
adata.obs["density"] = (
    adata.obs["total_counts"] / adata.obs["cell_area"]
)

# 分布を見てから閾値を決める。先に決めない
for col in ["total_counts", "cell_area", "density"]:
    q = np.percentile(adata.obs[col], [1, 5, 25, 50, 75, 95, 99])
    print(col, np.round(q, 2))
指標 何を表すか
細胞あたりの分子数 その細胞から回収できた量
細胞の面積 セグメンテーションが引いた輪郭の大きさ
面積あたりの分子数 切り方の良し悪しがここに出る

2. 面積と分子数を、組で読む


図:面積と分子数の組み合わせで、原因が見分けられる
図:面積と分子数の組み合わせで、原因が見分けられる

分子数だけを見ると、「少ない細胞」は1つの集団に見えます。しかし面積と組で見ると、まったく違う2つが混ざっていることが分かります。

面積 分子数 解釈 対応
小さい 多い 核だけ取れている(濃い) 広げ方を見直す
大きい 多い 正常、または複数細胞の融合 純度で見分ける
小さい 少ない 取りこぼし 落とす候補
大きい 少ない 広げすぎ 落とす候補
python
# 面積と分子数の組み合わせで、細胞を4つに分ける
med_a = np.median(adata.obs["cell_area"])
med_c = np.median(adata.obs["total_counts"])

big  = adata.obs["cell_area"] > med_a
rich = adata.obs["total_counts"] > med_c
adata.obs["quad"] = np.select(
    [~big & rich, big & rich, ~big & ~rich, big & ~rich],
    ["小さいが濃い", "大きく濃い", "小さく薄い", "大きいが薄い"],
)
print(adata.obs["quad"].value_counts())

# 組織の上に描くと、どこで切り方が崩れているかが見える
sq.pl.spatial_scatter(adata, color="quad", shape=None)
💡 組織の上に描くと、原因が場所で分かる
4つの分類を組織の上に描いてください。「広げすぎ」の細胞が特定の領域に固まっているなら、そこは細胞がまばらな領域か、核染色が弱かった領域です。全体に散らばっているなら、パラメータの問題です。場所の情報があるからこそ、原因まで辿れます。

3. 落とす基準を決める


python
# 落とす候補は2つ。どちらも「切り方が悪い」側
drop_thin = (adata.obs["cell_area"] > np.quantile(adata.obs["cell_area"], 0.9)) & \
            (adata.obs["density"] < np.quantile(adata.obs["density"], 0.1))
drop_low  = adata.obs["total_counts"] < 10

print("広げすぎ:", int(drop_thin.sum()), "/ 分子不足:", int(drop_low.sum()))
adata = adata[~(drop_thin | drop_low)].copy()

# 落とした細胞が、組織のどこにあったかを確認する
#   ひとかたまりで消えているなら、その領域は撮像に問題があった可能性
⚠️ 落とした細胞が、どこにあったかを必ず見る
細胞をひとかたまりで落としたなら、それは領域ごと壊れていたということです。その原因は、転写産物レベルの QCで扱った撮像の問題であることが多い。本来は切る前に、分子の段階でその領域を外しておくべきでした。今回は落として進めるとしても、次のサンプルでは分子の段階で確認してください。
⚠️ 排他的マーカーを併せ持つ細胞に印を付ける
2つの細胞を1つにまとめてしまった細胞は、同居しないはずのマーカーを同時に持ちます。scRNA-seq のダブレットと見かけは似ていますが、原因が違います。ここでは計算由来なので、落とすだけでなくセグメンテーションを見直す材料にもなります。そういう細胞が多いなら、セグメンテーションの段階に戻る判断もありえます。

4. 正規化 ─ 何を消して何を残すか


図:正規化の選び方 ─ 何を消して何を残すか
図:正規化の選び方 ─ 何を消して何を残すか
やり方 得られるもの 失うもの
総分子数で割る(既定) 切り方の影響が消える 細胞の大きさも消える
面積で割る 大きさの影響が消える 小さい細胞が過大評価されうる
割らない 情報を失わない 細胞の大きさがそのまま効く
python
# 選択肢を3つとも作って、比べられるようにしておく
adata.layers["by_counts"] = adata.X.copy()
sc.pp.normalize_total(adata)
sc.pp.log1p(adata)
adata.layers["by_counts"] = adata.X.copy()

# 面積で割る版
Xa = adata.layers["counts"].copy().astype(float)
area = adata.obs["cell_area"].to_numpy()[:, None]
Xa = Xa / area * np.median(area)
adata.layers["by_area"] = np.log1p(Xa)

# どちらでクラスタリングするかを、組織像と照らして決める
# 面積は obs に残しておく。正規化で消える情報だから
💡 細胞の大きさは、生物学でもあり計算の産物でもある
同じ細胞型でも、活性化した細胞は大きくなります。これは生物学です。一方、輪郭を広げれば面積は増えます。これは計算の産物です。この2つが同じ数字に混ざっているので、「消すべきか残すべきか」に一般解がありません。だから面積を obs に残し、あとから選び直せるようにしておきます。クラスタごとに面積の分布を比べれば、影響の大きさが見積もれます。

5. 特徴選択 ─ パネルはすでに選び抜かれている


図:パネルの大きさで、特徴選択の考え方が変わる
図:パネルの大きさで、特徴選択の考え方が変わる

高変動遺伝子の選択は、捨ててよい遺伝子があることを前提にしています。全転写産物のデータには、確かに情報を持たない遺伝子がたくさんあります。

しかしパネルは違います。設計の段階で、情報を持つ遺伝子だけが選ばれています。300 遺伝子のパネルからさらに 2,000 を選ぼうとしても、そもそも足りません。絞れば、信号を捨てることになりかねません。

python
# パネルの大きさによって、特徴選択の考え方が変わる
n_genes = adata.n_vars
print("パネルの遺伝子数:", n_genes)

if n_genes < 500:
    # 選び抜かれた小さなパネル。絞る余地がほとんど無い
    use = adata.var_names.tolist()
else:
    sc.pp.highly_variable_genes(adata, n_top_genes=min(2000, n_genes))
    use = adata.var_names[adata.var["highly_variable"]].tolist()

print("使う遺伝子:", len(use))

# 迷ったら、両方でクラスタリングして組織像と比べる
sc.pp.pca(adata, n_comps=min(50, len(use) - 1))
sc.pp.neighbors(adata)
sc.tl.leiden(adata, resolution=1.0, flavor="igraph")
sq.pl.spatial_scatter(adata, color="leiden", shape=None)
💡 迷ったら、両方でクラスタリングして比べる
絞った場合と絞らない場合の両方でクラスタリングし、組織像とよく合うほうを選べば済みます。空間データには「組織像」という外部の基準があるので、この比較ができます。scRNA-seq のクラスタリングでは、こうした外部基準がないぶん判断が難しくなります。

6. クラスタリングの解像度


解像度を1つに決めず、いくつか振って組織像と見比べます。「クラスタ数がいくつなら正しい」という基準はありません。組織のどの構造を分けたいのかで決めます。

⚠️ 細かく分けるほど良いわけではない
解像度を上げれば、クラスタは細かく分かれます。しかし、その細分がパネルの遺伝子で支えられているかは別の問題です。分ける根拠がパネルに無ければ、その境界はノイズで決まります。この点は パネル制約下でのアノテーションで詳しく扱います。

7. 複数スライドの統合


スライド間の差は HarmonyscVI で補正できます。道具立ては scRNA-seq と同じです。

⚠️ 3つの原因を切り分けてから統合する
スライドによって細胞あたりの分子数が違うとき、原因は3つ考えられます。(1) 実験のばらつき(2) セグメンテーションの出来の差(3) 検出感度そのものの差。バッチ補正で直るのは (1) だけです。(2) なら切り方をそろえるべきですし、(3) なら統合せず別々に解析するほうが安全なこともあります。面積・面積あたりの分子数・対照の率をスライドごとに比べて、どれなのかを先に見分けてください。

パネルが違うデータを比べる場合は、さらに注意が要ります。パネルの拡大が検出効率を下げうることが報告されており(Cervilla et al., Genome Biology, 2026)、共通遺伝子だけに絞っても、1遺伝子あたりの検出量が違う可能性があります。

8. 前処理完了チェック


  • 面積と面積あたりの分子数を計算したか
  • 面積と分子数を組で見て、4つに分類したか
  • 落とした細胞が組織のどこにあったかを確認したか
  • 排他的マーカーを併せ持つ細胞に印を付けたか
  • 生カウントを layers に残したか
  • 面積を obs に残したか
  • 正規化の選択肢を複数作って、比べられるようにしたか
  • パネルの大きさに対して、特徴選択の方針は妥当か
  • クラスタを組織の上に描いて、構造と対応するか確認したか
  • スライド間の差の原因を切り分けたか

まとめ


  • 分子数が少ない細胞は、発現が低い細胞切り方が悪い細胞か。面積と組で見ないと区別できない。
  • 大きいのに薄い細胞は、広げすぎ小さくて薄い細胞は、取りこぼし。どちらも落とす候補。
  • 落とした細胞の場所を見る。かたまっているなら、領域ごと壊れていた。
  • 正規化は総分子数・面積・割らないの3択。総分子数で割ると、切り方と一緒に細胞の大きさも消える
  • 細胞の大きさは生物学でもあり計算の産物でもあるので、一般解が無い。面積を obs に残して、あとから選び直せるようにする。
  • パネルはすでに選び抜かれている。高変動遺伝子の選択は「捨ててよい遺伝子がある」前提に立つが、小さなパネルではその前提が崩れる。
  • 空間データには組織像という外部基準がある。迷ったら両方試して比べればよい。
  • スライド間の差は実験・切り方・感度の3つに切り分ける。バッチ補正で直るのは1つ目だけ。

関連記事


参考文献


  • Petukhov, V., Xu, R. J., Soldatov, R. A., et al. (2022). Cell segmentation in imaging-based spatial transcriptomics. Nature Biotechnology, 40(3), 345–354. doi:10.1038/s41587-021-01044-w
  • Cervilla, S., Grases, D., Perez, E., et al. (2026). A technical comparison of spatial transcriptomics platforms across six cancer types. Genome Biology, 27, 22. doi:10.1186/s13059-026-03937-y
  • Janesick, A., Shelansky, R., Gottscho, A. D., et al. (2023). High resolution mapping of the tumor microenvironment using integrated single-cell, spatial and in situ analysis. Nature Communications, 14(1), 8353. doi:10.1038/s41467-023-43458-x
  • Wolf, F. A., Angerer, P., & Theis, F. J. (2018). SCANPY: large-scale single-cell gene expression data analysis. Genome Biology, 19, 15. doi:10.1186/s13059-017-1382-0
  • Traag, V. A., Waltman, L., & van Eck, N. J. (2019). From Louvain to Leiden: guaranteeing well-connected communities. Scientific Reports, 9, 5233. doi:10.1038/s41598-019-41695-z
  • Korsunsky, I., Millard, N., Fan, J., et al. (2019). Fast, sensitive and accurate integration of single-cell data with Harmony. Nature Methods, 16(12), 1289–1296. doi:10.1038/s41592-019-0619-0
  • Palla, G., Spitzer, H., Klein, M., et al. (2022). Squidpy: a scalable framework for spatial omics analysis. Nature Methods, 19(2), 171–178. doi:10.1038/s41592-021-01358-2
  • Marconato, L., Palla, G., Yamauchi, K. A., et al. (2025). SpatialData: an open and universal data framework for spatial omics. Nature Methods, 22(1), 58–62. doi:10.1038/s41592-024-02212-x

コメント

タイトルとURLをコピーしました