카이제곱(Chi-Square) 검정
통계 분석에서 우리가 다루는 데이터는 꼭 숫자만 있는 게 아닙니다.
“성별과 제품 선호도는 관련이 있을까?”처럼 범주형 데이터 간의 관계를 분석하고 싶을 때가 있죠.
이럴 때 바로 필요한 게 카이제곱(χ²) 검정입니다.
카이제곱 검정이란?
관측된 데이터(Observed)가 기대되는 분포(Expected)와 얼마나 다른지를 검정하는 통계 방법입니다.
주로 범주형 데이터에 사용되며, 다음과 같은 경우에 많이 쓰입니다.
상황 | 목적 | 예시 |
독립성 검정 | 두 범주형 변수 간 관계가 있는가? | 성별과 쇼핑몰 이용 여부가 관련이 있는가? |
적합도 검정 | 데이터가 특정 분포를 따르는가? | 주사위를 60번 던졌을 때 눈이 고르게 나왔는가? |
동질성 검정 | 여러 그룹이 같은 분포를 가지는가? | 지역별로 선호하는 음료수가 동일한 분포인가? |
핵심 개념
카이제곱 분포는 다음과 같은 수학적 정의를 갖습니다:
n개의 독립적인 표준 정규분포(평균 0, 분산 1)를 따르는 확률변수 Z₁, Z₂, ..., Zₙ에 대해,
이들의 제곱합은 자유도 n인 카이제곱 분포를 따릅니다.
즉, 정규분포를 제곱해서 더한 것이 카이제곱 분포입니다.
카이제곱 분포의 특징
- 표준정규분포(Z) 를 기반으로 만들어진다.
- Z²는 자유도 1인 카이제곱 분포를 따른다.
- n개의 독립적인 Z²의 합은 자유도 n인 카이제곱 분포를 따른다.
- 오른쪽 꼬리가 긴 비대칭 분포이다.
- 자유도 n이 커질수록 정규분포에 가까워진다. (중심극한정리)
자유도에 따른 분포 형태
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import chi2
# 한글을 사용하기 위해 설정 추가
plt.rcParams['font.family'] ='Malgun Gothic'
plt.rcParams['axes.unicode_minus'] =False
# 자유도에 따른 카이제곱 분포 시각화
k = np.linspace(0, 40, 200)
pdf_chi = chi2.pdf(k, df=3)
pdf_chi_7 = chi2.pdf(k, df=20)
plt.plot(k, pdf_chi, label='자유도 3', color='red')
plt.plot(k, pdf_chi_7, label='자유도 20', color='green')
plt.title('자유도에 따른 카이제곱 분포')
plt.xlabel('x')
plt.ylabel('Density')
plt.legend()
plt.show()
위와 같은 파이썬 코드로 카이제곱 분포를 시각화 해보았습니다.
chi2 를 import 한 뒤 matplotlib을 사용하면 간단히 시각화할 수 있습니다.
위 코드로 시각화한 결과물입니다. 오른쪽 꼬리가 긴 형태를 가지고 있습니다.
또한, 자유도가 클수록 종모양에 가까워지는 것을 볼 수 있습니다.
종류별 카이제곱 검정
1. 독립성 검정
두 범주형 변수 간 연관성이 있는지를 검정
예시:
한 쇼핑몰에서 성별과 구매 여부 간에 관계가 있는지를 알고 싶습니다.
이를 알기 위해 귀무가설과 대립가설을 설정합니다. 귀무가설은 일반적인 사실로 설정하고, 대립가설에 우리가 증명하고 싶은 사실을 넣습니다.
귀무가설(H0): 성별과 구매 여부는 관련이 없다.
대립가설(H1): 성별에 따라 구매 여부가 달라진다.
성별 | 구매함 | 구매 안 함 |
남성 | 30 | 20 |
여성 | 40 | 10 |
시각화
누적막대그래프로 시각화를 해보았습니다.
남성보다 여성의 구매 비율이 더 높은 것을 한 눈에 확인할 수 있습니다.
그렇다면,
이 차이가 단순한 우연인지, 아니면 통계적으로 유의미한 차이인지를 판단할 필요가 있습니다.
시각화는 경향을 보여주기에는 좋지만,
수치적으로 "의미 있는 차이"인지 여부는 판단할 수 없습니다.
이럴 때 사용하는 것이 바로 카이제곱 독립성 검정입니다.
성별과 구매여부가 전혀 무관하다는 가정 하에 계산된 기대값의 차이를 계산하여
그 차이가 우연으로 보기 어려울 정도로 큰지를 평가합니다.
즉,
“성별과 구매 여부는 독립이다”라는 귀무가설을 기각할 수 있는가?"
를 검증함으로써,
우리가 관측한 이 비율 차이가 통계적으로도 의미 있는지를 확인할 수 있습니다.
파이썬 코드를 통해 카이제곱 검정을 수행해보겠습니다.
독립성 검정: 파이썬 코드
import numpy as np
import pandas as pd
from scipy.stats import chi2_contingency
# 교차표 생성
data = np.array([[30, 20],
[40, 10]])
# 카이제곱 독립성 검정
chi2, p, dof, expected = chi2_contingency(data)
print(f"카이제곱 통계량: {chi2:.4f}")
print(f"p-value: {p:.4f}")
print(f"자유도: {dof}")
print("기대 빈도표:")
print(np.round(expected, 2))
출력 결과:
카이제곱 통계량: 3.8571428571428577
p-value: 0.04953461343562649
자유도: 1
# 기대값이란?
# 성별과 구매 여부가 전혀 관련이 없다고 했을 때 나와야 하는 평균 빈도수
기대값:
[[35. 15.]
[35. 15.]]
p-value 가 0.0495 이므로, 유의수준 0.05 (5%) 를 기준으로 볼 때, 귀무가설을 기각할 수 있습니다.
✔ 결론: "성별과 쇼핑몰 이용 여부는 통계적으로 유의미한 관계가 있다" 라고 할 수 있습니다.
2. 적합도 검정
관측된 데이터가 이론적 분포와 얼마나 잘 일치하는지를 확인하는 통계 검정입니다.
예시:
동전을 던졌을 때 앞/뒤가 똑같이 나올 것이라 기대하거나,
공정한 주사위라면 1~6이 균등한 비율로 나올 거라 기대하게 됩니다.
그런데 실제로 실험을 해보면 결과가 기대와 약간 다를 수 있습니다.
그 차이가 "우연인지", 아니면 "분포가 실제로 다르기 때문인지" 판단하는 게 이 검정의 목적입니다.
어떤 사람이 주사위를 60번 던졌습니다.
공정한 주사위라면 1~6이 각각 10번씩 나와야 합니다.
하지만 실제 결과는 아래와 같았습니다:
눈 | 관측값 |
1 | 8 |
2 | 11 |
3 | 10 |
4 | 9 |
5 | 12 |
6 | 10 |
시각화
- 관측값: 실험에서 실제로 관찰된 횟수 → [8, 11, 10, 9, 12, 10]
- 기대값: 공정하다면 기대되는 횟수 → [10, 10, 10, 10, 10, 10]
가설 설정:
- 귀무가설(H₀): 주사위는 공정하다 → 각 눈이 나올 확률은 모두 1/6
- 대립가설(H₁): 주사위는 공정하지 않다 → 각 눈이 나올 확률이 다르다
적합도 검정: 파이썬 코드
from scipy.stats import chisquare
observed = [8, 11, 10, 9, 12, 10]
expected = [10] * 6 # 공정한 주사위일 때 기대값
chi2, p = chisquare(f_obs=observed, f_exp=expected)
print("카이제곱 통계량:", chi2)
print("p-value:", p)
출력 결과:
카이제곱 통계량: 1.4
p-value: 0.9231
- 카이제곱 통계량: 기대값과 관측값 간의 차이 크기
- p-value: 귀무가설을 기각할 수 있는지 판단하는 기준
p-value = 0.9231 > 0.05 이므로 귀무가설을 기각할 수 없습니다.
즉, 이정도의 차이는 우연일 수 있으며 분포가 다르다고 단정지을 수 없게 됩니다.
3. 동질성 검정
여러 집단(범주형 그룹) 간에 같은 분포를 따르고 있는지 검정하는 방법입니다.
예를 들어,
- 서울, 부산, 대전 사람들의 음료 선호도 분포가 모두 같을까?
- A상품에 대해 연령대별로 구매 비율이 동일할까?
이런 질문에 답하고 싶을 때, 사용하는 검정이 동질성 검정입니다.
예시 상황
한 회사가 세 지역(A, B, C)의 사람들을 대상으로 좋아하는 음료를 조사했습니다.
응답자들에게 콜라 / 사이다 / 물 중 가장 선호하는 음료를 고르게 했고,
그 결과는 다음과 같았습니다:
지역 | 콜라 | 사이다 | 물 |
A | 28 | 32 | 40 |
B | 30 | 35 | 35 |
C | 42 | 28 | 20 |
시각화
- 지역별로 약간의 차이는 있지만 전체적으로 비슷해 보이기도 합니다.
- 즉, 시각적으로 차이가 있는지 아닌지 애매한 상황입니다.
- 하지만, 이정도의 차이가 우연일지 아니면 통계적으로 유의미한 지 추가적으로 증명해볼 필요가 있습니다.
시각화 코드
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 데이터: [콜라, 사이다, 물]
data = np.array([
[28, 32, 40], # A
[30, 35, 35], # B
[42, 28, 20] # C
])
regions = ['A', 'B', 'C']
categories = ['콜라', '사이다', '물']
colors = ['#fc8d62', '#66c2a5', '#8da0cb']
# 각 행의 합으로 나눠서 퍼센트 계산
row_sums = data.sum(axis=1, keepdims=True)
data_percent = data / row_sums
fig, ax = plt.subplots(figsize=(7, 5))
bottom = np.zeros(len(data)) # [0, 0, 0]
# 누적 비율형 막대그래프 그리기
for i in range(len(categories)):
ax.bar(regions, data_percent[:, i], bottom=bottom, label=categories[i], color=colors[i])
bottom += data_percent[:, i]
# 그래프 설정
plt.title("동질성 검정: 지역별 음료 선호 비율")
plt.ylabel("비율 (%)")
plt.ylim(0, 1.05)
plt.legend(title="음료 종류")
plt.grid(axis='y', linestyle='--', alpha=0.5)
plt.tight_layout()
plt.show()
가설 설정
- 귀무가설(H₀): 지역별로 음료 선호도 분포는 동일하다
- 대립가설(H₁): 지역별로 음료 선호도 분포가 다르다
동질성 검정: 파이썬 코드
import numpy as np
from scipy.stats import chi2_contingency
# 데이터: [콜라, 사이다, 물]
data = np.array([
[28, 32, 40], # A
[30, 35, 35], # B
[42, 28, 20] # C
])
chi2, p, dof, expected = chi2_contingency(data)
print("카이제곱 통계량:", chi2)
print("p-value:", round(p, 4))
print("자유도:", dof)
print("기대값:\n", np.round(expected, 2))
출력 결과:
카이제곱 통계량: 10.725590643274854
p-value: 0.0298
자유도: 4
기대값:
[[34.48 32.76 32.76]
[34.48 32.76 32.76]
[31.03 29.48 29.48]]
- p-value 가 0.02이므로 귀무가설을 기각할 수 있습니다. (유의수준 0.05 기준)
- 즉, 지역별로 선호 음료 분포가 유의미하게 다릅니다.
그래프 상으로 애매했던 부분을 카이제곱 검정을 통해 명확하게 검정할 수 있습니다.
결론
1. 시각화를 적극 활용하자.
데이터 분석에서 시각화는 문제의 패턴을 직관적으로 파악할 수 있는 강력한 도구입니다.
- 범주형 데이터의 경우, 막대그래프나 누적 비율 막대그래프를 통해
각 그룹(예: 지역, 성별 등) 간의 차이를 한눈에 볼 수 있습니다.
2. 통계적으로 유의미한지 추가적으로 검증하자.
- 즉, 통계 검정을 통해 시각화에서 본 차이가 우연인지, 의미있는 차이인지를 통계적으로 확인할 수 있습니다.
카이제곱 검정 요약
✅ 적합도 검정 (Goodness of Fit) |
하나의 분포가 기대한 분포와 일치하는지 | 주사위를 60번 던졌을 때 눈이 고르게 나왔는가? |
단일 막대그래프 |
✅ 독립성 검정 (Test of Independence) |
두 범주형 변수 간에 관련성이 있는지 | 성별과 쇼핑몰 이용 여부가 관련 있는가? | 그룹별 누적 비율 막대그래프 |
✅ 동질성 검정 (Test of Homogeneity) |
여러 집단 간에 분포가 동일한가 | 지역별 음료 선호 분포가 같은가? | 지역별 누적 비율 막대그래프 |
이번 글에서는 범주형 변수 분석에 유용한 카이제곱 검정을 알아봤습니다.
그렇다면, 수치형 데이터를 분석할 때는 어떻게 해야할까요?
가령, 세 지역의 평균 음료 소비량이 서로 다른 지 알고 싶을 경우 어떻게 해야할까요?
“세 지역의 하루 평균 커피 소비량이 서로 다른가?”
→ 이건 수치형 데이터죠.
이 경우에는 ANOVA(분산분석) 를 사용해야 합니다.
다음 포스팅에서는 ANOVA와 카이제곱 검정의 차이,
그리고 ANOVA 실습 예제를 다뤄보겠습니다.
2025.04.07 - [Data] - LS 빅데이터 스쿨 / 분산분석(ANOVA) / 수치형 데이터 비교 / 카이제곱 검정과의 차이점
LS 빅데이터 스쿨 / 분산분석(ANOVA) / 수치형 데이터 비교 / 카이제곱 검정과의 차이점
LS 빅데이터 스쿨에서 분산분석에 대해 배웠습니다.저번 시간에는 범주형 변수 분석에 유용한 카이제곱 검정에 대해 배웠으니, 이번 시간에는 수치형 데이터를 분석에 사용하는 분산분석에 대
kiminchae.tistory.com
'Data > 통계' 카테고리의 다른 글
사후 검정 / 본페로니 검정 / 튜키 검정 / Post-hoc Test (0) | 2025.04.08 |
---|---|
분산분석(ANOVA) / 수치형 데이터 비교 분석 / 카이제곱 검정과의 차이점 (0) | 2025.04.07 |
정규성 검정 / Shapiro-Wilk / Anderson-Darling / Kolmogorov–Smirnov / Q-Q Plot (0) | 2025.04.04 |
정규분포와 t분포 / Python (0) | 2025.04.03 |
확률질량함수(PMF), 확률밀도함수(PDF), 누적분포함수(CDF) (0) | 2025.03.27 |