C.W.K.
Stream
Lesson 04 of 06 · published

P-Hacking 과 다중 비교

~12 min · p-hacking, multiple-comparisons, replication-crisis, garden-of-forking-paths

Level 0통계 초심자
0 XP0/55 lessons0/14 achievements
0/100 XP to next level100 XP to go0% complete
"충분한 비교로, *종 곡선이 우연으로 유의를 건네줄 거야*. *재현 위기는 이게 발견으로 오인될 때 일어나는 일*."

메커니즘

*참 귀무가설 하, ~5% 통계 검정이 *순 우연으로* p < 0.05 받음* (*α = 0.05 에서 Type I 오류율*). *귀무에 대해 20 개 독립 검정 돌리면, 기댓값은 *실제 일어나는 일이 없는데도 하나가 '유의' 할 것**.

*'P-hacking' 은 이걸 이용하는 것* — *명시적으로 또는 우발적으로* — *많은 검정 돌려서, p < 0.05 친 것 선택, *그것만* 보고*. *보고된 p-value 가 *묘사하는 단일 검정에 대해서는 기술적으로 맞아*. *선택 과정 — 많이 보고 하나 보고 — 이 문제*. *출판된 p-value 는 *연구자가 결과 보기 전에 주사위를 여러 번 던졌다는 사실을 누락*.

흔한 형태

  • 많은 결과 지표 시도: *'15 가지 다른 것 측정; 하나가 통계적으로 유의'*. *놀랍지 않음*.
  • 많은 하위그룹 시도: *'전체적 효과는 없지만, *30-40 세 왼손잡이 여성에서 p < 0.05 결과**.
  • 많은 모델 명세 시도: *'이 공변량 사용하고 이 이상치 제외하면, 효과가 유의해짐'*.
  • 결과가 유리할 때 데이터 수집 중단: *'p 가 0.05 를 가로지를 때까지 연구 돌리고 멈춤'*.
  • 'forking paths 의 정원': *연구자가 많은 작은 분석 결정을 하고, 합쳐서 *많은 암묵적 검정을 돌리는 것에 해당* — *p-hack 의도 없이도*.

다중 비교 보정

*많은 검정을 돌려야 할 때 해결책*은 *비교 수에 대해 임계를 *보정*하는 것*. *Bonferroni 보정이 가장 간단*: *M 검정 돌리면, 검정당 임계를 α/M 으로 낮춤*. 20 검정 = 각각 α = 0.05/20 = 0.0025. *보수적*; *고차원 설정에서 *더 나은 절차* (False Discovery Rate, Benjamini-Hochberg) 존재*.

*사전 등록 (Pre-registration) 이 사회적 해결책*: *측정할 것, 어떻게 측정할 것인지, 어떤 검정 돌릴지 사전에 발표*. *그러면 *어떤 '탐색적' 분석도 그렇게 라벨링되고 확정적으로 가장할 수 없음*.

시민의 sniff 테스트

*결과가 '단일 유의 발견' 으로 제시될 때 물어*: *'연구자가 이걸 찾기 위해 *몇 개를 봤어*?'*. *단일 보고 p-value 는 *그걸 만든 선택 과정에 대해 아무것도 안 알려줘*. *재현 위기는 *전체 분야가 이 질문을 잊을 때 일어나는 일*. *사전 등록, p-curve 분석, 다중 비교 보정이 *분야가 정직을 되돌리기 위해 발명한 도구*.

Code

다중 검정 하 false-positive 인플레이션·python
import numpy as np
from math import erf, sqrt
rng = np.random.default_rng(140)

# *참 귀무 하 충분한 검정으로 '유의' 가 *거의 어딘가에서 보장*되는 걸 보임
# — *순 우연, 실제 효과 없음*.

N_per_test = 200
M_tests_per_experiment = 20
M_experiments = 5_000
p_true = 0.5     # 귀무가 어디서나 참

# 추적: *20 검정의 각 실험에서, 적어도 하나가 p<0.05 받는 빈도*?
hit_rate_at_alpha_05 = 0
for _ in range(M_experiments):
    significant = False
    for _ in range(M_tests_per_experiment):
        flips = rng.binomial(n=1, p=p_true, size=N_per_test)
        p_hat = flips.mean()
        z = (p_hat - 0.5) / np.sqrt(0.5 * 0.5 / N_per_test)
        p_val = 2 * 0.5 * (1 - erf(abs(z) / sqrt(2)))
        if p_val < 0.05:
            significant = True
            break
    if significant:
        hit_rate_at_alpha_05 += 1

print(f"P(20 검정 중 적어도 하나가 참 귀무 하 p<0.05 침): "
      f"{hit_rate_at_alpha_05 / M_experiments:.4f}")
print(f"예상: 1 - 0.95^20 = {1 - 0.95**20:.4f}")
print(f"\n20 검정에 대한 Bonferroni-보정 임계: alpha = 0.05/20 = 0.0025")
# *20 귀무 검정을 돌린 '실험' 의 약 64% 가 적어도 하나의 '유의' 결과 가짐*
# — *순 노이즈, 실제 효과 없음*. *그게 평이한 숫자로의 다중 비교 위험*.

External links

Exercise

*뉴스에서 기억나는 최근 놀라운 과학 발견* 식별 (커피 연구, 와인 연구, 영양 연구, 행동 발견). 물어: *이게 사전-등록된 확정적 연구야, 아니면 연구자가 많은 변수를 본 탐색적 분석이야*? *탐색적이면 보고된 p-value 가 거의 확실히 증거 강도를 과장*. *재현 안 되는 발견 대부분이 이 카테고리에서 옴*.
Hint
*사전-등록된 연구가 훨씬 더 재현 가능한 경향*. *탐색적 분석은 가설 생성에 유용하지만 확정적인 것처럼 보고되어선 안 됨*.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.