본문 바로가기
데이터과학 기초/통계

파이썬으로 공분산분석(ANCOVA) 수행하기

by eigenvector 2022. 9. 24.
반응형

지난 시간까지 우리는 분산분석(ANOVA)의 기본적인 유형(One-Way ANOVA)과 응용형(Two-Way ANOVA)을 수행해 봤습니다.

 

2022.08.14 - [데이터과학 기초/통계] - 파이썬으로 분산분석(ANOVA)하기 (1) - One Way (일원 분산분석)

2022.08.25 - [데이터과학 기초/통계] - 파이썬으로 분산분석(ANOVA)하기 (2) - Two-Way (이원 분산분석)

 

포스팅 내용 중 지나가듯 언급한 내용으로 "분산분석과 나중에 배울 회귀분석은 큰 차이가 없다"라고 말한 바가 있습니다.

 

선형모형이라는 큰 틀에서 분산분석과 회귀분석은 동일한 접근법을 가지기 때문입니다.

(아직은 이해할 수 없겠지만 회귀분석의 특수한 케이스가 분산분석이라고 생각해도 됩니다)

 

오늘은 나중에 배울 회귀분석과 연결이 강화된 공분산 분석(ANCOVA)에 대해 알아보겠습니다.

 


공분산분석?

지난 시간에 우리는 예상과 다른 결괏값이 나오는 과정(=전체 분산 값)에서 특정 요인이 영향을 미치는 정도를 알기 위해 일원~이원 분산 분석을 사용한다는 사실을 배웠습니다.

 

여기서 조금 생각을 확장해 보겠습니다.

 

분산분석이란 본질적으로 전체 분산(예측이 빗나가는 정도)에서 우리가 생각한 차이(요인)가 얼마나 영향을 미치는지 "비율"을 통해 확인하는 과정입니다(예를 들어 일원 분산분석의 핵심은 집단 내 vs 집단 간임을 설명한 바 있습니다).

 

2022.08.14 - [데이터과학 기초/통계] - 파이썬으로 분산분석(ANOVA)하기 (1) - One Way (일원 분산분석)

 

공분산분석은 이 과정에서 우리가 확인하려는 요인 외 다른 부가적인 요소가 전체 분산에 미치는 요인을 줄여 비율 차이를 두드러지게 만드는 기법입니다.

 

우리는 특정 요인을 중심으로 분산에 미치는 영향을 보지만, 현실 세계는 수많은 요인이 결과에 영향을 주고 있기 때문입니다.

 

 

예를 들어 레스토랑의 수입에 "지역", "층수"가 유의미한 영향을 미칠 수 있지만 그 외로 "가격", "영업시간대", "메뉴 종류" 등 수많은 요인이 영향을 줄 수 있습니다.

 

다만, 공분산분석(ANCOVA)은 수많은 요인 중 "우리 실험에서 보려는 요인과 관련은 없지만 결괏값에 영향을 줄 수 있는 요인"을 사용합니다.

 

왜냐하면, 이원 분산분석에서 볼 수 있듯 실험에서 보려는 요인과 관계를 갖는다면 "상호작용"을 추가로 고려할 필요가 있으니까요.

 

이렇게 될 경우 우리는 ANCOVA가 아닌 또 다른 이원~삼원 분산분석을 수행하는 꼴이 됩니다.

 

2022.08.25 - [데이터과학 기초/통계] - 파이썬으로 분산분석(ANOVA)하기 (2) - Two-Way (이원 분산분석)

 

이에 따라, 공분산 분석에서는 종속변인과 관계가 깊은 연속형 변수를 투입하여 분산을 줄이려고 시도합니다.

 

잘 이해가 안 간다면 앞선 분산분석 포스팅을 주의 깊게 읽어주시면 되겠습니다.

 


패키지 설치

오랜만에 하는 포스팅이지만, 통계 분석의 기본은 항상 동일합니다.

 

통계 분석에는 데이터 분석, 시각화, 통계 역할을 하는 패키지가 필요하고 이에 따라 다음과 같이 패키지를 설치합니다.

 

설치는 pip 혹은 conda로 진행하고, 해당 과정을 잘 모른다면 과거 포스팅을 참조해 주시면 되겠습니다.

 

2022.07.31 - [데이터과학 기초/Python배우기] - conda로 손쉽게 파이썬 환경 관리하자 (Intel부터 M1까지) - 기초

 

# conda 사용할 경우
conda install -c conda-forge seaborn pandas pingouin

# pip 사용할 경우
pip install seaborn pandas pingouin

 


샘플 데이터

오늘 사용할 데이터셋은 드링크의 당도와 향에 따라 만족도를 분석한 데이터 입니다.

 

해당 데이터(실험)의 목적은 "향 or 풍미(Flavour)"에 따라 음료의 만족도(Satisfaction)가 유의미한 차이가 있을까?라는 점을 검증하는데 목적을 두고 있습니다.

 

당도(Sweet)는 향과 관계가 없지만, 만족도에 유의미한 영향을 미칠 것으로 생각되는 변수이기에 연구자는 공분산분석(ANCOVA)을 사용하기로 통계 분석 과정을 설계했습니다.

 

아래 파일을 다운로드하여 파이썬 폴더에 위치시킵니다.

 

ancova_sample.csv
0.00MB

 

주피터 노트북 환경을 로드한 이후,  Pandas를 사용하여 데이터를 로드하고 데이터 일부를 확인해서 로드가 제대로 됐는지 점검하겠습니다.

 

import pandas as pd

drink = pd.read_csv("ancova_sample.csv")
drink.head()

데이터가 문제없이 로드됐기 때문에 각 변수를 살펴보도록 하겠습니다.

 


데이터 기술분석

 

일단, 데이터의 전반적인 형태를 확인하겠습니다.

대략적으로 봤을 때, 데이터는 90개의 행(row)과 4개의 항목(column)으로 구성되어 있습니다.

 

각 요인 중 풍미(flavour)는 종류 형태(명목형)로, 당도(sweet)와 만족도(satisfaction)는 연속형 형태로 구성된 것으로 추측됩니다.

 

통계 분석 전에 각의 항목의 구체적인 통계치를 확인해 보겠습니다.

 

컬럼 중, 우리가 통계에 집어넣는 당도, 만족도 연속형 변수의 값을 descirbe()로 확인합니다.

 

drink.describe()

 

명목형(종류)의 값을 value_counts()로 확인합니다.

 

drink.Flavour.value_counts()

 

이제 전반적인 데이터의 분포를 시각화를 통해 확인해 보겠습니다.

 


데이터 시각화

가장 먼저 수행해 볼 내용은, 우리가 관심 있는 항목인 "풍미(향)"에 따른 만족도의 차이입니다.

 

풍미에 따른 만족도의 차이는 간단하게 바 차트를 이용하여 확인해 볼 수 있습니다.

 

import seaborn as sns

sns.barplot(data=drink, x ='Flavour', y='Satisfaction')

위 시각화는 "Between(그룹 간)" 차이점이 존재할 수 있다는 점을 추측하게 해 줍니다.

 

그렇다면, 이와 비교되는 Within(집단 내) 차이점에 "당도"가 미치는 영향은 어느 정도일까요?

 

풍미, 당도에 따른 만족도의 차이를 산점도로 확인해 보겠습니다.

 

import seaborn as sns

sns.scatterplot(data=drink, x ='Sweet', y='Satisfaction',hue= 'Flavour')

우리가 연구를 통해 입증하려는 "풍미(향)" 외에도, "당도"라는 요인이 만족도에 일정한 영향(양의 방향)을 줄 수도 있다는 점을 추측하게 해 줍니다.

 

그렇다면, "당도"를 고려하여 분산분석을 수행한다면 (분산 비율 차이) 더 명확한 결과가 나오지 않을까요?

 

이것이 ANCOVA 접근 방식의 중요 포인트입니다.

 

이것이 실제 통계 분석에서 어떻게 나타나는지 다음 챕터에서 확인해 보겠습니다.

 


통계 분석

오늘은 이전 시간까지 사용한 Statsmodels대신 Pingouin을 사용하여 분석을 수행해 보도록 하겠습니다.

(회귀분석과 연계해서 설명하기 보다는 ANCOVA의 수행~결과에 집중한 간략한 방식을 보여주는 것에 목표를 두겠습니다)

 

통계 검정 전에 가설 검정에 대해서는 이미 이전 분산 분석 포스팅에서 다뤘기에 깊이 다루지 않겠습니다.

 

다만, "결과 or 종속변수(여기서는 만족도)"가 "정규성"을 가지며, 우리가 새로 투입(통제)하려는 "당도"라는 요인이 우리가 보려는 요인인 "풍미"와 상관관계가 없어야 한다는 사실이 필요하다는 점은 기억할 필요가 있습니다.

 

간단하게 종속변수(만족도)의 정규성만을 검정한 결과는 다음과 같습니다.

 

import pingouin as pg

pg.normality(drink.Satisfaction)

이제, 모델을 구성하여 통계 검정을 수행해 보겠습니다.


 

정석적인 분산분석의 접근은 가장 단순한 모델(중요 변수)을 기준으로 추가 통제 변수를 넣은 모델을 비교하는 방식으로 수행한다고 말한 적이 있습니다.

 

우리는 공분산분석(ANCOVA)의 기본적인 형태를 다룰 예정이기 때문에 이 과정을 간략화하여 1) 중요 변수(Flavour)만 넣은 모델 2) 당도(Sweet)를 넣어 통제한 모델 두 모델만 구성해 보도록 하겠습니다.

 

첫 번째 모델인 중요변수만 투입(Flavour)한 모델입니다.

 

pg.anova(dv='Satisfaction', between='Flavour', data=drink, detailed=True).round(3)

두 번째 모델인, 통제 변수를 고려한 모델입니다.

 

pg.ancova(data=drink, dv='Satisfaction', covar='Sweet', between='Flavour').round(3)

주요 변수(Flavour)가 유의하다는 점은 변하지 않았지만, 이를 계산하는 과정에서 관련 통계 수치(분산, F값)이 변화된 것을 확인할 수 있습니다.

 

비교 결과는 (종속변수와 관련된) 변수를 통제함으로써, F값(통계적 유의성)에 변화가 생길 수 있음을 보여줍니다

 

이것이 조건이 맞을 경우 분산분석 대신 공분산분석을 사용하는 이유입니다. 통계치를 "더 명확하게" 보여줄 수 있기 때문입니다.


통계 보고하기

통계 분석은 3가지 부분을 넣어 구성하면 됩니다. 오늘은 분산분석과 공분산분석의 차이점을 정리하기 위한 간략한 샘플 테스트였기 때문에 해석 부분은 생략하겠습니다.

 

1. 통계방법 - 공분산분석

2. 통계수치 - 두 번째 모델(주요변수, 통제변수)의 통계 테이블 사용

3. 해석 - 시각화를 사용(or 좀 더 정확하게 하려면 Tukey의 검정을 사용하여 정리)

 

간략히 정리해 보자면.

 

음료의 만족감과 향(Flavour)의 관계를 확인하는 과정에서, 당도(Sweet)를 공변량으로 사용하는 공분산분석을 시행했다. 당도는 F(1, 86) = 73.929, p<0.001 향은 F(2,86) = 95.374, p<0.001 에서 모두 유의한 영향을 주는 것이 확인됐다.

 

(사후검정까지 진행했을 경우) 각 변수의 영향력에 따른 차이는 다음과 같이 정리된다(사후검정 표 내용). 향에 따른 만족도의 차이는 ~집단에서 에서 유의했으며 ~집단에서 유의하지 않았다. 이는 다음과 같은 형태를 보인다 (산점도 시각화)

 

* 분야에 따라 통계 보고 과정에서 효과크기(Effect Size)의 보고를 요구하는 경우가 있습니다. 이는 Partial eta-sqaure, Omega-square 등의 개념과 연결되지만 본 포스팅에서 깊게 다루기엔 한계가 있으므로 여기서는 언급하지 않았습니다.

 


더 많은 문제들

오늘은 공분산분석(ANCOVA)의 간단한 설명과 실습을 진행해 봤습니다.

 

오늘 다룬 내용을 기본으로 통계 검정 과정을 더 깊게 들어가면 분산분석의 여러 이슈들이 나오는데요.

 

예를 들어, 분산분석에서 변수 적용 순서의 문제(Type 1,2,3)라든지, 선형모형과 결합된 가정의 확인(QQ-Plot)이라든지, 여러 변수를 사용하는 과정에서 비교의 구성(Contrasts), 효과크기(Effect Size)의 문제 등이 존재합니다.

 

해당 개념은 일정 수준의 수학(혹은 통계) 지식을 요구하며 체계적으로 실습하려면 R과 같은 통계에 집중된 툴을 사용하는 것이 적합하기 때문에, 본 포스팅에서는 추가로 다루지 않았습니다.

 

관심이 있을 경우 해당 키워드로 검색 or 통계 서적을 통해 추가 학습을 하는 것을 추천드립니다.

반응형