9강 / 20강
잡음 걸러내기 — 저발현 유전자 필터
불리언 마스크 한 줄로 24,419 → 13,095
표에 유전자가 24,419개 있지만, 그중 상당수는 이 세포에서 거의 켜지지 않았습니다. 7개 샘플 전부에서 0이거나, 어쩌다 1~2개 읽힌 유전자들이죠.
이런 유전자를 통계에 넣으면 두 가지 손해가 납니다.
- 가짜 발견이 늘어납니다. 0과 2를 비교하면 "무한대 배 증가!" 같은 극단적인 값이 튀어나옵니다. 우연히 하나 더 읽힌 것뿐인데요.
- 진짜 발견이 묻힙니다. 나중에 다중검정 보정을 할 때 검사 대상이 많을수록 기준이 가혹해져서, 애먼 유전자가 희생됩니다.
keep = (raw.sum(1) >= 10) & ((raw >= 1).sum(1) >= 3)
└ 7샘플 합이 10개 이상 ┘ └ 최소 3개 샘플에서 1개 이상 읽힘 ┘
두 조건을 모두 만족해야 남깁니다. 첫 조건은 "총량이 너무 적으면 탈락", 둘째 조건은 "한 샘플에서만 튀어나온 값이면 탈락"이에요. KD 그룹이 3개니까 최소 한 그룹에서는 전부 읽혀야 한다는 뜻이 됩니다.
24,419 → 13,095. 절반 가까이가 잡음이었습니다.
Python
브라우저에서 실행
🎮 필터 기준을 바꿔 보기
두 기준을 움직이면 몇 개가 남는지 즉시 나옵니다. 너무 느슨하면 잡음이, 너무 빡빡하면 진짜가 사라집니다. Ddx54 · Cd47 · Cd38 · Myc 가 살아남는지 꼭 같이 확인하세요.
필터 뒤에 정규화를 다시 하는 이유
코드랩을 자세히 보면, CPM 을 두 번 계산합니다.
한 번은 녹다운 확인용(cpm0), 그리고 필터 뒤에 다시 한 번.
cf = counts.loc[keep]
lib = cf.values.sum(0) # 필터 뒤 표로 라이브러리 크기를 다시 계산
logcpm = np.log2(cf.values / lib * 1e6 + 1)
버린 유전자들이 차지하던 몫이 있으니, 남은 표의 총합은 처음과 다릅니다. 지금 쓰는 표를 기준으로 다시 나눠야 "100만 개당 몇 개"가 정확해집니다.
이 logcpm 표가 10~13강 통계의 입력이 됩니다.
Python
브라우저에서 실행
🤔 확인 문제
(raw >= 1).sum(1) >= 3 이 걸러 내는 것은?해설
raw >= 1 로 True/False 표를 만든 뒤 .sum(1) 로 몇 개 샘플에서 읽혔는지를 셉니다. 3개 미만이면 우연히 튄 값일 가능성이 커서 버립니다.🤔 확인 문제
두 조건을 이을 때
and 대신 & 를 쓰는 이유는?해설
and 는 값 하나의 참·거짓을 따집니다. 24,419칸짜리 배열에는 쓸 수 없어 ValueError 가 납니다. 원소마다 AND 하려면 & 를 써야 합니다.🤔 확인 문제
필터한 뒤에 라이브러리 크기를 다시 계산하는 이유는?
해설 정규화는 '지금 쓰는 표의 총합'을 기준으로 해야 뜻이 맞습니다. 절반 가까운 유전자를 버렸으니 총합도 달라졌고, 그래서
lib = cf.values.sum(0) 로 다시 잽니다.