# 06. 비슷한 세포를 군집으로 묶기

> 품질 관리를 마친 세포×유전자 행렬에서 세포 사이의 발현 유사도를 계산하고, 비슷한 세포가 촘촘히 연결된 집단을 찾는 과정.

군집 분석은 2차원 그림에서 섬을 눈으로 둘러 그리는 작업이 아닙니다. 품질 관리를 마친 세포×유전자 count matrix에서 세포마다 측정량 차이를 조정하고, 발현 패턴이 비슷한 세포를 연결한 뒤, 연결이 촘촘한 집단을 찾는 과정입니다.

> **이 수업의 질문**: 수만 개 유전자 값을 가진 세포를 어떤 순서로 비교해 반복되는 발현 패턴을 찾는가?

## 한 행을 비교 가능한 벡터로 만든다

세포마다 고유 분자 식별자(unique molecular identifier, UMI)로 중복을 접은 뒤 검출된 원래 RNA 분자 수가 다릅니다. 이 수가 총 UMI count입니다. 세포 A에서 10,000개, 세포 B에서 2,000개가 검출됐다면 변환 전 원래 값인 raw count를 그대로 비교할 때 측정량 차이가 거리를 지배할 수 있습니다.

탐색용의 흔한 변환은 각 세포의 총 count를 같은 기준 규모로 맞춘 뒤, 각 값 $x$를 $\log(1+x)$로 바꾸는 `log1p`를 적용하는 것입니다.

```python
counts = adata.X.copy()       # 검정에 다시 쓸 raw count 보존
normalize_total(adata)        # 세포별 총 count 차이 조정
log1p(adata)                  # 큰 값의 영향 완화
```

이 코드는 Python 패키지 Scanpy의 데이터 객체인 AnnData를 본뜬 의사코드입니다. 정규화된 값은 시각화·거리 계산용 표현이고, 원래 RNA 분자 수를 복원한 절대값이 아닙니다. raw count와 변환값을 객체 안의 별도 저장 공간인 layer에 보존해야 뒤 단계가 맞는 입력을 사용할 수 있습니다.

## 모든 유전자를 거리 계산에 쓰지 않는다

많은 유전자는 거의 모든 세포에서 비슷하거나 너무 드물게 검출됩니다. 이런 열까지 모두 거리 계산에 넣으면 잡음과 계산량이 늘어납니다.

**HVG**(highly variable gene, 고변동 유전자)는 평균 발현량을 고려했을 때 세포 사이 변동이 큰 유전자입니다. 세포를 구분하는 데 정보가 많은 열을 선택하는 feature selection으로 볼 수 있습니다.

HVG는 곧 질병 유전자나 세포 종류를 식별하는 유전자라는 뜻이 아닙니다. 군집용 좌표를 만드는 데 유용한 열이라는 뜻입니다. 조건 비교에서 검사할 유전자 집합과도 구분해야 합니다.

## 유전자 수를 줄인 공간에서 이웃을 찾는다

선택한 수천 개 HVG를 바로 2차원에 그리기보다 먼저 **주성분 분석**(principal component analysis, PCA)으로 수십 개 좌표로 줄입니다. PCA는 서로 함께 변하는 유전자 패턴을 압축하고, 낮은 신호의 잡음이 거리 계산을 지배하는 문제를 줄입니다.

[PCA 레퍼런스](/reference/pca/)에서는 PC 좌표와 loading을 읽는 법을 설명합니다.

PCA 공간에서 각 세포의 가까운 이웃 `k`개를 찾아 선으로 연결하면 **k-nearest-neighbour graph**가 됩니다. 이제 세포는 표의 행이면서 그래프의 node이고, 비슷한 발현 패턴을 가진 세포 사이에 edge가 있습니다.



## 이웃 그래프를 나누고 2차원으로 보여 준다

Leiden clustering은 이웃 그래프에서 내부 연결이 촘촘한 node 집합을 찾습니다. `resolution`을 높이면 더 잘게 나뉘고 낮추면 큰 군집으로 합쳐지는 경향이 있습니다.

**Uniform Manifold Approximation and Projection**(UMAP)은 고차원 이웃 관계를 2차원 좌표에 배치하는 시각화입니다. 군집 번호를 만든 뒤 UMAP에 색으로 표시할 수 있지만, 군집 번호가 UMAP의 x·y 좌표에서 직접 나온 것은 아닙니다. [거리와 차원축소](/reference/distance-and-dimension-reduction/)에서는 PCA와 UMAP이 보존하는 관계의 차이를 설명합니다.

따라서 다음처럼 해석합니다.

- 가까운 세포가 반복해서 이웃으로 연결되는지 본다.
- UMAP의 전체 방향, 섬 사이 빈 공간과 절대 거리에 물리적 의미를 붙이지 않는다.
- seed, 이웃 수, 전처리를 바꿨을 때 큰 구조가 유지되는지 확인한다.
- 섬 하나를 곧바로 세포 종류 하나라고 부르지 않는다.

## 실험 날짜 차이가 생물학적 차이처럼 보일 수 있다

서로 다른 실험 날짜, 장비나 처리 묶음에서 생긴 기술적 차이를 **batch effect**라고 합니다. 여러 실험·환자·날짜의 세포를 합치면 이 차이가 군집을 만들 수 있습니다. Harmony나 Seurat integration 같은 방법은 기술적 차이를 줄여 비슷한 세포가 함께 놓이게 합니다.

그러나 condition과 batch가 완전히 겹치면 어떤 차이가 기술적이고 어떤 차이가 생물학적인지 데이터만으로 분리할 수 없습니다. 통합 알고리즘이 만들어 낸 좌표는 군집과 시각화에 쓸 수 있지만, 조건 간 발현 검정에는 원래 sample 정보와 raw count를 보존해야 합니다.

## 단계마다 산출물을 따로 남긴다

| 단계 | 대표 산출물 |
| --- | --- |
| 정규화 | normalized/log-transformed layer |
| feature selection | HVG 목록과 선택 파라미터 |
| PCA | cell × PC 좌표, gene loading |
| 이웃 계산 | cell-cell graph |
| Leiden | 세포별 cluster ID |
| UMAP | 시각화용 2차원 좌표 |

## 정리

군집은 정규화된 행렬에서 HVG를 고르고, PCA 공간에서 이웃 그래프를 만든 뒤, Leiden으로 연결이 촘촘한 구역을 찾는 과정입니다. UMAP은 그 결과를 보는 화면이며 세포 종류 이름을 자동으로 제공하지 않습니다.

다음 [유전자 조합으로 세포 종류 이름 붙이기](/lessons/single-cell-annotation/)에서는 cluster 0·1·2에 생물학적 이름을 붙이는 근거를 다룹니다.

---

### 출처

- Scanpy 공식 전처리·군집 workflow: [Preprocessing and clustering](https://scanpy.readthedocs.io/en/stable/tutorials/basics/clustering.html)
- Seurat 공식 PBMC workflow: [Guided clustering tutorial](https://satijalab.org/seurat/articles/pbmc3k_tutorial)
- 단일세포 분석 모범 사례: [Heumos et al., *Nature Reviews Genetics* (2023)](https://www.nature.com/articles/s41576-023-00586-w)
- Harmony integration: [Korsunsky et al., *Nature Methods* (2019)](https://www.nature.com/articles/s41592-019-0619-0)