Cute Hello Kitty 3
본문 바로가기
Data/통계

카이제곱(Chi-Square) 검정 / 범주형 데이터 분석 / 독립성 검정 / 동질성 검정 / 적합도 검정

by 민 채 2025. 4. 7.
 
 
 

 

카이제곱(Chi-Square) 검정

통계 분석에서 우리가 다루는 데이터는 꼭 숫자만 있는 게 아닙니다.
“성별과 제품 선호도는 관련이 있을까?”처럼 범주형 데이터 간의 관계를 분석하고 싶을 때가 있죠.

이럴 때 바로 필요한 게 카이제곱(χ²) 검정입니다.

 

카이제곱 검정이란?

관측된 데이터(Observed)가 기대되는 분포(Expected)와 얼마나 다른지를 검정하는 통계 방법입니다.

주로 범주형 데이터에 사용되며, 다음과 같은 경우에 많이 쓰입니다.

상황 목적 예시
독립성 검정 두 범주형 변수 간 관계가 있는가? 성별과 쇼핑몰 이용 여부가 관련이 있는가?
적합도 검정 데이터가 특정 분포를 따르는가? 주사위를 60번 던졌을 때 눈이 고르게 나왔는가?
동질성 검정 여러 그룹이 같은 분포를 가지는가? 지역별로 선호하는 음료수가 동일한 분포인가?

 

핵심 개념

카이제곱 분포는 다음과 같은 수학적 정의를 갖습니다:

n개의 독립적인 표준 정규분포(평균 0, 분산 1)를 따르는 확률변수 Z₁, Z₂, ..., Zₙ에 대해,
이들의 제곱합은 자유도 n인 카이제곱 분포를 따릅니다.

$$ X = Z_1^2 + Z_2^2 + \cdots + Z_n^2 \sim \chi^2(n) $$

즉, 정규분포를 제곱해서 더한 것이 카이제곱 분포입니다.

 

카이제곱 분포의 특징

  1. 표준정규분포(Z) 를 기반으로 만들어진다.
  2. Z²는 자유도 1인 카이제곱 분포를 따른다.
  3. n개의 독립적인 Z²의 합은 자유도 n인 카이제곱 분포를 따른다.
  4. 오른쪽 꼬리가 긴 비대칭 분포이다.
  5. 자유도 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