주요 다중 비교 절차 — Tukey HSD, Scheffé, Dunnett

쌍별·일반·대조군 비교에 특화된 보정 절차의 도출과 사용

Maxwell Ch.5 의 주요 다중 비교 절차를 정리한다. Tukey HSD (모든 쌍별 비교), Scheffé (모든 가능한 대비), Dunnett (대조군 vs 처치군) 의 임계값 도출, 검정력 비교, 실무 사용 가이드를 다룬다.

Experimentation
Fundamentals
저자

Kwangmin Kim

공개

2026년 05월 08일

1 도입 — 시나리오마다 다른 절차

Bonferroni·Holm 은 일반적 보정 이라 어떤 비교에도 적용 가능하지만 비교의 특수 구조 를 활용하지 않아 보수적이다. 이 글은 Maxwell Ch.5 의 특수 구조 에 맞춘 3 가지 표준 절차를 다룬다.

절차 사용 시점 추론 강도
Tukey HSD 모든 쌍별 비교 수준 2-3
Scheffé 모든 가능한 대비 수준 4
Dunnett 대조군 vs 처치군들 수준 1

2 Tukey HSD

정의: Tukey HSD (Honestly Significant Difference)

\(J\) 그룹의 모든 쌍별 평균 차이동시 검정. \(\alpha_{EW} \leq \alpha\) 보장.

검정 통계량 (균형 설계):

\[ q = \frac{|\bar{Y}_i - \bar{Y}_j|}{\sqrt{\text{MS}_W / n_0}} \]

이는 Studentized range 분포 \(q_{\alpha, J, n - J}\) 를 따른다.

기각 기준: \(q > q_{\alpha, J, n-J}\).

2.1 Studentized Range 분포

\(J\) 정규 변량 \(Z_1, Z_2, \ldots, Z_J\)최대값과 최소값의 차이추정된 표준 오차 로 표준화한 분포.

\[ q = \frac{\max_i Z_i - \min_i Z_i}{\sqrt{S^2 / n}} \]

이 분포가 모든 쌍별 차이의 최대 절댓값 의 분포와 일치한다. Tukey 가 1949 년 도출.

2.2 동시 신뢰 구간 (균형 설계)

\[ (\bar{Y}_i - \bar{Y}_j) \pm q_{\alpha, J, n-J} \cdot \sqrt{\frac{\text{MS}_W}{n_0}} \]

직관 — Tukey 가 Bonferroni 보다 강력한 이유

Bonferroni 는 6 쌍 비교 (4 그룹) 에 \(\alpha / 6 \approx 0.0083\) 사용. 그러나 모든 쌍별 비교가 양의 상관 (같은 자료, 같은 \(\text{MS}_W\)). 이 상관을 무시하면 보수적.

Tukey HSD 는 Studentized range 분포 를 사용해 상관 구조를 정확히 반영. 임계값이 Bonferroni 보다 작아 검정력 향상.

\(J\) \(\binom{J}{2}\) Tukey \(q_{0.05}\) Bonferroni 임계값 (대략)
3 3 약 3.5 약 4.0
4 6 약 3.7 약 4.5
5 10 약 4.0 약 5.0

Tukey 가 항상 Bonferroni 보다 검정력 우수 (모든 쌍별 비교 시).

2.3 불균형 설계의 변형

\(n_j\) 가 그룹마다 다른 경우 Tukey-Kramer 변형:

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

균형 설계와 거의 같은 검정력을 유지한다.

2.4 사용 시점

  • 사후 모든 쌍 비교가 목표
  • 균형 또는 약한 불균형 설계
  • 비슷한 분산 (등분산 가정)

3 Scheffé

정의: Scheffé 절차

모든 가능한 대비 (쌍별이 아닌 임의의 합 0 계수) 의 동시 검정. \(\alpha_{EW} \leq \alpha\) 보장.

대비 \(\psi = \sum c_j \mu_j\) 의 임계값:

\[ F^* = (J - 1) \cdot F_{\alpha, J-1, n-J} \]

기각 기준: \(F = \widehat{\psi}^2 / \text{Var}(\widehat{\psi}) > F^*\), 또는 동등하게

\[ \frac{|\widehat{\psi}|}{\sqrt{\text{Var}(\widehat{\psi})}} > \sqrt{(J-1) \cdot F_{\alpha, J-1, n-J}} \]

3.1 Scheffé 의 일반성

Scheffé 는 어떤 대비도 검정 가능. 사후에 자료를 본 후 새로운 대비를 발견해도 Scheffé 임계값 적용 시 \(\alpha_{EW}\) 가 보존된다.

3.2 보수성

Scheffé 의 임계값 \(\sqrt{(J-1) F_{\alpha, J-1, n-J}}\) 은 다른 절차보다 . 따라서 가장 보수적.

\(J\) Scheffé 임계값 (\(\alpha = 0.05\), \(n = 80\)) Tukey HSD 임계값
3 \(\sqrt{2 \cdot F_{0.05, 2, 77}} \approx 2.49\) \(q_{0.05, 3, 77} / \sqrt{2} \approx 2.39\)
4 \(\sqrt{3 \cdot F_{0.05, 3, 76}} \approx 2.85\) \(q_{0.05, 4, 76} / \sqrt{2} \approx 2.65\)
5 \(\sqrt{4 \cdot F_{0.05, 4, 75}} \approx 3.16\) \(q_{0.05, 5, 75} / \sqrt{2} \approx 2.85\)

Scheffé 가 항상 Tukey 보다 보수적.

3.3 사용 시점

  • 임의의 가능한 대비 를 사후 검정
  • 데이터를 본 후 새로운 가설 발견
  • “어떤 대비라도 통과시켜야 안전한” 보수적 보고

대부분의 실무에서 과한 보수성 이라 사용이 제한적이다. 사후 모든 가능 대비 검정이 정말로 목적인 경우만.

4 Dunnett

정의: Dunnett 절차

하나의 대조군 (group 1) 과 여러 처치군 (groups 2, 3, …, \(J\)) 의 차이 비교.

\(J - 1\) 개 비교: \(\mu_1 - \mu_2\), \(\mu_1 - \mu_3\), …, \(\mu_1 - \mu_J\).

\(\alpha_{EW} \leq \alpha\) 보장.

검정 통계량 (균형 설계):

\[ t_d = \frac{\bar{Y}_1 - \bar{Y}_j}{\sqrt{\text{MS}_W \cdot 2 / n_0}} \]

이는 Dunnett 분포 (수정된 Studentized maximum) 의 분위수 \(d_{\alpha, J-1, n-J}\) 와 비교.

4.1 Dunnett 의 효율성

Dunnett 은 모든 쌍 비교 가 아니라 대조군 vs 처치군 만 검정한다. 비교 수가 \(J - 1\) (Tukey 의 \(\binom{J}{2}\) 보다 적음) 이라 검정력이 더 높다.

\(J\) Tukey 비교 수 Dunnett 비교 수
3 3 2
4 6 3
5 10 4
10 45 9

비교 수가 적을수록 임계값 작음 → 검정력 큼.

4.2 사용 시점

  • 대조군이 명확 (예: 위약, 기존 디자인)
  • 처치군 간 비교는 무관
  • 검정력 극대화 필요

A/B 테스트의 흔한 시나리오: A (대조군) vs B, C, D (신규 변형들).

직관 — 절차 선택의 결정 트리
다중 비교 시나리오?
   ↓
1 대조군 vs 여러 처치군?
   Yes → Dunnett (가장 효율적)
   No → ↓
모든 쌍별 비교?
   Yes → Tukey HSD (균형) 또는 Tukey-Kramer (불균형)
   No → ↓
복합 대비 (한 그룹 vs 평균, 두 그룹 vs 두 그룹) ?
   Yes → Bonferroni 또는 Holm (소수 비교) / Scheffé (다수)
   No → ↓
임의의 가능한 대비 (사후 발견)?
   Yes → Scheffé (보수적이지만 안전)

이 트리가 비교 구조에 가장 적합한 절차 선택의 가이드이다. 잘못된 절차 선택은 검정력 손실 또는 \(\alpha\) 인플레이션을 만든다.

5 검정력 비교

같은 효과 크기, 같은 표본 크기에서 절차별 검정력 비교 (4 그룹 사례):

절차 비교 유형 상대 검정력
무보정 (Per-comparison) 임의 100 % (기준)
Dunnett (대조군 vs 처치군) 3 비교 약 90 %
Tukey HSD (모든 쌍) 6 비교 약 75 %
Bonferroni (6 비교) 임의 약 65 %
Scheffé (모든 대비) 무한 약 55 %

검정력 손실은 비교 구조 와 절차의 적합도 에 따라 다르다. 적합한 절차 선택이 검정력 보존의 핵심.

6 실무 사례

6.1 사례 1 — 임상시험 Phase III

3 용량 (저, 중, 고) + 위약 비교. 위약이 명확한 대조군.

권장: Dunnett. 검정력 극대화 + 명확한 의사결정 (어느 용량이 위약보다 우수한가).

6.2 사례 2 — UI 디자인 다중 변형

대조군 (현재 디자인) + 신규 디자인 A, B, C 의 클릭률 비교.

권장: Dunnett. A/B 테스트의 표준 시나리오.

6.3 사례 3 — 사후 발견 결과

ANOVA 후 자료를 보다가 “그룹 1, 2 vs 그룹 3 의 평균” 같은 사후 가설 발견.

권장: Scheffé. 사후 발견에 안전.

6.4 사례 4 — 수업 비교

5 가지 교습법 (강의, 토론, 자율, 혼합 1, 혼합 2) 의 학습 효과. 모든 쌍 비교가 관심.

권장: Tukey HSD (모든 10 쌍 비교).

7 코드 예시 — 3 절차 비교

import numpy as np
import pandas as pd
from scipy.stats import f, studentized_range
import statsmodels.api as sm
from statsmodels.formula.api import ols
from statsmodels.stats.multicomp import pairwise_tukeyhsd

np.random.seed(42)
n_each = 20
J = 4
group_control = np.random.normal(120, 10, n_each)
group_drug_a = np.random.normal(116, 10, n_each)
group_drug_b = np.random.normal(118, 10, n_each)
group_combined = np.random.normal(110, 10, n_each)

groups = ['control']*n_each + ['drug_a']*n_each + ['drug_b']*n_each + ['combined']*n_each
all_data = np.concatenate([group_control, group_drug_a, group_drug_b, group_combined])
df = pd.DataFrame({'bp': all_data, 'treatment': groups})

# 옴니버스 ANOVA
model = ols('bp ~ C(treatment)', data=df).fit()
anova_table = sm.stats.anova_lm(model)
ms_w = anova_table['mean_sq'].iloc[1]
df_w = int(anova_table['df'].iloc[1])

print("ANOVA F 검정:")
print(anova_table)

# 1. Tukey HSD (모든 쌍별)
print("\n--- Tukey HSD (모든 쌍 비교) ---")
tukey = pairwise_tukeyhsd(df['bp'], df['treatment'], alpha=0.05)
print(tukey)

# 2. Scheffé (자체 구현)
print("\n--- Scheffé (모든 가능한 대비) ---")
F_crit = f.ppf(0.95, J - 1, df_w)
scheffe_critical = np.sqrt((J - 1) * F_crit)
print(f"Scheffé 임계값: √((J-1)·F) = {scheffe_critical:.3f}")

# 임의의 대비 (예: control vs drug_a)
group_means = df.groupby('treatment')['bp'].mean()
c = {'control': 1, 'drug_a': -1, 'drug_b': 0, 'combined': 0}
psi = sum(c[g] * group_means[g] for g in c)
se_psi = np.sqrt(ms_w * sum(c[g]**2 / n_each for g in c))
t_psi = psi / se_psi
print(f"control vs drug_a: ψ = {psi:.2f}, t = {t_psi:.3f}, |t| > {scheffe_critical:.3f}? {abs(t_psi) > scheffe_critical}")

# 3. Dunnett (control 이 대조군)
print("\n--- Dunnett (control vs 각 처치군) ---")
# scipy 또는 statsmodels 에는 Dunnett 직접 구현 없음. statsmodels.stats.multicomp 의 별도 함수 사용
# 대안: pingouin.pairwise_ttests with one_vs_rest
import scipy.stats as stats
# 자체 구현 — Dunnett 임계값 사용 (정확히는 Dunnett 분포가 필요하나, 여기서는 Bonferroni 근사)
print("(Dunnett 분포는 별도 구현 필요. 여기서는 Bonferroni 근사)")
treatments = ['drug_a', 'drug_b', 'combined']
control_mean = group_means['control']
for tx in treatments:
    diff = control_mean - group_means[tx]
    se = np.sqrt(ms_w * (1/n_each + 1/n_each))
    t_dunnett = diff / se
    p_two = 2 * (1 - stats.t.cdf(abs(t_dunnett), df_w))
    p_bonf_approx = min(p_two * 3, 1)  # 3 비교 Bonferroni 근사
    print(f"  control vs {tx}: t = {t_dunnett:.3f}, p (Bonf 근사) = {p_bonf_approx:.4f}")

이 코드는 3 절차의 결과 를 비교한다. 각 절차의 기각/유의 수 가 다를 수 있다.

8 Hochberg, Hommel — 추가 변형

Bonferroni·Holm 의 계열에서 양의 상관 비교 에서 더 강한 검정력을 보이는 변형.

절차 강점
Bonferroni 가장 단순, 가장 보수적
Holm (step-down) Bonferroni 강화, 음의 상관 안전
Hochberg (step-up) 양의 상관에서 강함
Hommel Hochberg 와 비슷, 약간 더 강함

실무에서 비교 사이 상관 구조 를 알면 Hochberg 또는 Hommel 이 가장 강력. 모르면 Holm 으로 안전 선택.

9 Tukey HSD 의 자세한 도출

9.1 Studentized Range 분포

정의: Studentized Range Distribution

\(J\) 정규 변량 \(Z_1, Z_2, \ldots, Z_J\) (평균 0, 분산 \(\sigma^2\), 독립) 와 추정된 분산 \(S^2\) (자유도 \(\nu\)).

\[ q = \frac{\max_i Z_i - \min_i Z_i}{S} \]

이 통계량의 분포가 Studentized range \(q_{J, \nu}\).

9.2 Tukey HSD 의 도출

ANOVA 후 모든 쌍별 비교 (\(\binom{J}{2}\) 개) 의 검정.

핵심 통찰: 최대 차이 가 임계값을 통과하면 모든 작은 차이 도 자동 통제.

따라서 모든 쌍별 비교 의 임계값 = \(q_{\alpha, J, n-J}\).

9.3 검정 통계량

\[ q_{ij} = \frac{|\bar{Y}_i - \bar{Y}_j|}{\sqrt{\text{MS}_W / n_0}} \]

(균형 설계). 기각 기준: \(q_{ij} > q_{\alpha, J, n-J}\).

9.4 Tukey-Kramer (불균형)

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

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

9.5 Tukey HSD 의 강점

import numpy as np
from scipy.stats import studentized_range, f as f_dist

# 4 그룹 비교
J = 4
n_per = 25
df_w = J * (n_per - 1)

# Tukey HSD 임계값
q_tukey = studentized_range.ppf(0.95, J, df_w)
print(f"Tukey q (J=4, df={df_w}): {q_tukey:.3f}")

# Bonferroni 임계값 비교 (6 비교)
from scipy.stats import t as t_dist
n_comp = 6
t_bonf = t_dist.ppf(1 - 0.025/n_comp, df_w)
# Studentized range 와 비교 — q = √2 · t (대략)
q_bonf_equiv = np.sqrt(2) * t_bonf
print(f"Bonferroni 등가 q: {q_bonf_equiv:.3f}")

# 비율
print(f"Tukey 가 Bonferroni 보다 {(q_bonf_equiv/q_tukey - 1)*100:.1f} % 좁음")

Tukey 가 상관 구조 활용 으로 약 5~15 % 더 좁은 임계값 = 검정력 향상.

10 Scheffé 절차의 자세한 도출

10.1 F 분포 기반 임계값

Scheffé 임계값

임의의 대비 \(\psi\) 의 검정 통계량:

\[ F = \frac{\widehat{\psi}^2}{\sum (c_j^2/n_j) \cdot \text{MS}_W} \]

기각 기준: \(F > (J-1) \cdot F_{\alpha, J-1, n-J}\).

또는 동등하게:

\[ \frac{|\widehat{\psi}|}{\sqrt{\text{Var}(\widehat{\psi})}} > \sqrt{(J-1) \cdot F_{\alpha, J-1, n-J}} \]

10.2 임의의 대비

Scheffé 의 일반성: 사전에 정의되지 않은 어떤 대비 도 검정 가능.

# 4 그룹의 임의 대비
J = 4
df_w = 100

F_crit = f_dist.ppf(0.95, J-1, df_w)
scheffe_critical = np.sqrt((J-1) * F_crit)
print(f"Scheffé 임계값: {scheffe_critical:.3f}")

10.3 Scheffé 와 ANOVA F 의 관계

ANOVA 옴니버스 F 가 유의 ↔︎ 적어도 한 Scheffé 대비가 유의.

동치성 이 Scheffé 의 정당성. 옴니버스 정보를 모든 대비로 분배.

11 Dunnett 절차의 자세한 도출

11.1 Dunnett’s t 분포

Dunnett t 분포

대조군 vs 처치군의 t 통계량들의 결합 분포. 이들은 서로 양의 상관 (같은 대조군 사용).

이 상관 구조를 명시적으로 활용 하여 임계값 도출.

# Dunnett 임계값 (자체 라이브러리 또는 mvtnorm)
# scipy 에 직접 없음. R 의 multcomp 가 표준.

11.2 Dunnett vs Bonferroni 비교

\(J\) \(J - 1\) 비교 Dunnett 임계값 Bonferroni 임계값
3 2 약 2.25 약 2.39
4 3 약 2.40 약 2.63
5 4 약 2.51 약 2.79
10 9 약 2.80 약 3.30

Dunnett 이 약 5~15 % 더 효율 (상관 구조 활용).

12 절차 비교 — 동일 시나리오

import numpy as np
import pandas as pd
import statsmodels.api as sm
from statsmodels.formula.api import ols
from statsmodels.stats.multicomp import pairwise_tukeyhsd

np.random.seed(42)
n_per = 25
J = 4

# 4 그룹 자료
data = []
for j in range(J):
    data.extend(np.random.normal(loc=10 + j*0.5, scale=3, size=n_per))
groups = np.repeat(['A', 'B', 'C', 'D'], n_per)
df = pd.DataFrame({'value': data, 'group': groups})

# 1. ANOVA F
model = ols('value ~ C(group)', data=df).fit()
print("ANOVA F 검정:")
print(sm.stats.anova_lm(model, typ=2))

# 2. Tukey HSD
print("\n--- Tukey HSD ---")
tukey = pairwise_tukeyhsd(df['value'], df['group'], alpha=0.05)
print(tukey)

# 3. Scheffé (모든 가능한 대비)
ms_w = sm.stats.anova_lm(model)['mean_sq'].iloc[1]
df_w = int(sm.stats.anova_lm(model)['df'].iloc[1])
F_crit = f_dist.ppf(0.95, J-1, df_w)
scheffe_threshold = np.sqrt((J-1) * F_crit)
print(f"\n--- Scheffé ---")
print(f"임계값: {scheffe_threshold:.3f}")

# 4. Bonferroni (모든 쌍)
n_comp = 6
alpha_bonf = 0.05 / n_comp
print(f"\n--- Bonferroni ---")
print(f"단일 비교 α: {alpha_bonf:.4f}")

# 5. Dunnett (대조군 'A' vs 처치군)
print(f"\n--- Dunnett (자체 구현) ---")
control = df[df['group']=='A']['value']
for tx in ['B', 'C', 'D']:
    treatment = df[df['group']==tx]['value']
    diff = treatment.mean() - control.mean()
    se = np.sqrt(ms_w * (1/n_per + 1/n_per))
    t_stat = diff / se
    print(f"  A vs {tx}: t = {t_stat:.3f}, diff = {diff:.3f}")

이 코드가 5 가지 절차 비교. 각각의 결과 일관 또는 차이 확인.

13 절차 선택의 비즈니스 가이드

A/B 테스트 시나리오?

1 metric, 2 variants
   → 단순 t 검정 (보정 X)

1 metric, 3+ variants (multi-arm)
   대조군 명확? Yes → Dunnett
                 No → Tukey HSD

2+ metrics, 2 variants
   Primary 우선? Yes → Primary 보정 X, Secondary FDR
                  No → Bonferroni 또는 Holm

Many segments + many metrics
   → FDR 또는 hierarchical

이 가이드가 비즈니스 결정 도구.

14 후속 — FDR

다음 글 A-MAX5-4 는 FDR (False Discovery Rate) 를 다룬다. FDR 은 \(\alpha_{EW}\) 와 다른 통제 대상이며, 많은 가설 에서 효율적이다.

15 관련 주제

선행 지식

후속 주제 (Phase A)

  • A-MAX5-4 FDR + 실무 조정

다른 카테고리 연결

Subscribe

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