FDR 과 실무 조정 — 등분산 위반·균등 표본

False Discovery Rate 의 도출과 BH 절차 + 가정 위반 시의 다중 비교 보정

Maxwell Ch.5 의 마지막 두 주제 — False Discovery Rate (FDR) 와 가정 위반 시의 다중 비교 보정을 정리한다. FDR 의 정의, BH 절차, 검정력 우위, 그리고 등분산 위반 또는 불균형 설계에서의 실무 권장을 다룬다.

Experimentation
Fundamentals
저자

Kwangmin Kim

공개

2026년 05월 08일

1 도입 — α_EW 가 아닌 새 통제 대상

지금까지 다룬 절차 (Bonferroni, Holm, Tukey, Scheffé, Dunnett) 는 모두 experimentwise error rate \(\alpha_{EW}\) 를 통제한다. 그러나 수천~수백만 개 의 가설 검정 (예: GWAS, 유전체 분석) 에서는 이 방식이 너무 보수적 이다.

대안은 False Discovery Rate (FDR) 통제. 이 글은 FDR 의 정의, 도출, BH 절차, 그리고 실무 조정 (등분산 위반 시 등) 을 다룬다.

2 FDR — 새로운 통제 대상

정의: False Discovery Rate (FDR)

기각된 가설 (양성 결과) 중 거짓 양성의 비율 의 기댓값.

\[ \text{FDR} = E\left[\frac{V}{R}\right] \]

여기서 \(V\) 는 거짓 양성 수, \(R\) 은 기각된 가설 수 (전체 양성). \(R = 0\) 이면 \(V/R = 0\) 정의.

2.1 FDR vs \(\alpha_{EW}\) 의 차이

측면 \(\alpha_{EW}\) FDR
통제 대상 한 실험의 거짓 양성 발생 확률 발견 중 거짓 비율
단위 실험 단위 발견 단위
검정력 보수적 (낮음) 자유 (높음)
유리한 시나리오 의사결정 (신약 승인) 발견 (가설 생성)
직관 — FDR 의 의미

FDR = 0.05 의 의미: “기각된 가설 100 개 중 평균 5 개가 거짓이다.”

이는 전체 검정 중 거짓 양성 비율 이 아니라, 발견된 것 중 거짓 비율 이다. 따라서 발견이 많아도 비율 통제 가 보장된다.

GWAS 에서 100 만 개 SNP 검정 → Bonferroni 면 임계값 매우 작아 발견이 거의 0. FDR 통제면 발견은 많이 하되 그중 5 % 만 거짓 으로 허용. 후자가 더 생산적.

A/B 테스트의 탐색적 분석 (수십 개 메트릭, 수십 개 segment) 에도 비슷한 논리 적용.

3 Benjamini-Hochberg (BH) 절차

정의: BH 절차 (Benjamini & Hochberg 1995)

\(C\) 개 가설의 p 값을 오름차순 정렬: \(p_{(1)} \leq p_{(2)} \leq \cdots \leq p_{(C)}\).

\(k\) 에 대해 임계값:

\[ \alpha_k = \frac{k}{C} \cdot \alpha \]

가장 큰 \(k^*\) 를 찾는다: \(p_{(k^*)} \leq \alpha_{k^*}\).

\(k^*\) 까지의 모든 가설을 기각.

3.1 도출 (간략)

BH 의 핵심 아이디어: 발견 비율 통제는 발견 수에 비례한 임계값 을 사용하면 가능.

각 단계에서 임계값이 그 단계까지의 발견 수 에 비례 (\(k/C\)). 이는 작은 p 값 (강한 증거)엄격한 임계값, 큰 p 값 (약한 증거)덜 엄격한 임계값 을 부여.

원 논문 (Benjamini & Hochberg 1995) 에서 독립 검정 하에서 FDR ≤ \(\alpha\) 를 증명. 이후 (Benjamini & Yekutieli 2001) 에서 양의 상관 검정 하에서도 통제 보장.

3.2 사례 — 5 개 p 값

p 값: \((0.001, 0.012, 0.025, 0.04, 0.08)\), \(\alpha = 0.05\).

\(k\) \(p_{(k)}\) 임계값 \(k/C \cdot \alpha = k/5 \cdot 0.05\) 통과?
1 0.001 0.010 Yes
2 0.012 0.020 Yes
3 0.025 0.030 Yes
4 0.04 0.040 Yes
5 0.08 0.050 No

가장 큰 통과 \(k^* = 4\). 4 개 가설 기각.

비교:

  • Bonferroni: 1 개 기각
  • Holm: 2 개 기각
  • BH (FDR): 4 개 기각

FDR 이 훨씬 자유로움.

4 FDR 의 적절한 시점

시나리오 FDR 적합?
신약 승인 결정 No → \(\alpha_{EW}\) 엄격
임상 1 차 결과 No → \(\alpha_{EW}\) 엄격
탐색적 가설 생성 Yes → FDR
GWAS·유전체 Yes → FDR
다중 메트릭 + 다중 segment 탐색 Yes → FDR
Robustness check Yes → FDR (보고용)

5 등분산 위반 시 다중 비교

A-MAX3-4 에서 등분산 가정의 영향을 다뤘다. 다중 비교에서도 마찬가지로 Welch 보정 적용 가능.

5.1 Games-Howell 절차

Tukey HSD 의 등분산 약화 변형.

\[ t_{GH} = \frac{|\bar{Y}_i - \bar{Y}_j|}{\sqrt{\frac{s_i^2}{n_i} + \frac{s_j^2}{n_j}}} \]

자유도는 Welch-Satterthwaite 공식으로 그룹별 분산 사용.

5.2 사용 시점

  • Levene 또는 Brown-Forsythe 검정에서 등분산 위반 발견
  • 그룹별 분산이 강하게 다름

6 불균형 설계 (Unequal Sample Sizes)

6.1 Tukey-Kramer 변형

균형 Tukey HSD 의 불균형 일반화:

\[ q = \frac{|\bar{Y}_i - \bar{Y}_j|}{\sqrt{\frac{\text{MS}_W}{2} \left(\frac{1}{n_i} + \frac{1}{n_j}\right)}} \]

균형 사례와 거의 동일한 검정력 유지.

6.2 Scheffé 의 강건성

Scheffé 는 불균형 설계와 등분산 위반 모두에 근본적으로 강건. 이는 검정력 손실의 대가로 얻는 안정성.

7 절차 매트릭스 — 가정·구조별 권장

가정 / 구조 모든 쌍 vs 대조군 일반 대비 많은 가설
등분산 + 균형 Tukey HSD Dunnett Holm FDR
등분산 + 불균형 Tukey-Kramer Dunnett Holm FDR
등분산 위반 Games-Howell Dunnett’s T3 Holm FDR
강한 비대칭 Kruskal-Wallis 후 비모수 사후 Permutation FDR

이 매트릭스가 모든 시나리오 에서 적절한 절차를 제안한다.

8 A/B 테스트 다중성 — 실무 가이드

8.1 시나리오 1 — 다중 변형 + 단일 메트릭

A/B/C/D 테스트, 클릭률만 검정.

권장: Dunnett (대조군 vs 처치군 3 개).

8.2 시나리오 2 — 단일 변형 + 다중 메트릭

A vs B, 클릭률·매출·체류시간·리텐션 검정.

권장: - Primary metric (예: 매출) 사전 지정 → 그것만 \(\alpha = 0.05\) - Secondary metrics (3 개) → FDR 보정 또는 Bonferroni \(\alpha / 3\)

8.3 시나리오 3 — 다중 변형 + 다중 메트릭

A/B/C 테스트, 4 메트릭. 비교 수 = \(2 \times 4 = 8\).

권장: FDR (BH). 또는 primary metric 만 Dunnett, secondary metrics 는 FDR 의 계층화.

8.4 시나리오 4 — 다중 segment 분석

A vs B, 매출만 검정. 그러나 전체·모바일·데스크톱·신규·기존 5 segment 분석.

권장: - 사전 등록: 전체 분석 만 confirmatory - Segment 분석 은 exploratory + FDR 보정

8.5 시나리오 5 — Sequential Testing

매일 결과 모니터링.

권장: Alpha spending (Pocock, OBF) 또는 Always-valid inference (mSPRT). 자세한 내용은 Phase F 시리즈에서.

9 보고 형식 — 모범 사례

A/B/C/D 테스트 결과

옴니버스 ANOVA:
  F(3, 76) = 8.21, p < 0.001, η² = 0.245

대조군 vs 신규 변형 (Dunnett):
  대조군 vs B: 차이 = +0.5 %, t = 1.85, p = 0.06 (Dunnett 보정)
  대조군 vs C: 차이 = +1.2 %, t = 4.42, p < 0.001
  대조군 vs D: 차이 = +0.8 %, t = 2.97, p = 0.012

결론: C 가 통계적·실용적으로 가장 우수. C 채택.

이 형식이 옴니버스 + 사후 보정 + 효과 크기 + 의사결정 의 완전한 보고이다.

10 가정 위반에 대한 강건한 절차

10.1 비모수 다중 비교

Kruskal-Wallis 후 Dunn 절차 (비모수 사후) 또는 Steel-Dwass (비모수 Tukey).

# scikit-posthocs 라이브러리
from scikit_posthocs import posthoc_dunn
result = posthoc_dunn(df, val_col='y', group_col='group', p_adjust='bh')

10.2 Bootstrap 다중 비교

각 비교에 부트스트랩 CI 구성 + Bonferroni 또는 FDR 보정.

10.3 Permutation 다중 비교

각 비교에 permutation p 값 + Holm 또는 FDR 보정.

11 Closed Testing Procedure

다중 비교의 통합 프레임워크 가 closed testing procedure (Marcus, Peritz, & Gabriel 1976).

11.1 원리

가설들의 모든 부분 집합교집합 가설 을 옴니버스로 검정. 각 부분 집합에서 옴니버스가 유의해야 그 안의 개별 가설을 기각 가능.

11.2 함의

  • \(\alpha_{EW}\) 통제 자동 보장
  • 일부 절차 (Holm, Hochberg) 가 closed testing 의 특수 사례

자세한 이론은 Hochberg & Tamhane (1987) 참조.

12 코드 예시 — FDR + 가정 진단

import numpy as np
import pandas as pd
from scipy.stats import levene
from statsmodels.stats.multitest import multipletests
from statsmodels.stats.multicomp import pairwise_tukeyhsd

np.random.seed(42)
n_each = 30

# 시뮬레이션 — 등분산 위반 + 4 그룹
group_A = np.random.normal(5.0, 0.5, n_each)
group_B = np.random.normal(5.5, 1.0, n_each)
group_C = np.random.normal(6.0, 1.5, n_each)
group_D = np.random.normal(6.5, 2.0, n_each)

# 등분산 진단
stat, p_levene = levene(group_A, group_B, group_C, group_D, center='median')
print(f"Brown-Forsythe: stat = {stat:.3f}, p = {p_levene:.4f}")
if p_levene < 0.05:
    print("  → 등분산 위반, Welch 또는 Games-Howell 권장")

# 다중 비교의 다양한 보정 (10 개 가상 p 값)
np.random.seed(123)
p_values = np.sort(np.random.uniform(0, 0.2, 10))
print(f"\np 값 (정렬됨): {p_values}")

methods = ['bonferroni', 'holm', 'hommel', 'fdr_bh', 'fdr_by']
print(f"\n절차별 기각 수:")
for m in methods:
    rej, p_adj, _, _ = multipletests(p_values, alpha=0.05, method=m)
    print(f"  {m:15s}: {rej.sum()} / {len(p_values)} 기각")
    if m == 'fdr_bh':
        for i, (p_orig, p_a, r) in enumerate(zip(p_values, p_adj, rej)):
            mark = "*" if r else " "
            print(f"     {mark} p_orig = {p_orig:.4f} → p_adj = {p_a:.4f}")

# Tukey HSD on actual data
data_df = pd.DataFrame({
    'y': np.concatenate([group_A, group_B, group_C, group_D]),
    'g': ['A']*n_each + ['B']*n_each + ['C']*n_each + ['D']*n_each
})
tukey_result = pairwise_tukeyhsd(data_df['y'], data_df['g'], alpha=0.05)
print(f"\n--- Tukey HSD ---")
print(tukey_result)

13 FDR 의 자세한 변형

13.1 Benjamini-Hochberg (BH)

A-MAX5-4 의 표준. 독립 또는 양의 상관 검정에서 정확.

13.2 Benjamini-Yekutieli (BY)

BH 의 변형. 임의 의존성 에 robust. 더 보수적.

from statsmodels.stats.multitest import multipletests

p_values = np.array([0.001, 0.012, 0.025, 0.04, 0.08, 0.15])

# BH (양의 상관)
reject_bh, p_bh, _, _ = multipletests(p_values, alpha=0.05, method='fdr_bh')

# BY (임의 의존성)
reject_by, p_by, _, _ = multipletests(p_values, alpha=0.05, method='fdr_by')

print("BH 기각:", reject_bh.sum())
print("BY 기각:", reject_by.sum())

13.3 Adaptive FDR

진정한 영가설 비율 (\(\pi_0\)) 추정 + BH.

\[ \text{adjusted } \alpha_k = \frac{k}{C \cdot \hat{\pi}_0} \cdot \alpha \]

진정한 효과가 많으면 \(\hat{\pi}_0 < 1\) → 더 많은 발견.

13.4 Storey’s q-value

각 가설의 FDR 조정 p 값 직접 추정. q-value 가 일반적인 보정 p 값보다 정보적.

# Storey's q-value (statsmodels 에 직접 X, R 의 qvalue 패키지)
# 단순 근사: BH p 값

14 FDR 의 시뮬레이션 비교

import numpy as np
from statsmodels.stats.multitest import multipletests
from scipy.stats import ttest_ind

np.random.seed(42)
n_simulations = 1000
n_tests = 100
true_effect_proportion = 0.20  # 20 % 가 진짜 효과

# 시뮬레이션 1 — 무보정
fdr_uncorrected = []
power_uncorrected = []

for _ in range(n_simulations):
    p_values = []
    is_true_effect = []
    for i in range(n_tests):
        if np.random.random() < true_effect_proportion:
            x = np.random.normal(0.5, 1, 30)  # 효과 있음
            y = np.random.normal(0, 1, 30)
            is_true_effect.append(True)
        else:
            x = np.random.normal(0, 1, 30)  # 효과 없음
            y = np.random.normal(0, 1, 30)
            is_true_effect.append(False)
        _, p = ttest_ind(x, y)
        p_values.append(p)

    p_values = np.array(p_values)
    is_true_effect = np.array(is_true_effect)

    # 무보정
    rejected = p_values < 0.05
    if rejected.sum() > 0:
        fdr_uncorrected.append((rejected & ~is_true_effect).sum() / rejected.sum())
    power_uncorrected.append((rejected & is_true_effect).sum() / is_true_effect.sum())

print(f"무보정: FDR = {np.mean(fdr_uncorrected):.3f}, Power = {np.mean(power_uncorrected):.3f}")
# FDR 0.20 ~ 0.30 (목표 0.05 초과)

이 시뮬레이션이 FDR 보정의 가치 정량화. 무보정은 FDR 폭증.

15 A/B 테스트의 FDR 적용

15.1 다중 segment 분석

import numpy as np
from statsmodels.stats.multitest import multipletests
from scipy.stats import chi2_contingency

# 가상 자료 — A/B 테스트 + 10 개 segment
np.random.seed(42)
segments = ['모바일', '데스크톱', '태블릿', '신규', '기존',
            'iOS', 'Android', '서울', '부산', '국제']

p_values = []
effects = []
for seg in segments:
    n_per = 1000
    p_control = 0.05
    # 일부 segment 에 진짜 효과 (모바일, 신규)
    p_treatment = 0.06 if seg in ['모바일', '신규'] else 0.05
    control = np.random.binomial(1, p_control, n_per)
    treatment = np.random.binomial(1, p_treatment, n_per)
    table = [[treatment.sum(), n_per - treatment.sum()],
             [control.sum(), n_per - control.sum()]]
    _, p, _, _ = chi2_contingency(table)
    p_values.append(p)
    effects.append(treatment.mean() - control.mean())

# Bonferroni vs FDR
reject_bonf, p_bonf, _, _ = multipletests(p_values, alpha=0.05, method='bonferroni')
reject_fdr, p_fdr, _, _ = multipletests(p_values, alpha=0.05, method='fdr_bh')

print("Segment 별 효과:")
for seg, p_orig, e, b, f in zip(segments, p_values, effects, reject_bonf, reject_fdr):
    print(f"  {seg}: 효과 {e*100:+.2f} %, p = {p_orig:.4f}, "
          f"Bonf: {'유의' if b else '미유의'}, FDR: {'유의' if f else '미유의'}")

FDR 가 더 많은 발견 을 자유롭게 함. 그러나 false discoveries 의 비율 은 통제.

16 Multiple Testing 의 미래

16.1 Online FDR Control

지속적인 검정 시나리오 (예: 매일 A/B 테스트). 온라인 FDR 통제.

  • LORD (Levels based On Recent Discovery)
  • SAFFRON (Smoothed Adaptive Forward FDR)

이 절차들이 동적 보정 으로 시간에 따른 FDR 통제.

16.2 Knockoffs

새 다중 검정 도구 (Barber & Candès 2015). 가짜 변수 (knockoff) 를 만들고 진짜와 비교 → FDR 통제.

머신러닝 + 통계의 융합 도구. 점차 표준 채택.

17 Ch.5 마무리 — 다중 비교의 종합

Maxwell Ch.5 의 5 단계 흐름이 끝난다.

  1. Overview (A-MAX5-0)
  2. 3 오류율 + 동시 CI (A-MAX5-1)
  3. Hsu 5 강도 + Bonferroni (A-MAX5-2)
  4. Tukey, Scheffé, Dunnett (A-MAX5-3)
  5. FDR + 실무 조정 (이 글)

17.1 핵심 통찰 정리

  1. 다중 비교는 보정 필수 — 비교가 많을수록 거짓 양성 폭증
  2. 통제 대상 선택\(\alpha_{EW}\) vs FDR vs \(\alpha_{PC}\) 는 의사결정
  3. 절차 선택은 비교 구조 — 모든 쌍 (Tukey), vs 대조군 (Dunnett), 임의 대비 (Scheffé), 많은 가설 (FDR)
  4. 사전 등록의 중요성 — Planned 비교가 사후 보정의 보수성을 회피

18 A-MAX5 시리즈가 후속 시리즈로 이어짐

  • A-SCH19-* — 임상시험에서의 다중성 (multiplicity in clinical trials)
  • Phase F-* — A/B 테스트의 sequential testing 과 alpha spending
  • Phase I-* — 다중 변형의 베이즈/MAB 접근

다중 비교는 통계 추론의 근본적 도전이며, 분야마다 다른 도구 가 발전했다. Ch.5 가 그 토대를 제공한다.

19 관련 주제

선행 지식

후속 주제 (Phase A)

  • A-SCH19-* (임상시험 다중성)

다른 카테고리 연결

Subscribe

Enjoy this blog? Get notified of new posts by email: