Summary
- 3개 이상의 집단(표본)이 동일한 모집단에서 샘플링된 것인지 확인할 수 있는 확률적 가이드라인을 잡아주는 기법
- t-test는 2개의 집단에서만 본 것과 차별점.
- F-stat을 결과값으로 하고 해석은 ‘적어도 한 집단은 모집단에서 추출되었을 확률이 낮다.‘로 할 수 있음.
- 그렇다면 모집단에서 나오지 않은 것으로 추정되는 표본을 찾을 수 있냐? → Post-hoc(사후 검정)
용어 설명
- 더미변수 (Dummy variable): 범주형 변수를 0/1로 코딩한 것. 예: 집단 B = 1, 나머지 = 0. ANOVA 내부에서 회귀처럼 작동할 때 사용
- 주효과 (Main effect): 각 독립변수가 종속변수에 미치는 독립적인 효과. Two-way ANOVA에서 요인 A의 효과, 요인 B의 효과 각각
- 교호작용 (Interaction effect): 두 독립변수의 효과가 서로 영향을 미치는 경우. “교수법 효과가 성별에 따라 다르다” 같은 상황
- 구형성 (Sphericity): 반복측정 ANOVA의 추가 가정. 모든 조건 쌍 간 차이의 분산이 동일해야 함. Mauchly’s test로 검정
- F 통계량 (F-statistic): 집단 간 분산 / 집단 내 분산. 값이 클수록 집단 간 차이가 오차에 비해 큰 것
- Cohen’s f: ANOVA용 효과 크기. η²에서 변환: . 0.10(small), 0.25(medium), 0.40(large)
Implementation
import statsmodels.api as sm from statsmodels.formula.api import ols from statsmodels.stats.anova import anova_lm import pandas as pd df = pd.DataFrame({ # Data sample 'score': [10, 12, 13, 15, 20, 21, 19, 25, 28], 'group': ['A','A','A','B','B','B','C','C','C'] }) # OLS(Ordinary Least Square) model fit. # C means categorical value # score: dependent var # group: independent var model = ols('score ~ C(group)', data=df).fit() # generate ANOVA table anova_table = sm.stats.anova_lm(model, typ=2) print(anova_table)
Relationship between ANOVA and OLS
NOTE
ANOVA는 OLS 의 일종. 아래와 같이 수식적으로 표현 가능.
- : 전체 평균
- : 그룹 i의 효과
- : 오차항
조금 더 자세히 알아보자.
Example
아래와 같은 데이터 셋이 있다 가정하자.
idx feature1 y 1 A 5 2 A 7 3 B 9 4 B 11 5 C 13 6 C 15 Recap: ANOVA는 기본적으로 categorical independent var를 위한 regression!
ANOVA는 matrix form으로 다음과 같이 써질 수 있는데,
관례 상 회귀 시 한 group을 baseline으로 잡고, 나머지 그룹 간 차를 변수로 두는 경우가 많은데 여기선 A를 baseline으로 set.그렇다면, Dummy는 이렇게 잡을 수 있음.
그렇다면, 이제 데이터와 기울기는
물론 위의 는 baseline 대비 임.
model이 fitting하는 건, 위 식을 통해 예측한 각 y 값과 ground_truth 간 RSS 혹은 LS를 minimizing 함.
ANOVA의 유형
One-way ANOVA
- 독립변수(요인) 1개, 수준(집단) 3개 이상
- 예: 3가지 교수법 → 시험 점수 비교
Two-way ANOVA (Factorial ANOVA)
- 독립변수 2개, 주효과(main effect) + 교호작용(interaction) 검정
- 예: 교수법(3) × 성별(2) → 시험 점수
수식 변수 풀이
- : 요인 A의 수준 i, 요인 B의 수준 j, 관측 k의 종속변수 값
- : 전체 평균
- : 요인 A(예: 교수법)의 수준 i의 주효과
- : 요인 B(예: 성별)의 수준 j의 주효과
- : A와 B의 교호작용 효과 — 두 요인의 조합에 따른 추가 효과
- : 오차항 — 모형으로 설명되지 않는 개인 차이
| Source | df |
|---|---|
| Factor A | a - 1 |
| Factor B | b - 1 |
| A × B | (a-1)(b-1) |
| Error | N - ab |
Repeated-Measures ANOVA (RM-ANOVA)
- 같은 피험자가 모든 조건에 참여 (within-subject design)
- 개인 간 변동을 분리하여 오차 감소 → 검정력 향상
- 추가 가정: 구형성(sphericity) — Mauchly’s test로 검정
수식 변수 풀이
- : 조건 i의 효과 (관심 대상)
- : 피험자 j의 개인 효과 — 각 피험자의 전반적 수준 차이를 분리하여 오차 감소
- 직관: 피험자 효과를 분리하면 이 줄어들어 → F값 증가 → 검정력 향상
- : 피험자 j의 효과 (subject effect)
구형성 위반 시
- Greenhouse-Geisser 보정 (ε < 0.75일 때)
- Huynh-Feldt 보정 (ε ≥ 0.75일 때)
- 또는 LMM 사용 (구형성 가정 불필요)
Mixed ANOVA
- Between-subject factor + Within-subject factor 동시 포함
- 예: 집단(실험/통제) × 시점(사전/사후/추후)
가정 (Assumptions)
| 가정 | 검정 방법 | 위반 시 대안 |
|---|---|---|
| 정규성 | Shapiro-Wilk, Q-Q plot | Kruskal-Wallis test |
| 등분산성 | Levene’s test | Welch’s ANOVA, Games-Howell post-hoc |
| 독립성 | 연구 설계 | LMM |
| 구형성 (RM만) | Mauchly’s test | G-G / H-F 보정, LMM |
Effect Size
→ Eta-squared 참조
| 지표 | 수식 | 해석 (S/M/L) |
|---|---|---|
| η² | .01 / .06 / .14 | |
| partial η² | .01 / .06 / .14 | |
| ω² | 편향 보정 | |
| Cohen’s f | .10 / .25 / .40 |
사후 검정 (Post-hoc)
ANOVA가 유의하면 → “어떤 집단 쌍이 다른가?” → Post-hoc(사후 검정)
| 방법 | 등분산 가정 | 보수성 | 권장 상황 |
|---|---|---|---|
| Tukey HSD | Yes | 중간 | 모든 쌍 비교 (가장 일반적) |
| Bonferroni | Yes | 높음 | 특정 소수 쌍만 비교 |
| Scheffe | Yes | 매우 높음 | 복잡한 대비(contrast) |
| Games-Howell | No | 중간 | 등분산 위반 시 |
| Dunnett | Yes | 중간 | 통제 집단 vs 나머지 |
확장 구현
Implementation — Two-way & RM-ANOVA
import pingouin as pg import statsmodels.api as sm from statsmodels.formula.api import ols # === Two-way ANOVA === model = ols('score ~ C(method) * C(gender)', data=df).fit() anova_table = sm.stats.anova_lm(model, typ=2) print(anova_table) # === RM-ANOVA (pingouin) === rm = pg.rm_anova(data=df, dv='score', within='condition', subject='subject', correction=True) print(rm[['Source', 'F', 'p-unc', 'p-GG-corr', 'np2', 'eps']]) # p-GG-corr = Greenhouse-Geisser 보정 p-value # eps = sphericity epsilon # === Mixed ANOVA === mixed = pg.mixed_anova(data=df, dv='score', within='time', between='group', subject='subject') print(mixed) # === Post-hoc (Tukey) === posthoc = pg.pairwise_tukey(data=df, dv='score', between='method') print(posthoc[['A', 'B', 'diff', 'p-tukey', 'hedges']])
관련 문서
- 통계 검정법 개요 — 검정법 선택 플로우차트
- t-test — ANOVA의 2집단 특수 사례 ()
- ANCOVA — 공변량 통제 + ANOVA
- Linear Mixed Effects Model — ANOVA의 확장 (random effects)
- Kruskal-Wallis test — 비모수 대안
- Eta-squared — ANOVA effect size
- Sample Size Determination — ANOVA 표본 크기 (Cohen’s f)