[Part 2/3] GO Annotation과 Pathway Enrichment 실전 가이드
clusterProfiler, topGO, fgsea, MSigDB로 GO와 Pathway Enrichment를 수행하는 실전 워크플로. ORA vs GSEA 선택 기준과 background 함정.
📚 시리즈 안내 · 본 글은 3편 시리즈의 두 번째입니다. Part 1 — PPI + Hub · Part 2 — GO + Pathway Enrichment (현재) · Part 3 — TF Activity + Biomarker 통합
⬅️ 이전 글 Part 1 — PPI 네트워크 구축과 Hub 단백질 분석에서 추린 Hub 후보 리스트를 가지고 이번 글로 넘어옵니다.
"이 DEG들이 무엇을 말하고 있나?" 이 질문에 답하는 두 가지 표준 도구가 GO enrichment와 Pathway enrichment입니다. 그러나 도구를 잘못 쓰면 해석 가능한 결과처럼 보이지만 실제로는 background bias의 산물이 됩니다. 이번 글의 핵심은 도구가 아니라 그 함정들입니다.
📌 TL;DR
- **Background(universe)**를 발현 검출된 유전자로 제한 — 이걸 안 하면 결과 90%가 거짓
- Cutoff가 명확하면 ORA, 미약한 일관 신호 보려면 GSEA
- 중복 GO term은 topGO elim 또는 clusterProfiler::simplify로 정리
- Pathway redundancy(parent/child 동시 노출) 항상 의심
- 도구·DB 버전 명시는 reporting 필수 (KEGG는 라이선스 유의)
1. Gene Ontology — 계층 구조와 evidence codes
1.1 GO의 DAG 구조
GO는 트리가 아니라 **DAG (Directed Acyclic Graph)**입니다. 한 term이 여러 parent에 속할 수 있어 enrichment 결과의 중복 해석에 영향을 줍니다.
예: GO:0000278 (mitotic cell cycle)
is_a → GO:0007049 (cell cycle)
is_a → GO:0009987 (cellular process)
is_a → GO:0008150 (biological_process)
세 가지 namespace
- BP (Biological Process) — mitotic cell cycle, apoptosis, immune response
- MF (Molecular Function) — DNA binding, kinase activity, transporter activity
- CC (Cellular Component) — nucleus, mitochondrion, ribosome, membrane
1.2 Evidence codes — 신뢰도 계층
| 코드 | 의미 | 신뢰도 |
|---|---|---|
| EXP, IDA, IMP, IGI, IPI, IEP | 실험적 증거 | ⭐⭐⭐ 최고 |
| TAS, IC | 큐레이터 기반 | ⭐⭐ 높음 |
| ISS, ISO, ISA, ISM | 서열 유사성 기반 | ⭐⭐ 중 |
| IEA | 자동 주석 (알고리즘) | ⭐ 주의 — 대부분의 주석이 이 범주 |
💡 실전 필터링 — 보수적 분석이 필요하면 IEA 제외. 전체 coverage가 필요하면 포함.
org.Hs.eg.db의GOALL사용 시 자동으로 ancestor가 포함되어 double-counting 가능성에 주의.
2. GO Enrichment 도구 비교
| 도구 | 인터페이스 | 특징 |
|---|---|---|
| clusterProfiler | R | 사실상 표준, ORA + GSEA 모두 지원, 시각화 풍부 |
| topGO | R | GO 계층 고려한 elim/weight 알고리즘 — 중복 자동 제거 |
| g:Profiler (gprofiler2) | R/web/Python | 최신 데이터, 커스텀 background 쉬움, multi-query |
| DAVID | web | 고전적, 업데이트 주기 길다 |
| Enrichr | web/R | 방대한 gene set 카탈로그 (200+ 라이브러리) |
| GOseq | R | RNA-seq의 length bias 보정 — 짧은 유전자가 적게 검출되는 편향 교정 |
R 예시 — clusterProfiler ORA + 시각화
library(clusterProfiler)
library(org.Hs.eg.db)
library(enrichplot)
# DEG: Entrez ID 벡터 / universe: 발현된 전체 유전자
ego <- enrichGO(gene = deg_entrez,
universe = universe_entrez, # ← 핵심
OrgDb = org.Hs.eg.db,
ont = "BP",
pAdjustMethod = "BH",
pvalueCutoff = 0.05,
qvalueCutoff = 0.10,
readable = TRUE)
# 중복 GO term 축약 (semantic similarity 기반)
ego_simp <- simplify(ego, cutoff=0.7, by="p.adjust", select_fun=min)
dotplot(ego_simp, showCategory=20)
emapplot(pairwise_termsim(ego_simp)) # term 네트워크
cnetplot(ego_simp, categorySize="pvalue",
foldChange=geneList) # 유전자–term 양측 그래프
heatplot(ego_simp, foldChange=geneList)
3. Background (universe) — 가장 흔하고 가장 큰 함정
⚠️ 왜 background가 결정적인가
Enrichment는 본질적으로 "전체에서 기대되는 것보다 많은가"를 묻는 검정입니다. 분모(universe)가 잘못 잡히면 분자가 옳아도 결론은 무의미합니다.
- 잘못된 예: 전체 인간 유전체(20,000)를 background로 사용 → 발현조차 안 되는 유전자가 분모에 포함되어 enrichment가 과대평가
- 옳은 예 (RNA-seq):
CPM > 1 in ≥ N samples등으로 발현 검출된 유전자만 universe로 사용- 옳은 예 (proteomics): 각 실험에서 검출된 단백질만 universe로 사용
잘못된 background는 "면역 관련 enrichment", "신경 발달 enrichment" 같은 일견 그럴듯한 허위 결과를 만들기 쉽습니다.
4. Pathway Enrichment — DB 비교
| DB | 특징 | 사이즈 |
|---|---|---|
| KEGG | 고전, signaling + metabolism — 학술 비영리는 무료, 상업은 라이선스 유의 | ~550 pathway |
| Reactome | 계층 구조, 반응 수준 상세, 완전 오픈 | ~2,500 pathway |
| WikiPathways | 커뮤니티 기반, 질병 특화 경로 강함 | ~1,300 pathway |
| MSigDB | Hallmark(H), C2(curated), C5(GO), C7(immune) 등 통합 카탈로그 | ~35,000 set |
| BioCarta, PID, NCI | MSigDB C2에 통합됨 | - |
5. ORA vs GSEA — 선택 기준
📋 ORA (Fisher's exact / hypergeometric)
- 입력: DEG 리스트 + background
- 질문: "이 DEG 세트 안에 특정 pathway 유전자가 우연보다 많이 있나?"
- 장점: 단순, 직관적, 계산 빠름
- 단점: cutoff에 민감, 순위 정보 손실
📊 GSEA (Kolmogorov-Smirnov-like)
- 입력: 모든 유전자의 랭크된 통계량
- 질문: "특정 pathway 유전자들이 순위 분포의 상/하위에 몰려 있나?"
- 장점: cutoff 불필요, 미약한 일관 신호 포착
- 단점: 파라미터 복잡, 해석 까다로움
R 예시 — fgsea로 빠른 GSEA
library(fgsea)
library(msigdbr)
# MSigDB Hallmark 50종 (인간)
m_df <- msigdbr(species="Homo sapiens", category="H")
pathways <- split(m_df$gene_symbol, m_df$gs_name)
# ranks: named numeric, signed -log10(p) × log2FC 권장
ranks <- sort(stats, decreasing=TRUE)
fgsea_res <- fgsea(pathways = pathways,
stats = ranks,
minSize = 15,
maxSize = 500,
eps = 0)
# Leading edge — 신호를 만든 핵심 유전자
fgsea_res[order(padj)][1:10,
c("pathway","NES","padj","leadingEdge")]
# 시각화
plotEnrichment(pathways[["HALLMARK_E2F_TARGETS"]], ranks)
6. 해석 시 자주 만나는 함정
⚠️ Pathway 결과 해석 체크리스트
- Pathway 크기 편향 — 큰 pathway(metabolism, signal transduction)가 항상 나오기 쉽다. NES와 gene set size를 같이 보기.
- Redundancy — Reactome 계층 구조상 parent/child pathway가 둘 다 top에 뜸.
simplify나 leading edge 중복도로 판단.- Direction ambiguity — ORA는 up/down을 구분하지 않음. up과 down DEG를 따로 분석하거나 GSEA의 signed NES 활용.
- Gene-level redundancy — 한 유전자가 여러 pathway에 속함. 같은 유전자가 다른 pathway 결과를 만들 때 "정말 다른 생물학"인지 의심.
- Tissue context mismatch — "신경계 발달" pathway가 혈액 샘플에서 유의하게 나오면 재검토 (이는 background 문제일 가능성도 있음).
7. Topology-aware Pathway Analysis
ORA/GSEA는 pathway를 "유전자 리스트"로만 봅니다. 실제 pathway는 방향과 반응 구조가 있습니다. 이를 반영하는 방법:
- SPIA (Signaling Pathway Impact Analysis) — KEGG topology 기반, signed impact factor
- PathwayPCA, CePa — pathway 내 유전자 간 종속성 반영
- PROGENy — 14개 주요 signaling의 하류 타깃 발현으로 "pathway activity" 추론
- DoRothEA + viper — TF-target 네트워크 기반 활성 추론 (Part 3에서 상세히 다룸)
💡 실전 권장 흐름
- 1차: clusterProfiler로 KEGG + Reactome ORA → 빠른 큰 그림
- 2차: fgsea로 MSigDB Hallmark + C2 GSEA → 보다 미세한 신호
- 3차: PROGENy로 signaling pathway activity 정량화
- 4차: top hits에 대해 leading edge 유전자 → Part 1의 PPI Hub와 교차 확인
8. Reporting 체크리스트
- 모든 DB 버전 명시 (MSigDB v2023.2, GO 릴리스 날짜, KEGG 버전 등)
- Background(universe) 정의 명확히
- 다중검정 보정 방법(BH / Bonferroni)
- FDR cutoff 및 효과 크기(NES, log2FC) 모두 보고
- Leading edge / 핵심 유전자 목록 supplementary table
- 도구 버전 (clusterProfiler 4.x, fgsea x.y) sessionInfo 첨부
➡️ 다음 글: Part 3 — 전사인자 활성 추론과 바이오마커 통합
DoRothEA + viper, SCENIC, ChEA3로 "누가 이 발현 변화를 지시했는가"를 역추적하고, Part 1·2의 결과를 바이오마커 후보로 통합합니다.