1 도입 — 가정이 깨졌을 때
A-MAX3-4 에서 ANOVA F 검정이 가정에 의존함을 봤다. 그러나 실제 자료는 가정을 완벽하게 만족하지 않는다. 강건 (robust) 대안은 가정 위반 시에도 정확한 (또는 보수적) 검정을 보장한다.
이 글의 4 가지 대안:
- Welch’s F — 등분산 위반에 강건
- Brown-Forsythe F — 정규성 + 등분산 모두 약화
- Kruskal-Wallis — 비모수 (분포 가정 X)
- Permutation / Bootstrap — 모든 가정 약화
2 Welch’s F — 등분산 가정 완화
2.1 표준 F 의 한계
표준 F 통계량은 풀링된 분산 \(s_p^2 = \text{MS}_W\) 를 사용한다.
\[ F = \frac{\text{MS}_B}{\text{MS}_W} = \frac{\text{SS}_B / (J-1)}{\text{SS}_W / (n-J)} \]
이 식은 모든 그룹이 같은 분산 이라는 가정에 의존한다. 위반 시 검정 분포가 정확한 \(F_{J-1, n-J}\) 가 아니다.
2.2 Welch’s F
그룹별로 다른 분산을 허용하는 ANOVA 변형. 그룹 평균에 분산의 역수 로 가중치를 주어 검정 통계량을 구성한다.
\[ F^* = \frac{\sum_{j=1}^{J} w_j (\bar{Y}_j - \bar{Y}^*)^2 / (J - 1)}{1 + \frac{2(J - 2)}{J^2 - 1} \sum_j \frac{(1 - w_j / w)^2}{n_j - 1}} \]
여기서 \(w_j = n_j / s_j^2\), \(w = \sum w_j\), \(\bar{Y}^* = \sum w_j \bar{Y}_j / w\).
자유도: \(\text{df}_1 = J - 1\) (분자), \(\text{df}_2\) 는 Welch-Satterthwaite 근사로 계산.
2.3 직관
가중치 \(w_j = n_j / s_j^2\) 는 분산이 작은 그룹 에 더 큰 영향을 준다. 이는 분산이 큰 그룹의 부정확한 평균이 검정에 과한 영향을 주지 않도록 막는 보정이다.
자유도도 그룹별 분산에 따라 조정된다. 분산이 매우 다르면 분모 자유도가 줄어들어 임계값이 커지고 검정이 보수적 이 된다.
2.4 사용 권장
R 의 oneway.test() 와 Python 의 scipy.stats.alexandergovern 또는 pingouin.welch_anova() 가 Welch’s F 를 제공한다.
Ruxton (2006) 은 항상 Welch 를 쓰라 고 권장한다. 이유:
- 등분산 충족 시 Welch ≈ 표준 F (검정력 거의 동일)
- 등분산 위반 시 Welch ≫ 표준 F (정확성 보장)
- “등분산 검정 후 선택” 절차는 이중 검정으로 \(\alpha\) 인플레이션
- Welch 는 지는 게임이 없다
R 의 t.test() 와 oneway.test() 가 기본값으로 Welch 를 사용하는 것은 이 권고의 반영이다. Python 의 scipy.stats.ttest_ind() 도 equal_var=False 가 권장이다.
3 Brown-Forsythe F — 정규성 약화
3.1 원리
Brown-Forsythe (1974) 는 그룹 평균 대신 그룹 중앙값 을 사용한다. 이는 비대칭 자료와 이상치에 강건하다.
\[ \text{BF} = \frac{\sum n_j (\bar{Y}_j - \bar{Y})^2 / (J - 1)}{\sum_j (1 - n_j / n) s_j^2} \]
분모가 표준 F 와 다르다. 분산을 풀링하지 않고 각 그룹의 가중치 평균 으로 계산한다.
3.2 자유도
분모 자유도는 Welch-Satterthwaite 와 유사한 근사로 계산된다.
3.3 사용 시점
- 자료가 강하게 비대칭
- 이상치가 다수 존재
- 표본 크기가 작음 (CLT 가 약함)
4 Kruskal-Wallis — 비모수 ANOVA
4.1 원리
자료의 순위 (rank) 를 사용해 그룹 차이를 검정하는 비모수 절차.
- 모든 자료를 합쳐 순위를 매긴다 (\(1, 2, \ldots, n\)).
- 각 그룹의 순위 합 \(R_j\) 를 계산한다.
- 통계량:
\[ H = \frac{12}{n(n+1)} \sum_{j=1}^{J} \frac{R_j^2}{n_j} - 3(n+1) \]
\(H\) 는 큰 \(n\) 에서 \(\chi^2_{J-1}\) 분포에 근사한다.
4.2 가설
\[ H_0: \text{모든 그룹이 같은 분포에서 추출됨} \]
이 가설은 평균 차이가 아니라 분포 동일성 에 대한 것이다. 그러나 그룹 간 분포가 같은 형태이고 위치만 다른 경우, Kruskal-Wallis 는 위치 (중앙값) 차이의 검정으로 해석된다.
4.3 t 검정 (Mann-Whitney U) 과의 관계
\(J = 2\) 일 때 Kruskal-Wallis 는 Mann-Whitney U 검정 과 동등하다. 즉 Kruskal-Wallis 는 Mann-Whitney 의 J 그룹 일반화 이다.
4.4 검정력
| 자료 분포 | Kruskal-Wallis 검정력 (vs F) |
|---|---|
| 정규 | 약 95.5 % (F 가 강함) |
| 비대칭 (지수, log-normal) | 종종 더 높음 (KW 가 강함) |
| 두꺼운 꼬리 (t 분포 자유도 작음) | KW 가 강함 |
따라서 자료가 정규에서 멀어질수록 Kruskal-Wallis 의 상대적 우위가 커진다.
Kruskal-Wallis 가 왜 이상치에 강건한가?
원자료에서 한 점이 1000 처럼 매우 크면, 표본 평균과 분산이 그 한 점에 지배 된다. 그러나 순위 변환에서는 그 점이 가장 큰 순위 1 개를 받을 뿐이다. 다음 큰 점이 999 이든 100 이든, 둘 다 동일한 순위 차이 1 만 가진다.
이 압축 이 이상치 영향을 제한한다. 동시에 분포 형태에 무관한 검정이 가능하다.
대가는 세부 정보의 손실 이다. 두 점이 1000 과 999 차이라도 1 과 2 차이로 변환되면, 자료의 척도 정보가 사라진다. 따라서 자료가 정규에 가까우면 정규 이론 검정이 더 효율적이다.
5 Permutation / Bootstrap — 모든 가정 약화
5.1 Permutation 검정 (J 그룹)
A-MAX2-1 에서 두 그룹 사례를 다뤘다. J 그룹 일반화는 다음과 같다.
- 자료의 그룹 라벨 을 무작위로 재배치한다.
- 재배치된 자료에서 검정 통계량 (예: F, MS_B) 을 계산한다.
- 이를 \(B\) 회 반복한다.
- 관측 통계량보다 극단적인 비율이 p 값.
이 절차는 어떤 통계량에도 적용 가능 하며 분포 가정이 없다.
5.2 Bootstrap
부트스트랩은 검정보다 추정 에 가까운 도구다. 각 그룹 평균과 차이의 신뢰 구간 을 비모수적으로 구성한다. 자세한 절차는 후속 글 A-BUI7-* 에서 다룬다.
6 절차 비교 표
| 절차 | 등분산 | 정규성 | 독립성 | 자료 척도 |
|---|---|---|---|---|
| 표준 F | 가정 | 가정 | 가정 | 양적 |
| Welch’s F | 약화 | 가정 | 가정 | 양적 |
| Brown-Forsythe F | 약화 | 약화 | 가정 | 양적 |
| Kruskal-Wallis | 약함 | 불필요 | 가정 | 순위 가능 |
| Permutation | 약함 | 불필요 | 약화 | 자유 |
| Bootstrap | 약함 | 불필요 | 가정 | 자유 |
이 표가 어떤 대안을 언제 쓰는가 의 가이드이다.
7 검정력 비교
가정이 충족된 정규 자료에서:
| 절차 | 상대 검정력 (F = 100 %) |
|---|---|
| 표준 F | 100 % |
| Welch’s F | ≈ 100 % |
| Brown-Forsythe | 약 95 % |
| Kruskal-Wallis | 약 95.5 % |
| Permutation | ≈ 100 % |
가정이 충족되면 표준 F 가 가장 강력하지만, robust 대안의 손실이 크지 않다 (대부분 5 % 이내).
가정이 위반된 비정규 자료에서:
| 절차 | 위반 유형 | 상대 검정력 |
|---|---|---|
| 표준 F | 등분산 위반 | \(\alpha\) 부정확 |
| Welch’s F | 등분산 위반 | 안정 |
| Brown-Forsythe | 강한 비대칭 | 안정 |
| Kruskal-Wallis | 비정규 | 종종 더 높음 |
8 결정 트리 — 어떤 절차를 선택할까
자료 진단
↓
독립성 위반? Yes → 혼합 모형, GEE
↓ No
표본 크기 충분 (n_j > 30)?
Yes → CLT 작동
등분산? Yes → 표준 F 또는 Welch (둘 다 OK)
No → Welch's F
No → 표본 작음
정규성 OK?
Yes → 등분산 OK? Yes → 표준 F
No → Welch
No → 비대칭 약함 → Brown-Forsythe
강한 비대칭 → Kruskal-Wallis
일반 → Permutation
9 신뢰 구간 — Robust 대안과의 호환
각 절차에서 효과 크기의 신뢰 구간:
| 절차 | CI 구성 |
|---|---|
| 표준 F | t 분포 기반 닫힌 형태 |
| Welch’s F | Welch-Satterthwaite 자유도 사용 |
| Brown-Forsythe | 근사 t |
| Kruskal-Wallis | Hodges-Lehmann 추정량 |
| Permutation | 부트스트랩 또는 직접 |
이 절차들 모두 효과 크기 + CI 보고 를 지원한다.
10 자료 변환과의 비교
A-MAX3-4 에서 자료 변환 (log, sqrt 등) 도 가정 위반의 한 해법이라 했다. Robust 절차와 변환의 비교:
| 측면 | 자료 변환 | Robust 절차 |
|---|---|---|
| 추론 정확도 | 변환된 척도에서만 정확 | 원 척도에서 정확 |
| 해석 | 변환된 단위로 모호 | 원 단위 유지 |
| 적용 범위 | 분포 형태에 의존 | 일반적 |
| 검정력 | 변환이 잘 맞으면 강함 | 안정적 |
권장: 간단한 변환 (log) 으로 가정 위반이 해결되면 변환을 우선 시도. 변환이 어렵거나 해석을 해치면 robust 절차 사용.
11 코드 예시 — 4 가지 절차 비교
import numpy as np
import pandas as pd
from scipy.stats import f_oneway, kruskal, levene
from statsmodels.stats.weightstats import ttest_ind
import scipy.stats as stats
np.random.seed(42)
n_each = 30
# 시뮬레이션 1: 등분산 + 정규
data_normal = {
'A': np.random.normal(5.0, 1.0, n_each),
'B': np.random.normal(5.5, 1.0, n_each),
'C': np.random.normal(6.0, 1.0, n_each)
}
# 시뮬레이션 2: 등분산 위반
data_uneq = {
'A': np.random.normal(5.0, 0.5, n_each),
'B': np.random.normal(5.5, 1.0, n_each),
'C': np.random.normal(6.0, 2.0, n_each)
}
# 시뮬레이션 3: 강한 비대칭
data_skew = {
'A': np.random.exponential(1.0, n_each),
'B': np.random.exponential(1.5, n_each),
'C': np.random.exponential(2.0, n_each)
}
def compare_methods(data, label):
print(f"\n=== {label} ===")
groups = list(data.values())
F, p_F = f_oneway(*groups)
print(f"표준 F: F = {F:.3f}, p = {p_F:.4f}")
# Welch — pingouin 또는 수동 (statsmodels 에 직접 없음)
# 여기서는 간이 구현
n_j = np.array([len(g) for g in groups])
means = np.array([g.mean() for g in groups])
vars_ = np.array([g.var(ddof=1) for g in groups])
w = n_j / vars_
w_total = w.sum()
weighted_mean = (w * means).sum() / w_total
J = len(groups)
F_welch_num = (w * (means - weighted_mean)**2).sum() / (J - 1)
correction = 1 + 2*(J-2)/(J**2-1) * sum((1 - w/w_total)**2 / (n_j-1))
F_welch = F_welch_num / correction
df2_welch = (J**2 - 1) / (3 * sum((1 - w/w_total)**2 / (n_j-1)))
p_welch = 1 - stats.f.cdf(F_welch, J-1, df2_welch)
print(f"Welch's F: F = {F_welch:.3f}, df2 = {df2_welch:.1f}, p = {p_welch:.4f}")
# Kruskal-Wallis
H, p_kw = kruskal(*groups)
print(f"Kruskal-Wallis: H = {H:.3f}, p = {p_kw:.4f}")
# Levene 진단
stat_lev, p_lev = levene(*groups, center='median')
print(f"Brown-Forsythe (등분산 진단): stat = {stat_lev:.3f}, p = {p_lev:.4f}")
# Permutation 검정 (간이)
obs_F = F
pooled = np.concatenate(groups)
extreme = 0
n_perm = 5000
for _ in range(n_perm):
np.random.shuffle(pooled)
perm_groups = [pooled[i*n_each:(i+1)*n_each] for i in range(J)]
F_perm, _ = f_oneway(*perm_groups)
if F_perm >= obs_F:
extreme += 1
print(f"Permutation: p = {extreme/n_perm:.4f}")
compare_methods(data_normal, "등분산 + 정규")
compare_methods(data_uneq, "등분산 위반")
compare_methods(data_skew, "강한 비대칭")세 시나리오에서 절차의 상대적 신뢰성 을 비교할 수 있다. 일반적으로:
- 가정 충족 시: 모든 절차의 결론 일치
- 가정 위반 시: 표준 F 와 robust 대안이 다른 결론 → robust 신뢰
12 Robust 절차의 한계
각 절차에도 한계가 있다.
| 절차 | 한계 |
|---|---|
| Welch’s F | 정규성은 여전히 가정 |
| Brown-Forsythe | 검정력이 표준 F 보다 낮음 |
| Kruskal-Wallis | 척도 정보 손실 |
| Permutation | 계산 비용 |
따라서 robust 절차는 대체 가 아니라 robustness check 로 사용하는 것이 권장된다. 표준 F 와 robust 대안을 모두 보고하여 결과의 강건성 을 보여주는 것이 좋다.
13 결과 보고 — 모범 형식
Mood induction 의 효과를 검정했다 (n = 30, 그룹당 10 명).
표준 ANOVA: F(2, 27) = 22.5, p < 0.001, η² = 0.625.
Welch's F: F(2, 18.0) = 22.5, p < 0.001 (등분산 가정 약화).
Brown-Forsythe: 자료가 강한 비대칭이 아니므로 미수행.
Kruskal-Wallis (robustness check): H(2) = 23.0, p < 0.001.
결론: 모든 절차가 일관된 결론. 그룹 간 차이가 강하다.
사후 비교 (Tukey HSD): Pleasant > Neutral > Unpleasant (모두 p < 0.001).
이런 다중 절차 결과 보고 가 결과의 robustness 를 시각적으로 보여 준다.
14 Robust Methods 의 추가 변형
14.1 Trimmed Means
극단값 (양 극단 일정 비율) 제외 후 평균.
import numpy as np
from scipy.stats import trim_mean
data = [1, 2, 3, 4, 5, 6, 100] # 이상치 100
mean = np.mean(data) # 17.3
trim_5 = trim_mean(data, 0.10) # 10 % trimming
trim_20 = trim_mean(data, 0.20)
print(f"평균: {mean:.2f}")
print(f"10 % trimmed: {trim_5:.2f}")
print(f"20 % trimmed: {trim_20:.2f}")이상치에 robust. 그러나 검정력 약간 손실.
14.2 Yuen’s t-test
Trimmed means 의 t-test 변형. 이분산 + 이상치 모두 robust.
14.3 M-estimators
Maximum likelihood 의 robust 변형. Huber’s M-estimator 가 표준.
15 Robust ANOVA 의 시뮬레이션 비교
import numpy as np
from scipy.stats import f_oneway, kruskal, levene
np.random.seed(42)
n_sim = 1000
n_per = 30
J = 3
# 시나리오 1 - 이상 (정규 + 등분산)
type_I_normal = {'F': 0, 'KW': 0}
for _ in range(n_sim):
groups = [np.random.normal(0, 1, n_per) for _ in range(J)]
if f_oneway(*groups)[1] < 0.05:
type_I_normal['F'] += 1
if kruskal(*groups)[1] < 0.05:
type_I_normal['KW'] += 1
# 시나리오 2 - 등분산 위반
type_I_uneq = {'F': 0, 'Welch': 0}
for _ in range(n_sim):
groups = [np.random.normal(0, sigma, n_per) for sigma in [1, 2, 3]]
if f_oneway(*groups)[1] < 0.05:
type_I_uneq['F'] += 1
# Welch (간이)
n = sum(len(g) for g in groups)
ws = [len(g)/g.var(ddof=1) for g in groups]
# ...
print("이상 시나리오 (Type I):")
print(f" F: {type_I_normal['F']/n_sim:.3f}, KW: {type_I_normal['KW']/n_sim:.3f}")
print("등분산 위반:")
print(f" F: {type_I_uneq['F']/n_sim:.3f}")16 A/B 테스트의 Robust 분석 모범
import numpy as np
from scipy.stats import ttest_ind, mannwhitneyu, levene
# 가상 매출 자료 (우편향)
np.random.seed(42)
control = np.random.lognormal(4, 1.0, 1000)
treatment = np.random.lognormal(4.05, 1.0, 1000)
# 1. Welch t (이분산 robust)
t_stat, p_t = ttest_ind(treatment, control, equal_var=False)
print(f"Welch t: t = {t_stat:.3f}, p = {p_t:.4f}")
# 2. Mann-Whitney (분포 robust)
u_stat, p_u = mannwhitneyu(treatment, control, alternative='two-sided')
print(f"Mann-Whitney U: U = {u_stat:.0f}, p = {p_u:.4f}")
# 3. 등분산 검정
stat, p_lev = levene(treatment, control, center='median')
print(f"Brown-Forsythe: stat = {stat:.3f}, p = {p_lev:.4f}")
# 4. Permutation
B = 5000
obs_diff = treatment.mean() - control.mean()
combined = np.concatenate([treatment, control])
perm_diffs = []
for _ in range(B):
np.random.shuffle(combined)
perm_diffs.append(combined[:1000].mean() - combined[1000:].mean())
p_perm = np.mean(np.abs(perm_diffs) >= np.abs(obs_diff))
print(f"Permutation: p = {p_perm:.4f}")
# 결과 일관 → robust
print("\n결과 일관성:")
print(f" Welch p: {p_t:.4f}")
print(f" Mann-Whitney p: {p_u:.4f}")
print(f" Permutation p: {p_perm:.4f}")3 가지 robust 검정의 결과 일관 이 robustness 의 증거.
17 Ch.3 마무리
Maxwell Ch.3 의 6 단계 흐름이 끝난다.
- GLM 도입 (A-MAX3-1)
- One/Two-Group (A-MAX3-1)
- General Case (A-MAX3-2)
- F 검정 + 효과 크기 (A-MAX3-3)
- 가정 진단 (A-MAX3-4)
- Robust 대안 (이 글)
Ch.3 가 일원 ANOVA의 완전한 토대 를 제공했다. 이제 Ch.4 는 어느 그룹 사이 차이가 있는지를 묻는 대비 (contrast) 분석으로 확장한다. 이는 후속 시리즈 A-MAX4-* 에서 다룬다.
18 관련 주제
선행 지식
후속 주제 (Phase A)
- A-MAX4-* (Individual Comparisons / Contrasts)
- A-MAX5-* (Multiple Comparisons)
- A-BUI7-* (Bootstrap)
- A-WOO14-* (Permutation 일반)
다른 카테고리 연결
- 순열 p 값
- 부트스트랩 표준 오차
- Robust regression — 회귀에서의 robust