본문 바로가기
Python notes/Statistical Analysis

파이썬) 범주형 변수의 상관관계 확인을 위한 교차분석 하기 (+카이제곱 검정)

by 성실한 나무 2021. 7. 22.

#1. 교차분석이란?

교차분석(cross-tabulation anlaysis)은 두 범주형 자료 간의 상관관계를 확인하기 위한 분석방법이다. 즉, 상호 관련성을 확인하고자 하는 두 변수가 명목척도일 때 사용하는 분석 방법이다. 교차분석을 하기 위해서 먼저 교차표를 만들어 두 변수 간의 관계를 정리하고, 관측빈도(observed frequency)와 기대빈도(expected frequency)를 확인할 수 있다. 이를 바탕으로 카이제곱 통계량을 계산하고, 이 검정통계량의 p-value를 통해 둘의 상관관계가 유의한지 유의하지 않은지를 판단할 수 있다.

 

 

#2. 파이썬에서 pandas와 scipy 패키지로 교차분석 하기

파이썬을 이용해 간단하게 교차분석을 할 수 있다. 이를 위해 먼저 pandas와 scipy 패키지를 설치해야 하며 아래와 같이 함수들을 모듈을 import 해야 한다.

1
2
import pandas as pd
from scipy.stats import chi2_contingency
cs

교차분석을 진행하기 위해 명목척도를 변수로 갖는 아래와 같이 DataFrame을 정의해보았다. 성별 별로 흡연 여부를 표시한 데이터프레임이다. df.head(3)을 통해 전체 데이터프레임 중 첫 세개의 행만 불러와 데이터프레임이 제대로 정의되었는지 확인도 하였다.

1
2
3
4
5
6
7
8
#교차분석 하기 위한 범주형 데이터 정의
df=pd.DataFrame({"성별":['남자''남자''남자''남자''남자''남자'
'남자''남자''남자''남자''남자''남자''남자''남자''남자''남자'
'남자''여자''여자''여자''여자''여자''여자''여자'], "흡연여부":['흡연'
'흡연''흡연''흡연''흡연','흡연''비흡연''흡연''흡연''흡연','흡연'
'비흡연''흡연''흡연''비흡연','비흡연''비흡연','비흡연''비흡연','비흡연''비흡연',
'비흡연''흡연''비흡연']})
df.head(3)
cs

pandas에서 불러온 crosstab이라는 함수를 사용해서 교차분석표를 만들 수 있는데, 기본적으로 pd.crosstab(df['변수명1'], df['변수명2']) 형태로 입력하면 간단하게 교차표가 그려진다. 여기서 margins라는 파라미터에 True를 입력하면 아래 그림과 같이 각 행과 열의 값을 sum한 합계 값이 교차표에 포함이 된다. margins에 False를 입력하면 이런 합계 값들은 없고, 각 경우의 빈도값만 표시된다.

파이썬 교차분석표 (관측값; observed)

 

이제 위의 교차분석표를 토대로 두 변수 간의 상관관계가 유의미한지 확인하기 위해 카이제곱 검정통계량을 구해야 한다. 이 때 사용하는 함수는 scipy 모듈의 chi2_contingency 함수이다. 이 함수를 통해 교차분석 결과값들을 일괄적으로 계산할 수 있다. chi2_contingency(observed=위에서 구한 pandas의 crosstab 객체, correction=False)를 객체 result에 담고 result를 실행한다. 이 때 주의할 점은 observed에 입력하는 crosstab 객체는 합계가 없는 교차분석표이어야 한다는 점이다. 즉, margins=False로 한 crosstab 객체를 observed에 파라미터로 입력해야 한다.

그러면, result는 아래와 같이 카이제곱 통계량, p-value, df, 기대값 행렬의 총 4개의 값을 반환한다.

반응형
1
2
3
4
5
6
7
8
9
10
11
12
13
#crosstab 객체의 margins=False여야 
smoke_crosstab=pd.crosstab(df['성별'], df['흡연여부'], margins=False)
 
#교차분석 결과값들 일괄계산
#correction=True를 적용하면 Yates' correction이 적용 되어 검정통계량이 보수적으로 더 낮게 나옴
result=chi2_contingency(observed=smoke_crosstab, correction=False)
print("1. 카이제곱 통계량:", result[0])
print("2. p-value:", result[1])
print("3. df:", result[2]) #(행의개수-1)*(열의개수-1)
print("4. 기대값 행렬:")
pd.DataFrame(result[3]).rename(index={0:'남자'1:'여자'}, columns={0:'비흡연'1:'흡연'})
 
 
cs

파이썬 카이제곱통계량, 기대값 행렬

 

 

#3. 수기로 기대값 행렬 및 카이제곱 통계량 계산하기

앞에서 구한 기대값 행렬과 카이제곱 통계량이 맞게 계산된 것인지 다시 한번 수기 계산을 통해 비교해 보았다. 먼저, 기대값 행렬은 각 셀에 값을 구하는데, 해당 셀에 해당하는 소계들을 곱하고 그 값을 총계로 나누어 각각 구한다. 그리고 이 행렬 값들을 모두 합하면 카이제곱 통계량이 된다. 앞서 구한 기대값 행렬과 동일한 값을 가지는 것을 확인할 수 있었다.

기대값 행렬 (기대값; Expected)

카이제곱 통계량은 "(각 관찰값- 각 기대값)제곱/ 각 기대값"들의 합이다. 텍스트로 보기보다 관찰값과 기대값이 적힌 교차표를 보면서 어떻게 계산했는지 보면 더 이해가 쉽다. 이번에도 파이썬으로 구한 카이제곱 통계량과 수기 계산한 통계량이 동일함을 확인할 수 있었다.

카이제곱 통계량 계산

 

 

#4. 데이터 종류에 적합한 상관관계 분석 방법 선택하기

상관관계를 확인하고자 하는 두 데이터의 데이터 종류가 등간척도, 비율척도 일 때는 피어슨 상관계수를 계산하고, 서열척도 일 때는 스피어만 상관계수를 사용한다. 그리고 위에서 확인한 바와 같이 두 변수가 명목척도일 때는 카이제곱 검정통계량을 통한 교차분석을 진행하여 상관관계의 유의성을 확인할 수 있다. 

 

 

 

"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."

댓글