7강 / 20강

정규화 ② — 왜 log2 를 씌우나

1 = 두 배, 그리고 +1 의 정체

정규화 ② — 왜 log2 를 씌우나
발현량은 몇 배로 움직입니다. 그래서 눈금도 배수 눈금으로 바꿔 줍니다.

유전자 발현량에는 고약한 성질이 있습니다. 값의 범위가 어마어마하게 넓어요. 어떤 유전자는 CPM 0.5, 어떤 유전자는 CPM 20,000. 4만 배 차이입니다. 이 둘을 한 그래프에 그리면 작은 쪽은 바닥에 딱 붙어 아무것도 안 보입니다.

게다가 생물학적으로 의미 있는 변화는 뺄셈이 아니라 나눗셈입니다. "10 늘었다"보다 "2배가 됐다"가 훨씬 쓸모 있는 정보예요.

그냥 CPM
100 → 200   : +100
 10 →  20   : +10
둘 다 '두 배'인데 숫자가 딴판
log2 CPM
6.64 → 7.64 : +1
3.32 → 4.32 : +1
두 배 = 언제나 +1

log2 를 씌우면 곱셈이 덧셈이 됩니다. 2배 = +1, 4배 = +2, 8배 = +3, 절반 = −1. 이 성질 때문에 생물정보학은 log2 를 기본 눈금으로 씁니다. 앞으로 계속 나올 log2FC(fold change)가 바로 이 눈금 위의 뺄셈이에요.

log2 눈금 위에서는 '몇 배'가 곧 '얼마나 떨어져 있나'가 됩니다.
Python 브라우저에서 실행

+1 은 왜 붙이나 — log2(CPM + 1)

여기에 함정이 하나 있습니다. log2(0) 은 음의 무한대예요. RNA-seq 표에는 0이 아주 많습니다 (그 유전자가 아예 안 켜진 세포). 그대로 로그를 씌우면 표 곳곳에 -inf 가 박혀 이후 계산이 전부 망가집니다.

np.log2(cpm) → 0 인 칸이 -inf 로 폭발 np.log2(cpm + 1) → 0 인 칸이 0.0 으로 안전 착륙

+1 을 의사 카운트(pseudocount) 라고 부릅니다. 큰 값에는 거의 영향이 없고(20000 → 20001, 차이 없음), 작은 값 근처만 부드럽게 눌러 줍니다. 공짜는 아니에요 — 아주 낮은 발현의 배수 차이는 조금 과소평가됩니다. 그 대신 안정성을 얻습니다.

-inf 가 실제로 어떻게 생기는지 눈으로 봅니다.
Python 브라우저에서 실행

🎮 배수 ↔ log2 변환기

슬라이더를 움직여 두 값을 바꿔 보세요. 몇 배인지, log2FC 로는 얼마인지가 동시에 나옵니다. log2FC = −1 이 '절반' 이라는 감각을 여기서 만들어 두면 14강 이후가 훨씬 쉬워집니다.

log2 변환기 — 배수와 log2FC 를 나란히
불러오는 중…
🤔 확인 문제
log2FC 가 +2 라면 발현량은 몇 배가 된 것인가요?
🤔 확인 문제
np.log2(cpm + 1) 에서 +1 을 빼면 무슨 일이 생기나요?
🤔 확인 문제
발현량에 로그를 씌우는 가장 큰 이유는?