8. 聚類Clustering
預處理和可視化使我們能夠描述我們的scRNA-seq數據集并降低其維度。到目前為止,我們嵌入并可視化了細胞以了解數據集的基礎屬性。然而,它們的定義仍然相當抽象。單細胞分析的下一個步驟是識別數據集中的細胞結構。
在scRNA-seq數據分析中,我們通過查找與已知細胞狀態或細胞周期階段相關的細胞身份來描述數據集中的細胞結構。這個過程通常稱為細胞身份注釋。為此,我們將細胞組織成簇,以推斷相似細胞的身份。聚類本身是一個常見的無監督機器學習問題。我們可以通過最小化表達空間中的簇內距離來導出簇。在這種情況下,表達空間決定了細胞相對于降維表示的基因表達相似性。例如,這種較低維度的表示是通過主成分分析確定的,然后基于歐幾里德距離進行相似性評分。
在k最近鄰(KNN)圖中,節點反映數據集中的細胞。我們首先在PC(主成分)縮減表達空間上計算所有細胞的歐幾里德距離矩陣,然后將每個細胞連接到其K個最相似的細胞。通常,K設置為5到100之間的值,具體取決于數據集的大小。KNN圖通過圖中的密集連接區域來反映表達數據的基礎拓撲結構。KNN圖中的密集區域是通過Leiden和Louvain等community檢測方法實現。
Leiden算法是Louvain算法的改進版本,在單細胞RNA-seq數據分析方面優于其他聚類方法。由于Louvain算法不再維護,因此首選使用Leiden。
因此,我們建議在單細胞k最近鄰(KNN)圖上使用Leiden算法來對單細胞數據集進行聚類。
Leiden通過考慮簇中細胞之間的鏈接數量與數據集中的總體預期鏈接數量來創建簇。
起點是一個單例分區,其中每個節點都充當自己的社區(a)。下一步,該算法通過將單個節點從一個社區移動到另一個社區來創建分區(b),隨后進行細化以增強分區(c)。然后將細化的分區聚合到網絡(d)。隨后,算法再次移動聚合網絡中的各個節點(e),直到細化不再改變分區(f)。 重復所有步驟,直到創建最終的聚類并且分區不再發生變化。
Leiden模塊具有分辨率參數,可以確定分區簇的規模,從而確定聚類的粗糙度。更高分辨率的參數會導致更多的簇。該算法還允許通過對KNN圖進行子設置來對數據集中的特定聚類進行有效的子聚類。子聚類使用戶能夠識別聚類內的細胞類型特定狀態或更精細的細胞類型標記,但也可能導致僅由于數據中存在的噪聲而產生的結果。
前面提到,Leiden算法是在scanpy中實現的。
import scanpy as sc
sc.settings.verbosity = 0
sc.settings.set_figure_params(dpi=80, facecolor="white", frameon=False)
8.1 聚類人類骨髓來源細胞
首先,我們加載數據集。 我們對來自我們已經預處理的NeurIPS人類骨髓數據集的預處理樣本site4-donor8
進行聚類。
該數據集使用log1pPF、scran和scTransform 進行標準化。我們將按照預處理章節中的建議重點關注本筆記本中數據集的scran標準化版本,以更好地識別單個細胞的狀態。
adata = sc.read("s4d8_subset_gex.h5ad")
我們可以使用scanpy函數sc.pp.neighbors
計算低維基因表達表示的KNN圖。我們在前30個主成分上調用此函數,因為它們捕獲了數據集中的大部分方差。
可視化聚類可以幫助我們理解結果,因此我們將細胞嵌入到UMAP中。有關UMAP可視化的更多信息可以在可視化部分找到。
sc.pp.neighbors(adata, n_pcs=30)
sc.tl.umap(adata)
輸出結果:
/Users/anna.schaar/opt/miniconda3/envs/bp_pp/lib/python3.8/site-packages/tqdm/auto.py:22: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html
from .autonotebook import tqdm as notebook_tqdm
OMP: Info #276: omp_set_nested routine deprecated, please use omp_set_max_active_levels instead.
我們現在可以調用Leiden算法。
sc.tl.leiden(adata)
scanpy中默認的分辨率參數是1.0。然而,在許多情況下,分析人員可能希望嘗試不同的分辨率參數來控制聚類的粗糙度。因此,我們建議將聚類結果保存。
sc.tl.leiden(adata, key_added="leiden_res0_25", resolution=0.25)
sc.tl.leiden(adata, key_added="leiden_res0_5", resolution=0.5)
sc.tl.leiden(adata, key_added="leiden_res1", resolution=1.0)
我們現在可視化在不同分辨率下使用萊頓算法獲得的不同聚類結果。正如我們所看到的,分辨率很大程度上影響了我們的聚類的粗略程度。較高的分辨率參數會導致更多的社區,即更多的識別簇,而較低的分辨率參數會導致更少的社區。因此,分辨率參數控制算法將KNN嵌入中的聚類區域分組在一起的密度。這對于注釋集群變得尤其重要。
sc.pl.umap(
adata,
color=["leiden_res0_25", "leiden_res0_5", "leiden_res1"],
legend_loc="on data",
)
我們現在可以清楚地檢查不同分辨率對聚類結果的影響。對于0.25的分辨率,聚類更加粗糙,算法檢測到的社區也更少。此外,與分辨率為1.0 時獲得的聚類相比,聚類區域的密度較低。
我們想再次強調,必須謹慎解釋顯示的簇之間的距離。由于UMAP嵌入是二維的,因此不一定能很好地捕獲所有點之間的距離。我們建議不要解釋UMAP嵌入上可視化的簇之間的距離。