본문 바로가기
Data Analysis/Python

[Python] 일원배치분산분석 (1-Way ANOVA)

by 불탄오징어 2020. 10. 13.
반응형

 

 

 

 

 

ANOVA 하면 학부 시절 실험계획법 시간 때 집중적으로 들었던 기억이 있습니다. 물론 수리통계학 시간이나 기초 통계학 시간 때도 훝고 지나갔던 기억이 있지만 실상 정확하게 용도나 활용에 대해 사용해본 것은 한참 뒤였네요. 그 쯤에서야 정확하게 이해를 했던 것 같습니다. 분산분석은 말 그대로 분산/변동을 분석합니다. 간단하게 집단간 변동(분산)과 집단내 변동(분산)의 비는 F분포를 따르기 때문에 이를 이용하여 가설 검정을 합니다. 이때 독립변인, 종속변인의 수에 따라서 일원배치분산분석, 이원배치 분산분석, 다원변량분산분석 등으로 구분하여 부릅니다. 

 

 

일원배치분산분석(1-Way ANOVA)


일원배치분산분석은 종속변인이 1개, 독립변인도 하나인 경우입니다. 하나의 독립변인으로 구분되는 집단간 비교가 되므로 통상 3개이상의 집단간 차이가 있는지를 검증할 때 사용합니다. 참고로 두 집단간 비교는 t-검정을 사용합니다. 예제로 iris 데이터를 활용하여 간단하게 python으로 진행해봅니다.

 

iris.txt
0.00MB

 

필요한 패키지들을 import 합니다. 

 

import pandas as pd
from statsmodels.formula.api import ols
from statsmodels.stats.anova import anova_lm
import statsmodels.stats.multicomp as mc

df = pd.read_csv("C:/temp/iris.txt")

 

Data 핸들링을 위해선느 pandas는 필수이고 대부분의 통계모형이 들어있는 statsmodel패키지도 가져옵니다. 전체를 가져오는 것은 아니고 일부 관련 있는 패키지들을 가져옵니다. ols(), anova_lm()으로 anova 를 실행, 결과를 얻을 것이고 mulitcomp는 사후 분석을 위한 패키지입니다.

 

df.boxplot(column=['Sepal.Width'], by=['Species'])

 

간단하게 Species별로 Sepal.Width에 대해서 boxplot을 그려봅시다.

 

 

참고로 Anova 또한 몇가지 가정이 필요한데 다음과 같습니다.

  • 독립변인/독립변수의 그룹 군은 서로 독립
  • 독립변인에 대한 종속변인은 정규분포
  • 독립변인에 따른 종속변인의 분산은 등분산

각 가정에 대해서 검증을 했다고 가정하고 넘어가겠습니다. 일단 boxplot을 보니 대략 등분산인듯....
본격적으로 ANOVA를 돌려보겠습니다. ANOVA를 돌리는 명령어는 다른 방식이 하나 더 있긴한데 개인적으로는 아래와 같은 formula 식을 쓰는 것을 좋아합니다. (R과 동일)

 

df.columns = ['SepalLength','SepalWidth','PetalLength','PetalWidth','Species']
fit = ols(formula='SepalWidth ~ C(Species)', data=df).fit()
anova_lm(fit)

 

단 첫줄에 보면 df의 column들을 한번 지정해준 것이 있는데 기존의 칼럼에 "."이 들어있어서 ols()함수 사용시 에러가 납니다. 그래서 일단 .을 뺀 칼럼명으로 지정하고 수행했습니다.

 

 

결과에서 보면 Species에 따른 F 분포 값이 49.16으로 유의수준 0.000으로 나옵니다. 이는 각 집단간의 평균이 동일하다는 귀무가설을 기각하는 것으로 최소한 하나의 집단은 다르다는 결론을 낼 수 있습니다. 그러면 어떤 집단이 다른 것인지 확인이 필요한데 이 단계의 것은 사후 분석이라고 합니다. 

 

 

사후분석


앞서 말한 바와같이 분산분석 후 어떤 집단이 유의미한 차이를 가지고 있는지 확인이 필요한데 이때 사용하는 분석을 사후 분석이라고 이야기합니다. 각 집단끼리 매칭하여 유의미한 차이가 있는지를 찾아냅니다. 대표적인 사후분석은 다음과 같습니다. 

 

  • Tukey HSD
  • Fisher LSD
  • Bonferroni correction
  • Scheffe's method
  • 등등등...

 

그중에  Tukey HSD로 사후분석을 해보겠습니다.

 

comp = mc.MultiComparison(df['SepalLength'], df['Species'])
tukeyhsd = comp.tukeyhsd(alpha=0.05)
tukeyhsd.summary()

print(tukeyhsd)
fig = tukeyhsd.plot_simultaneous()

 

위의 스크립트를 실행하면 다음과 같은 결과를 얻을 수 있습니다.

 

 

각 그룹간 비교를 한 결과 virginica > versicolor > setosa 순으로 3집단 모두 통계적으로 유의미한 차이를 보입니다.

 

 

이는 마지막에 출력되는 사후분석 결과에서도 확인할 수 있습니다.

 

댓글