1 도입 — 강도가 다른 5 가지 추론
다중 비교 절차는 동일하지 않다. Hsu (1996) 는 이들을 추론의 강도 로 5 단계 분류했다. 강도가 높을수록 세밀한 결론 을 주지만 더 큰 표본 이 필요하다.
이 글은 (a) Hsu 의 5 단계 분류, (b) Bonferroni 절차의 자세한 도출, (c) Holm 의 시퀀셜 보정을 다룬다.
2 Hsu 의 5 추론 강도
다중 비교 절차의 결론의 정밀성 에 따라 5 단계로 분류된다.
| 수준 | 추론 | 절차 예시 |
|---|---|---|
| 0 | “어디든 차이가 있는가?” (옴니버스) | F 검정 |
| 1 | “어느 처치가 baseline 보다 다른가?” | Dunnett |
| 2 | “모든 쌍 중 어느 것이 다른가?” | Tukey HSD |
| 3 | “어느 쌍이 어느 방향으로 다른가?” + 신뢰 구간 | Tukey HSD + CI |
| 4 | “모든 가능한 대비의 동시 추론” | Scheffé |
수준이 높을수록 더 강한 결론 을 주지만 더 보수적 이다. 따라서 연구 질문 이 결정한다.
2.1 수준 0 — 옴니버스 검정
ANOVA F 검정. “어떤 차이가 있는가?” 만 답한다. 어느 그룹 인지는 모름.
2.2 수준 1 — vs Baseline
대조군 (baseline) vs 처치군들. Dunnett 절차 가 표준.
A/B 테스트의 “대조군 vs 신규 변형들” 시나리오에 적합.
2.3 수준 2 — 모든 쌍 비교
모든 가능한 쌍 (\(J\) 그룹 → \(\binom{J}{2}\) 쌍) 비교. Tukey HSD 가 표준.
“어느 처치들이 서로 다른가?” 를 답함.
2.4 수준 3 — 모든 쌍 + 방향 + CI
수준 2 + 효과의 방향 + 신뢰 구간. Tukey HSD 의 동시 CI 형태.
“A 가 B 보다 [3.2, 5.8] 만큼 우수하다” 같은 정량적 결론.
2.5 수준 4 — 모든 가능한 대비
쌍별이 아닌 모든 가능한 대비 (예: 한 그룹 vs 나머지, 두 그룹 vs 두 그룹). Scheffé 가 표준.
가장 강력하지만 가장 보수적.
3 Bonferroni 절차 — 가장 단순한 보정
\(C\) 개의 비교를 동시 검정할 때, 각 비교를 다음 임계값으로 검정:
\[ \alpha_{PC} = \frac{\alpha_{EW}}{C} \]
또는 동등하게, p 값을 \(C\) 배 곱하여 수정된 p 값 으로 보고:
\[ p_{\text{adj}} = \min(C \cdot p, 1) \]
3.1 도출 — Bonferroni 부등식
A-MAX5-1 에서 다룬 부등식:
\[ \Pr\left(\bigcup_{k=1}^{C} A_k\right) \leq \sum_{k=1}^{C} \Pr(A_k) \]
\(A_k\) = “비교 \(k\) 가 거짓 양성”, \(\Pr(A_k) = \alpha_{PC}\).
각 \(\alpha_{PC} = \alpha / C\) 로 두면:
\[ \alpha_{EW} = \Pr\left(\bigcup A_k\right) \leq C \cdot \frac{\alpha}{C} = \alpha \]
\(\alpha_{EW} \leq \alpha\) 불평등으로 보장. 보수적.
부등식의 불평등성 이 보수성의 원천이다.
\(\Pr(A \cup B) = \Pr(A) + \Pr(B) - \Pr(A \cap B)\). 일반적으로 \(\Pr(A \cap B) > 0\) 이므로
\[ \Pr(A \cup B) < \Pr(A) + \Pr(B) \]
Bonferroni 는 마지막 항을 무시 하고 상한 만 사용한다. 비교들이 서로 양의 상관 이면 (\(\Pr(A \cap B) > 0\), 즉 한 비교가 거짓 양성이면 다른 비교도 거짓 양성일 확률이 높음), 실제 \(\alpha_{EW}\) 는 \(C \cdot \alpha_{PC}\) 보다 훨씬 작다.
따라서 Bonferroni 는 비교가 독립이거나 음의 상관일 때만 정확. 양의 상관에서는 과한 보수성 을 띤다.
A/B 테스트에서 두 메트릭이 강하게 상관 (예: 클릭률과 매출) 되어 있으면, Bonferroni 는 필요 이상으로 보수적이다. 이때 FDR 또는 상관 구조를 반영한 보정 이 더 효율적.
4 Bonferroni 의 검정력 손실
검정력은 \(\alpha_{PC}\) 가 작을수록 떨어진다. Bonferroni 보정으로 \(\alpha_{PC}\) 가 \(\alpha / C\) 가 되면, 검정력이 다음과 같이 감소한다 (Cohen’s \(d\) 가 0.5 인 경우 예시).
| \(C\) | \(\alpha_{PC}\) | 단일 비교 검정력 | 모든 비교 동시 검정력 |
|---|---|---|---|
| 1 | 0.050 | 0.80 | 0.80 |
| 3 | 0.0167 | 0.71 | \(\approx 0.36\) |
| 6 | 0.0083 | 0.66 | \(\approx 0.08\) |
| 10 | 0.005 | 0.61 | \(\approx 0.006\) |
비교 수가 늘어날수록 모든 비교에서 검출 할 검정력이 기하급수적 으로 감소한다.
5 Bonferroni 가 적절한 시나리오
| 시나리오 | 적절성 |
|---|---|
| 사전 등록된 소수 (≤ 3) 가설 | 매우 적절 |
| 독립 또는 약한 양의 상관 비교 | 적절 |
| 중간 수의 검정 (≤ 10) | 보통 |
| 많은 검정 (> 10) | 검정력 손실 큼, FDR 고려 |
| 강한 양의 상관 비교 | 과보수적, Tukey 또는 다른 절차 |
6 Holm 시퀀셜 절차 (Step-Down Bonferroni)
Bonferroni 의 검정력 손실을 줄인 변형이 Holm (1979) 의 시퀀셜 절차.
\(C\) 개 비교의 p 값을 오름차순 으로 정렬: \(p_{(1)} \leq p_{(2)} \leq \cdots \leq p_{(C)}\).
순서대로 다음 임계값과 비교:
- \(p_{(1)} < \alpha / C\) → 기각, 다음 단계
- \(p_{(2)} < \alpha / (C - 1)\) → 기각, 다음 단계
- \(p_{(k)} < \alpha / (C - k + 1)\) → 기각, 다음 단계
- 어느 단계에서 기각하지 못하면 그 시점부터 모든 후속 비교도 기각하지 못함.
6.1 Holm 의 장점
- \(\alpha_{EW}\) 보장은 Bonferroni 와 동일
- 그러나 검정력은 항상 Bonferroni 이상 (수학적 사실)
- 가장 작은 p 값에 더 큰 임계값 (Bonferroni 임계값) 을 부여, 후속 검정에 덜 보수적인 임계값 부여
6.2 사용 권장
Bonferroni 가 적절한 모든 시나리오에서 Holm 이 더 효율적. 따라서 언제든 Bonferroni 보다 Holm 권장 (Aickin & Gensler 1996).
Bonferroni 는 모든 비교에 동일한 엄격함 을 적용한다 — \(\alpha / C\). 이는 모든 비교가 대등하다 는 가정.
Holm 은 p 값 순서 로 비교를 평가한다. 가장 작은 p 값 (가장 강한 증거) 부터 시작해 Bonferroni 수준의 엄격함 으로 검정. 그것이 통과되면, 두 번째 비교는 한 단계 덜 엄격한 임계값으로 검정. 등등.
직관적으로: 가장 강한 증거가 통과되면 나머지 비교는 덜 엄격해도 안전 하다. 이것이 검정력 향상의 출처.
이 시퀀셜 사고 가 다중 비교의 핵심 통찰 중 하나이며, FDR 의 BH 절차와도 연결된다.
7 Bonferroni vs Holm — 사례 비교
5 비교, p 값 = (0.001, 0.012, 0.025, 0.04, 0.08), \(\alpha = 0.05\).
7.1 Bonferroni
각 비교의 임계값 = \(0.05 / 5 = 0.01\).
| p | < 0.01? | 결정 |
|---|---|---|
| 0.001 | Yes | 기각 |
| 0.012 | No | 기각 못함 |
| 0.025 | No | 기각 못함 |
| 0.04 | No | 기각 못함 |
| 0.08 | No | 기각 못함 |
기각 1 / 5.
7.2 Holm
| 단계 | p 값 | 임계값 | 결정 |
|---|---|---|---|
| 1 | 0.001 | \(0.05 / 5 = 0.01\) | 기각 |
| 2 | 0.012 | \(0.05 / 4 = 0.0125\) | 기각 (0.012 < 0.0125) |
| 3 | 0.025 | \(0.05 / 3 = 0.0167\) | 기각 못함 (멈춤) |
| 4 | - | - | (자동) 기각 못함 |
| 5 | - | - | (자동) 기각 못함 |
기각 2 / 5. Bonferroni 보다 1 개 더 발견.
8 Šidák 보정 — 독립성 가정 정확
비교들이 독립 이면 Bonferroni 보다 약간 덜 보수적인 정확한 보정이 가능하다.
\[ \alpha_{PC, \text{Šidák}} = 1 - (1 - \alpha)^{1/C} \]
이는 독립 비교 의 정확한 \(\alpha_{EW}\) 통제.
| \(C\) | Bonferroni \(\alpha_{PC}\) | Šidák \(\alpha_{PC}\) |
|---|---|---|
| 3 | 0.0167 | 0.0170 |
| 5 | 0.0100 | 0.0102 |
| 10 | 0.0050 | 0.0051 |
| 20 | 0.0025 | 0.0026 |
차이가 매우 작다. 따라서 실무에서 Šidák 사용은 불필요한 정밀성. Bonferroni 또는 Holm 으로 충분.
9 Bonferroni 가 부적절한 시나리오
9.1 시나리오 1 — 매우 많은 가설 (예: GWAS)
유전체 GWAS 에서 수백만 개 가설 검정. Bonferroni → \(\alpha_{PC} \approx 5 \times 10^{-8}\). 거의 모든 발견 차단.
해법: FDR (BH). 진짜 효과의 비율이 매우 낮을 때 효율적.
9.2 시나리오 2 — 강한 상관 비교
같은 메트릭의 부분 집합 비교 (예: 전체 사용자 vs 신규 사용자 vs 기존 사용자). 상관이 강하면 Bonferroni 가 과보수적.
해법: Hochberg, Hommel (Bonferroni 변형, 양의 상관에서 더 강함).
9.3 시나리오 3 — 계층적 가설
Primary metric (전체 매출) → Secondary metrics (부분 메트릭). 일관된 계층.
해법: Hierarchical testing. Primary 가 유의하면 secondary 들에 전체 \(\alpha\) 를 분배. 자세한 절차는 후속 시리즈에서 다룸.
10 A/B 테스트의 실무 가이드
10.1 시나리오 — 2 변형, 3 메트릭
A vs B, 클릭률·매출·체류시간 검정.
권장: Holm 보정 (Bonferroni 보다 검정력 좋음). 또는 primary metric (예: 매출) 만 \(\alpha = 0.05\) 로, secondary metrics 는 FDR.
10.2 시나리오 — 4 변형, 1 메트릭
대조군 + 신규 3 개의 매출 비교.
권장: Dunnett (1 대조군 vs 처치군들 특화). Bonferroni 는 검정력 약간 손실.
10.3 시나리오 — 다중 사용자 segment 분석
A vs B 의 전체 + 모바일 + 데스크톱 + 신규 + 기존 매출 분석.
권장: 전체 분석은 primary, segment 분석은 exploratory 로 표시 + FDR 보정.
11 코드 예시 — Bonferroni vs Holm
import numpy as np
from statsmodels.stats.multitest import multipletests
p_values = np.array([0.001, 0.012, 0.025, 0.04, 0.08])
# Bonferroni
reject_bonf, p_bonf, _, _ = multipletests(p_values, alpha=0.05, method='bonferroni')
print("Bonferroni:")
for p_orig, p_adj, rej in zip(p_values, p_bonf, reject_bonf):
print(f" p_orig = {p_orig:.4f}, p_adj = {p_adj:.4f}, 기각: {rej}")
# Holm
reject_holm, p_holm, _, _ = multipletests(p_values, alpha=0.05, method='holm')
print("\nHolm:")
for p_orig, p_adj, rej in zip(p_values, p_holm, reject_holm):
print(f" p_orig = {p_orig:.4f}, p_adj = {p_adj:.4f}, 기각: {rej}")
# Hochberg (양의 상관에서 강한 검정력)
reject_hoch, p_hoch, _, _ = multipletests(p_values, alpha=0.05, method='hommel')
print("\nHochberg/Hommel:")
for p_orig, p_adj, rej in zip(p_values, p_hoch, reject_hoch):
print(f" p_orig = {p_orig:.4f}, p_adj = {p_adj:.4f}, 기각: {rej}")
# 비교 — 모든 절차의 기각 수
methods = ['bonferroni', 'sidak', 'holm', 'simes-hochberg', 'hommel', 'fdr_bh']
print("\n절차별 기각 수 (5 비교, p_orig 위와 동일):")
for m in methods:
rej, p_adj, _, _ = multipletests(p_values, alpha=0.05, method=m)
print(f" {m:18s}: {rej.sum()} / {len(p_values)} 기각")이 코드는 6 개 절차 의 결과를 비교한다. 일반적으로 Bonferroni 가 가장 보수적, FDR 이 가장 자유로움.
12 Step-Down vs Step-Up 절차
Step-Down (Holm 1979): 작은 p 값부터 검정. 임계값 증가.
p_(1) < α/C → 기각, p_(2) 검사
p_(2) < α/(C-1) → 기각, p_(3) 검사
...
어느 단계에서 미통과 → 그 단계와 후속 모두 기각 X
Step-Up (Hochberg 1988): 큰 p 값부터 검정. 임계값 감소.
p_(C) < α → 모두 기각 (만족 시)
p_(C-1) < α/2 → ...
...
어느 단계에서 통과 → 그 시점과 *이전* 모두 기각
12.1 차이
| 측면 | Step-Down | Step-Up |
|---|---|---|
| 검정 순서 | 작은 p 부터 | 큰 p 부터 |
| 검정력 | 보통 | 일반적 더 큼 |
| 가정 | 임의 (Bonferroni) | 양의 상관 (필수) |
| 사용 | Holm | Hochberg, Hommel |
Hochberg 가 양의 상관 (대부분의 실무 시나리오) 에서 가장 강력. 그러나 가정 깨지면 보수성 손실.
13 Closed Testing 의 함의
부분 집합의 모든 가설을 옴니버스 로 검정. 여러 절차의 통합 이론.
- 모든 부분 집합 H ⊆ {H_1, H_2, …, H_C} 에 대한 교집합 가설 검정
- 각 부분 집합에서 옴니버스 유의 → 그 안의 개별 가설 기각 가능
- α_EW ≤ α 자동 보장
13.1 Holm 의 closed testing 표현
Holm 절차는 closed testing 의 특수 사례.
증명 (스케치):
- 부분 집합 H 의 옴니버스 검정 = 그 안의 최소 p 값 의 검정
- α/|H| 임계값 사용
- Step-down 으로 유효성 보장
13.2 Hochberg 와 Hommel 의 차이
- Hochberg: 단순 step-up
- Hommel: 더 정교한 closed testing → 더 강한 검정력
실무에서는 Holm 또는 Hochberg/Hommel 모두 가능.
14 다중성과 효과 크기
다중 비교 보정이 효과 크기 추정 에 미치는 영향:
14.1 Selection Bias
여러 효과 중 유의한 것만 선택해서 보고하면 효과 크기 과대 추정.
시뮬레이션:
10 개 효과, 모두 진짜 효과 = 0.2
표본 노이즈로 관측 효과 = 0.0 ~ 0.4 분포
유의한 결과만 선택 (예: |effect| > 0.3)
→ 평균 관측 효과 ≈ 0.4 (진짜 0.2 보다 2 배)
이것이 selection bias.
14.2 해법
- 모든 결과 보고 (유의 + 미유의)
- 사전 등록
- Empirical Bayes shrinkage (베이즈 통합)
14.3 Empirical Bayes Shrinkage
여러 효과의 평균 으로 각 효과 추정 shrink. 큰 효과는 작아지고, 작은 효과는 거의 그대로.
import numpy as np
# 10 개 관측 효과
effects = np.array([0.10, 0.15, 0.20, 0.25, 0.30, -0.05, 0.05, 0.40, 0.10, 0.20])
# Empirical Bayes 단순 적용
mean_effect = effects.mean()
var_effect = effects.var(ddof=1)
shrinkage_factor = var_effect / (var_effect + 1.0) # 단순화
shrunk_effects = mean_effect + shrinkage_factor * (effects - mean_effect)
print("원 효과 vs Shrunk 효과:")
for orig, shrunk in zip(effects, shrunk_effects):
print(f" {orig:+.3f} → {shrunk:+.3f}")이 절차가 극단값을 보수적으로 처리. A/B 테스트의 다중 segment 분석에 유용.
15 A/B 테스트의 Bonferroni 결정 트리
A/B 테스트 시나리오?
↓
1 metric, 2 variants
→ 보정 불필요
1 metric, 3+ variants (multi-arm)
→ Dunnett (대조군 vs 처치군)
또는 Tukey HSD (모든 쌍)
2+ metrics, 2 variants
Primary + Secondary 분리?
Yes → Primary 만 보정 X, Secondary FDR
No → Bonferroni 또는 Holm
Many segments + many metrics
→ FDR 또는 hierarchical
이 트리가 상황별 보정 의 가이드.
16 Bonferroni 와 Power 계산
표본 크기 산정 시 Bonferroni 영향:
import numpy as np
from scipy.stats import norm
def n_with_bonferroni(p1, p2, n_comparisons=1, alpha=0.05, power=0.80):
"""다중 비교 보정 후 표본 크기"""
alpha_per = alpha / n_comparisons
z_a = norm.ppf(1 - alpha_per/2)
z_b = norm.ppf(power)
num = (z_a + z_b)**2 * (p1*(1-p1) + p2*(1-p2))
return num / (p1 - p2)**2
# 비교 수에 따른 표본 크기
print("비교 수와 표본 크기 (p1=0.10, p2=0.06):")
for n_comp in [1, 2, 5, 10, 20]:
n = n_with_bonferroni(0.10, 0.06, n_comp)
print(f" C = {n_comp}: n_per = {np.ceil(n):.0f}")10 개 비교 시 단일 검정의 2.5 배 표본 필요. 실무 영향 큼.
17 후속 — 절차별 디테일
다음 글 A-MAX5-3 은 Tukey HSD, Scheffé, Dunnett 의 자세한 절차와 사용 시점을 다룬다.
18 관련 주제
선행 지식
후속 주제 (Phase A)
- A-MAX5-3 Tukey HSD, Scheffé, Dunnett
- A-MAX5-4 FDR + 실무 조정
다른 카테고리 연결