분산 분석(ANOVA, analysis of variance)

분산 분석이 뭐지?

분산 분석(分散分析, analysis of variance, ANOVA, 또는 변량 분석)은 통계학에서 두 개 이상 다수의 집단을 서로 비교하고자 할 때 집단 내의 분산, 총평균 그리고 각 집단의 평균의 차이에 의해 생긴 집단 간 분산의 비교를 통해 만들어진 F분포를 이용하여 가설검정을 하는 방법이다.
- 위키백과

보통 세 개 이상의 집단 간 평균이 유의미한 차이가 있는지 알아보기 위한 방법이다.

❓ 이름은 분산 분석인데 평균을 비교하네? 뭐지?
'집단 간 분산'과 '집단 내 분산'을 이용하여 분석하기 때문에 '분산 분석'이라고 함.
∵ 평균값이 같아도 분산에 따라 데이터의 모양이 완전히 달라질 수 있다
$\rightarrow$ 분산이 클수록 집단 간 평균값의 차이가 무의미해짐

  • 여러 집단 간의 평균이 비슷하다 = 여러 집단 간의 분산이 작다
  • 여러 집단 간의 평균이 다르다 = 여러 집단 간의 분산이 크다

∴ '분산'이라는 단어 안에 '평균'의 의미가 내포되어 있다
∴ '분산 분석 = 평균 간 차이 분석' 이라고 할 수 있다

<예시>

import numpy as np
import scipy.stats as stats
import matplotlib.pyplot as plt

mean = [4.8, 5.2, 5]
std = 0.1 # 표준편차(-> 분산)
color = 'rgb'

data = []
for i in  range(len(mean)):
    data.append(stats.norm(mean[i], std).rvs(100))
    plt.plot(np.arange(len(data[i]))+i*len(data[0]), data[i], '.', color=color[i])

std2 = 1 # 표준편차(분산)를 기존 0.1에서 1로 변경

data2 = []
for i in  range(len(mean)):
    data2.append(stats.norm(mean[i], std2).rvs(100))
    plt.plot(np.arange(len(data2[i]))+i*len(data2[0]), data2[i], '.', color=color[i])
# 각 데이터별 평균값은 이전과 동일하나, 분산에 따라서 전체적인 분포 모양의 차이가 있음

정리해보면
$$집단\ 간\ 평균\ 차이 = \frac{집단\ 간\ 분산}{집단\ 내\ 분산}$$
$$= {집단\ 간\ 평균\ 차이가\ 큰가?\over애초에\ 집단이라고\ 할\ 수\ 있나?}$$
$$= F\ 값(F-statistic)$$
이라고 할 수 있다.
- 집단 간 분산 : 커야 함 (집단 간의 평균값 차이가 뚜렷하다는 것)
- 집단 내 분산 : 작아야 함 (집단 내 분산이 크면(=집단 내 데이터 간의 차이가 크면) 이 안에 속한 것들이 진짜 한 집단이라고 하기 애매함)

완전한 분산 분석은 세 단계로 이루어진다.

  1. 가정 검정(등분산성, 정규성, 독립성) (여기서는 '등분산성'만 언급)
    1) 등분산성 검정 : 집단 간 비교가 가능한가?
    • 집단 내 분산이 서로 다르다 $\rightarrow$ 집단들을 동등하게 비교하기 어려움
    • $H_0$ : 모든 집단의 '집단 내 분산'이 같다
    • $H_a$ : 모든 집단의 '집단 내 분산'이 같지 않다
  2. 분산 분석의 가설 검정 (Omnibus test) : 집단 간 평균이 다른가?
    • $H_0$ : 모든 집단의 평균이 같다
    • $H_a$ : 모든 집단의 평균이 같지 않다
    • 한계점 : 구체적으로 어떻게 같지 않은 것인지, 어떤 집단의 평균이 다른 것인지 알 수 없음
  3. 사후분석 (post-hoc test) : 어느 집단의 평균이 다른가?
    • 분산 분석에서 F값이 충분히 큰 경우(평균이 같지 않은 경우) 사후분석 시행
    • 어떻게? 집단 2개씩 묶어서 T-test? 아니다
    • ∵ 1종 오류의 증가alpha=0.05로 설정, 3번 시행하면 0.95 * 0.95 * 0.95 = 0.86으로 1종 오류를 저지르지 않을 확률이 낮아짐
    • 이를 방지하기 위해 Bonferroni Correction 등을 사용함

분산 분석에는 일원 분산 분석(One-way ANOVA)과 이원 분산 분석(Two-way ANOVA)이 있다.


분산 분석은 어떻게 하는거지?

일원 분산 분석(One-way ANOVA)

  • 독립 변수와 종속 변수 모두 1개인 경우
  • 한 변수의 변화가 결과에 미치는 영향을 알아보기 위해 사용

<예시 - scipy 이용>

import numpy as np
from scipy.stats import f_oneway

g1 = np.array([0, 31, 6, 26, 40])
g2 = np.array([24, 15, 12, 22, 5])
g3 = np.array([32, 52, 30, 18, 36])

f_oneway(g1, g2, g3)

F_onewayResult(statistic=2.6009238802972483, pvalue=0.11524892355706169)


이원 분산 분석(Two-way ANOVA)

  • 독립 변수가 2개 이상인 경우
  • 두 요인이 서로 영향을 미치는지의 여부를 알아보기 위해 사용

<예시 - statsmodel 이용>

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

df = pd.DataFrame({'water': np.repeat(['daily', 'weekly'], 15),
                   'sun': np.tile(np.repeat(['low', 'med', 'high'], 5), 2),
                   'height': [6, 6, 6, 5, 6, 5, 5, 6, 4, 5,
                              6, 6, 7, 8, 7, 3, 4, 4, 4, 5,
                              4, 4, 4, 4, 4, 5, 6, 6, 7, 8]})  

#perform two-way ANOVA
model = ols('height ~ C(water) + C(sun) + C(water):C(sun)', data=df).fit()
sm.stats.anova_lm(model, typ=2)
  sum_sq df F PR(>F)
C(water) 8.533333 1.0 16.0000 0.000527
C(sun) 24.866667 2.0 23.3125 0.000002
C(water):C(sun) 2.466667 2.0 2.3125 0.120667
Residua 12.800000 24.0 NaN NaN

 

<참고 자료>
분산 분석 - 위키백과
분산 분석 - 나무위키
파이썬으로 분산분석(ANOVA)
분산 분석(ANOVA)이란 무엇인가요?
ANOVA using Python (with examples)
수식없는 분산분석 1 - ASDF 오터의 통계
수식없는 분산분석 1 - ASDF 오터의 통계
F값 (통계) - 위키백과
F-value의 의미와 분산분석 - 공돌이의 수학정리노트
통계 F 값 (F-ratio) 을 가장 쉽게 설명해 보자 - 엘트리고의 농업저널
scipy.stats.f_oneway - One-way ANOVA
statsmodels.stats.anova.anova_lm - Two-way ANOVA
How to Perform a Two-Way ANOVA in Python

+ Recent posts