본문 바로가기

Data/Statistics

통계 실습 : One-way ANOVA (with 파이썬)

 

t-test에 이어서 이번 시간에는 ANOVA(분산분석)에 대해 이야기 해보려고 합니다. ANOVA는 크게 One-way ANOVA(일원배치 분산분석)과 Two-way ANOVA(이원배치 분산분석)로 분류 되는데요. 오늘은 One-way ANOVA를 먼저 설명하고 다음 시간에 Two-way ANOVA를 별도로 다루도록 하겠습니다.

 

우선 앞 부분에서는 간략하게 ANOVA에 대한 개념을 다룬 뒤에 파이썬을 통해 실습을 해보도록 하겠습니다.

 

 

ANOVA(분산분석)이란?

 

ANOVA(분산분석)은 Analysis Of Varience을 줄여서 표현한 것인데요.

 

t-test의 경우에는 두 집단의 평균 값의 차이가 통계적으로 유의한지 비교하였다면, ANOVA(분산분석)는 '세 개 이상의 집단 평균 값의 차이가 통계적으로 유의미'한지 확인하기 위한 분석 방법입니다. 그리고 집단간 분산과 집단 내 분산을 이용하여 F-값을 도출해 각 집단의 평균에 대한 통계적 유의성을 확인합니다.

One-way ANOVA(일원배치 분산분석)
- 반응값(종속변수)에 대해 하나의 범주형 변수(독립변수)의 영향을 알아보기 위해 사용되는 검증 방법
- 쇼핑몰 고객의 총 지불금액이 지불방법에 따라 차이가 있는지 통계적으로 검증하는 경우

Two-way ANOVA(이원배치 분산분석)
- 반응값(종속변수)에 대해 두 개의 범주형 변수(독립변수) A, B의 영향을 알아보기 위해 사용되는 검증 방법
- 성별과 학년에 따른 시험점수의 차이를 통계적으로 검증하는 경우

 

 

ANOVA(분산분석) 프로세스

 

ANOVA는 전제조건을 만족하고 가설검정 결과가 통계적으로 유의한 결과가 나온다면, 다음과 같이 3단계의 프로세스로 진행이 됩니다.

1. 전제조건(등분산성, 정규성, 독립성)
  - 등분산성 : 분산이 집단별로 동일하다. 

  - 정규성 : 데이터가 정규분포를 따른다
  - 독립성 : 데이터 수집이 랜덤하게 결정되고 서로 독립이다.

2. F-값(F-value) 계산 및 가설검정
  - 귀무가설 : 모든 집단의 평균이 같다.
  - 대립가설 : 모든 집단의 평균이 같지 않다. (=적어도 한 그룹의 평균은 다르다.)

3. 사후검정(Post-hoc test)
  - 분산분석의 결과 귀무가설이 기각 되어 적어도 한 집단에서 평균의 차이가 있음이 통계적으로 유의할 경우,
    어떤 집단들에 대해서 평균의 차이가 존재하는지 알아보기 위해 실시하는 분석.

 

 

Python을 통한 One-way ANOVA 실습

데이터셋 : [Kaggle] Telco Customer Churn

 

1. 데이터 불러오기

 

사용할 데이터는 캐글에서 다운로드 받을 수 있는 고객 주문정보가 들어가있는 데이터 입니다. 판다스 라이브러리를 이용해 아래 데이터를 불러와보면 고객ID, 성별, 서비스 가입 정보, 총 지불금액, 지불방법 등의 컬럼이 있는 것을 볼 수 있습니다.

 

In [1] :

import pandas as pd
import numpy as np

import warnings
warnings.filterwarnings('ignore')   # 경고 메시지를 무시하고 숨기기

data = pd.read_csv('WA_Fn-UseC_-Telco-Customer-Churn.csv')
data.shape

 

Out [1] :

(7043, 21)

 

In [2] :

data.head()

 

Out [2] :

 

2. 데이터 전처리

 

여기서 불필요한 데이터는 제외하고 분산분석에 필요한 독립변수(PaymentMethod), 종속변수(TotalCharges)만을 가지고 분산분석을 해보도록 하겠습니다.

 

In [3] :

df = data[['PaymentMethod','TotalCharges']]
df.head()

 

Out [3] :

 

데이터의 정보를 확인해보니 총 지불금액(TotalCharges) 컬럼의 데이터 타입이 object 형태입니다. 분산분석 시 종속변수가 되는 변수는 반드시 연속형 변수여야 하기 때문에 이를 float 타입으로 바꿔줄 필요가 있겠습니다.

 

In [4] :

df.info()

 

Out [5] :

 

위에서 데이터 정보를 봤을 때 결측치는 없는 것으로 보였는데 자세히 살펴보니 데이터 값 중 공백이 있는 빈값이 존재하는 걸 확인할 수 있습니다. 이를 제거하기 위해서는 우선 아래와 같이 NaN으로 대체해주도록 하겠습니다.

 

 

In [6] :

df[df['TotalCharges'] == ' ']

 

Out [6] :

 

In [7] :

df['TotalCharges'] = df['TotalCharges'].replace(" ",np.nan)

 

 

빈 공백을 NaN으로 대체해주니 다시 결측치가 확인됩니다. 

 

In [8] :

df.isnull().sum()

 

Out [8] :

 

dropna() 함수를 이용해 결측치를 제거해주고 다시 확인해보니 결측치가 제거된 것을 확인할 수 있습니다.

 

In [9] :

df = df.dropna()
df.isnull().sum()

 

Out [9] :

앞서 말했던 총 지불금액(TotalCharges) 컬럼의 데이터 타입을 float 형태로 바꿔주면 분산분석을 위한 데이터 전처리 작업이 마무리 됩니다.

 

In [10] :

df['TotalCharges'] = df['TotalCharges'].astype(float)

 

 

3. 분산분석

 

일원 분산분석을 위한 라이브러리를 불러와 독립변수와 종속변수에 알맞게 코딩을 해주면 아래와 같이 일원 분산분석을 수행할 수 있습니다.

 

여기서 수행할 분산분석에 대한 귀무가설과 대립가설은 다음과 같습니다.

 

- 귀무가설 : 지불방법에 대한 집단의 평균이 같다.
- 대립가설 : 지불방법에 대한 평균이 적어도 한 그룹은 다르다.

 

In [11] :

from statsmodels.formula.api import ols
from statsmodels.stats.anova import anova_lm

 

분석 결과를 확인해보니 P-값이 0.05 이하 이므로 귀무가설을 기각할 수 있습니다. 

 

In [12] :

model = ols('TotalCharges ~ C(PaymentMethod)', df).fit()
anova_lm(model)

 

Out [12] :

 

오늘은 ANOVA의 개념과 프로세스, 그리고 Python을 활용한 간단한 One-way ANOVA 실습을 진행해봤는데요. 여기서 다루지 못한 분산분석의 전제조건(가정), 사후분석 Two-way ANOVA 실습 등은 추후 포스팅을 통해 다시 찾아오도록 하겠습니다.

 

 

작성된 내용 중 잘못된 부분이나 궁금한 사항이 있다면 언제든지 피드백 부탁 드립니다.

 

감사합니다.