-
single cell 분석 - cluster 개수 정하기Bio-info/analysis 2025. 3. 5. 20:48
참고 : scanpy - preprocessing & clustering
https://scanpy.readthedocs.io/en/stable/tutorials/basics/clustering.html#manual-cell-type-annotation
written by chatGPT 4o
🔍 클러스터 개수를 정하는 가장 근거 있는 방법
클러스터 개수(Optimal Number of Clusters)를 정하는 방법은 데이터의 구조와 분석 목적에 따라 다르지만, 일반적으로 다음과 같은 방법들이 신뢰할 수 있습니다.
📌 1. 데이터 기반의 정량적 방법
1️⃣ Elbow Method (엘보우 방법)
- 클러스터 개수 k를 변화시키면서 클러스터 내 응집도(SSE, Within-cluster sum of squares, WCSS)를 계산한 후, 그래프에서 곡선이 급격히 꺾이는 지점(Elbow point)을 최적의 클러스터 개수로 선택하는 방법.
- K-means, Leiden, Louvain 등 대부분의 클러스터링 알고리즘에서 사용 가능.
✅ 적용 방법 (Scanpy):
import scanpy as sc import numpy as np import matplotlib.pyplot as plt from sklearn.metrics import silhouette_score wcss = [] resolutions = np.linspace(0.01, 2.0, 20) # 여러 가지 해상도(resolution) 값 테스트 for res in resolutions: sc.tl.leiden(adata_pdo_hvg, resolution=res, key_added=f'leiden_{res:.2f}') clusters = adata_pdo_hvg.obs[f'leiden_{res:.2f}'].astype(int) wcss.append(np.mean([np.var(adata_pdo_hvg[clusters == i].X) for i in range(clusters.nunique())])) # 그래프 출력 plt.plot(resolutions, wcss, marker='o') plt.xlabel("Resolution (Leiden parameter)") plt.ylabel("Within-Cluster Variance (WCSS)") plt.title("Elbow Method for Optimal Clustering") plt.show()
📌 Elbow point에서 클러스터 개수가 최적인 경우가 많음.
2️⃣ Silhouette Score (실루엣 스코어)
- 클러스터링이 얼마나 잘 분리되었는지를 측정하는 지표.
- 값이 1에 가까울수록 클러스터가 명확하게 구분됨.
- Leiden, Louvain, K-means 등에서 사용 가능.
✅ 적용 방법 (Scanpy):
from sklearn.metrics import silhouette_score scores = [] resolutions = np.linspace(0.01, 2.0, 20) for res in resolutions: sc.tl.leiden(adata_pdo_hvg, resolution=res, key_added=f'leiden_{res:.2f}') clusters = adata_pdo_hvg.obs[f'leiden_{res:.2f}'].astype(int) score = silhouette_score(adata_pdo_hvg.obsm['X_umap'], clusters) scores.append(score) plt.plot(resolutions, scores, marker='o') plt.xlabel("Resolution") plt.ylabel("Silhouette Score") plt.title("Optimal Clustering based on Silhouette Score") plt.show()
📌 Silhouette Score가 가장 높은 클러스터 개수를 선택하면 좋음.
3️⃣ Gap Statistics (갭 통계량)
- 클러스터링의 성능을 랜덤 데이터와 비교하여 최적 개수를 결정.
- Leiden, Louvain 등에서 사용 가능.
✅ 적용 방법: gap_statistic 패키지를 이용한 방법
from gap_statistic import OptimalK optimal_k = OptimalK(parallel_backend='joblib') n_clusters = optimal_k(adata_pdo_hvg.obsm['X_umap']) print(f"Optimal number of clusters: {n_clusters}")
📌 랜덤 데이터와의 차이가 가장 큰 클러스터 개수를 선택하면 최적의 클러스터 수를 결정할 수 있음.
📌 2. 생물학적/도메인 지식 기반 방법
1️⃣ Marker Genes 확인
- 각 클러스터에서 특이적으로 발현되는 유전자를 확인하여 클러스터 개수를 결정.
- 만약 일부 클러스터가 생물학적으로 의미 없는 분리라면, 클러스터 개수를 줄이는 것이 좋음.
✅ 적용 방법 (Scanpy):
sc.tl.rank_genes_groups(adata_pdo_hvg, 'leiden', method='wilcoxon') sc.pl.rank_genes_groups(adata_pdo_hvg, n_genes=20, sharey=False)
📌 각 클러스터가 생물학적으로 의미 있는지를 확인한 후, 클러스터 개수를 조정 가능.
2️⃣ Cluster Stability Test (클러스터 안정성 테스트)
- 동일한 데이터에 대해 여러 번 클러스터링을 수행한 후, 클러스터 구성의 안정성을 평가.
- 특정 클러스터가 계속 유지된다면 신뢰할 수 있는 클러스터 개수임.
✅ 적용 방법 (Bootstrap 기반)
import random stability_scores = [] resolutions = np.linspace(0.01, 2.0, 10) for res in resolutions: scores = [] for _ in range(10): # 10번 반복 sampled_cells = random.sample(list(adata_pdo_hvg.obs.index), int(len(adata_pdo_hvg) * 0.8)) sc.tl.leiden(adata_pdo_hvg[sampled_cells], resolution=res, key_added=f'leiden_{res:.2f}') clusters = adata_pdo_hvg[sampled_cells].obs[f'leiden_{res:.2f}'] scores.append(len(set(clusters))) stability_scores.append(np.mean(scores)) plt.plot(resolutions, stability_scores, marker='o') plt.xlabel("Resolution") plt.ylabel("Cluster Stability Score") plt.title("Cluster Stability Test") plt.show()
📌 클러스터 개수가 일정하게 유지되는 해상도를 선택하는 것이 좋음.
📌 3. 실용적인 결론
방법 설명 추천 시나리오
Elbow Method WCSS가 급격히 감소하는 지점을 선택 클러스터 개수를 빠르게 결정하고 싶을 때 Silhouette Score 가장 높은 실루엣 점수를 가지는 클러스터 개수 선택 클러스터가 얼마나 잘 분리되었는지 확인하고 싶을 때 Gap Statistics 랜덤 데이터와 비교하여 최적 개수 선택 데이터 구조가 불분명할 때 Marker Genes 분석 특정 클러스터가 생물학적으로 유의미한지 확인 유전자 발현을 기반으로 의미 있는 클러스터를 찾고 싶을 때 Cluster Stability Test 반복된 샘플링에서 안정적인 클러스터 개수를 찾음 클러스터링이 얼마나 안정적인지 평가하고 싶을 때 💡 보통 Elbow Method + Silhouette Score + Marker Genes 분석을 함께 사용하면 가장 신뢰할 수 있음! 🚀
'Bio-info > analysis' 카테고리의 다른 글
single cell analysis - after cell type annotation (0) 2025.03.05 single-cell analysis (0) 2025.03.05 single cell - spatial transcription analysis (0) 2023.03.29 GSEA 분석 (0) 2023.03.10