카이제곱 검정은 두 범주형 변수에 대한 분석 방법이다.
다음의 세가지 검증 방법이 있다.
사용 상황: 한 범주형 변수의 관측된 분포가 예상되는 분포(기대치)와 일치하는지 검증할 때 사용한다.
예시:
주사위를 100번 던졌을 때 각 면(1~6)이 나오는 비율이 공정한 주사위의 기대 비율(1/6)과 일치하는지 검증.
가설:
사용 상황:
두 범주형 변수가 서로 독립인지(관련이 없는지) 확인할 때 사용한다.
예시:
사용 상황:
여러 집단의 특정 범주형 변수 분포가 동일한지 비교할 때 사용한다.
예시:
세 개의 다른 마케팅 채널(A, B, C)을 통해 접촉한 고객들이 구매를 했는지(구매/미구매) 여부가 채널 간에 동일한 분포를 보이는지 확인.
가설:
주사위를 100번 던졌을 때, 각 면의 빈도가 공정한 주사위의 기대값과 같은지 검증하는 예제.
import numpy as np
from scipy.stats import chisquare
# 관측값 (주사위를 던져 나온 결과)
observed = np.array([18, 20, 17, 15, 16, 14]) # 각 면의 빈도
# 기대값 (공정한 주사위라면 100번 중 각 면이 나올 확률은 1/6)
expected = np.full(6, 100 / 6) # 1차원 배열 (길이 6) , 모든 값 100/6
# [16.66666667 16.66666667 16.66666667 16.66666667 16.66666667 16.66666667]
# 카이제곱 적합도 검정
chi2, p_value = chisquare(observed, expected)
print(f"Chi-squared Statistic: {chi2}")
print(f"P-value: {p_value}")
if p_value < 0.05:
print("귀무가설 기각: 주사위는 공정하지 않는다.")
else:
print("귀무가설 채택: 주사위는 공정한다.")
np.full은 NumPy에서 특정 크기와 모양(shape)의 배열을 생성하고, 모든 요소를 동일한 값으로 채우는 함수.np.full(shape, fill_value, dtype=None)
shape: 배열의 모양 (정수 또는 튜플)fill_value: 배열을 채울 값dtype: 배열 데이터 타입 (선택, 기본은 fill_value의 타입)
성별과 구매 여부 간의 독립성을 검증하는 예제.
import pandas as pd
from scipy.stats import chi2_contingency
# 교차표 데이터 (성별과 구매 여부)
data = pd.DataFrame({
"구매": [30, 50], # 남성, 여성
"미구매": [70, 50]
}, index=["남성", "여성"])
# 카이제곱 독립성 검정
chi2, p_value, dof, expected = chi2_contingency(data)
print(f"Chi-squared Statistic: {chi2}")
print(f"P-value: {p_value}")
print(f"Expected Frequencies:\n{expected}")
if p_value < 0.05:
print("귀무가설 기각: 성별과 구매 여부는 독립이 아닙니다.")
else:
print("귀무가설 채택: 성별과 구매 여부는 독립입니다.")
마케팅 채널(A, B, C) 간 구매 분포가 동일한지 검증하는 예제.
from scipy.stats import chi2_contingency
# 관측된 데이터 (각 채널 별 구매/미구매 수)
data = [
[40, 60], # 채널 A (구매, 미구매)
[35, 65], # 채널 B (구매, 미구매)
[50, 50] # 채널 C (구매, 미구매)
]
# 카이제곱 동질성 검정
chi2, p_value, dof, expected = chi2_contingency(data)
print(f"Chi-squared Statistic: {chi2}")
print(f"P-value: {p_value}")
print(f"Expected Frequencies:\n{expected}")
if p_value < 0.05:
print("귀무가설 기각: 채널 간 구매 분포는 동일하지 않는다.")
else:
print("귀무가설 채택: 채널 간 구매 분포는 동일한다.")
chi2_stat, p_value, dof, expected = stats.chi2_contingency(observed=result)
scipy.stats.chi2_contingency 함수는 카이제곱 검정을 수행하며, 이 함수가 반환하는 값들(chi2_stat, p_value, dof, expected)은 다음과 같은 의미를 가진다:
χ^2 =∑ (O−E)^2/E
O: 관측값 (observed values)
𝐸: 기대값 (expected values)
- 𝑝 < 0.05 : 통계적으로 유의미함 (독립 아님).
- 𝑝 ≥ 0.05 : 통계적으로 유의미하지 않음 (독립).
dof (Degrees of Freedom)
expected (Expected Frequencies)
두 변수가 독립이라고 가정했을 때 기대되는 빈도값(기대값)의 배열이다.
각 셀의 기대값은 다음 공식으로 계산된다:
E_ij = (행합계 i)×(열합계 j) / 전체합계
기대값과 관측값 간의 차이가 클수록 두 변수 간의 관계가 강하다는 것을 나타낸다.
예시를 통한 값의 이해
import numpy as np
from scipy.stats import chi2_contingency
# 관측 데이터
result = np.array([[30, 20, 50], # 계절 A
[40, 30, 30], # 계절 B
[50, 40, 10]]) # 계절 C
# 카이제곱 검정 수행
chi2_stat, p_value, dof, expected = chi2_contingency(result)
print("Chi-squared Statistic:", chi2_stat)
print("P-value:", p_value)
print("Degrees of Freedom:", dof)
print("Expected Frequencies:\n", expected)
출력:
Chi-squared Statistic: 16.25
P-value: 0.0125
Degrees of Freedom: 4
Expected Frequencies:
[[40. 30. 30.]
[40. 30. 30.]
[40. 30. 30.]]
해석:
chi2_stat : 16.25 로, 관측값과 기대값 간의 차이를 나타낸다.p_value : 0.0125로, 0.05보다 작기 때문에 두 변수(계절과 색상)는 독립적이지 않다고 결론지을 수 있다.dof : 4로, (행의 개수 - 1) × (열의 개수 - 1)로 계산된다.expected : 기대값 배열로, 독립을 가정했을 때 각 셀에서 기대되는 빈도를 보여준다.카이제곱 통계량 (𝜒^2) 값이 클수록 두 변수 간의 관계가 강하다는 것은 일반적인 경향일 뿐, 항상 그런 것은 아니다.
표본 크기의 영향:
관측값과 기대값의 차이
𝜒^2 값이 크더라도 이를 단독으로 해석하지 않고, p-value와 함께 해석해야 한다.
예시:
- 큰 𝜒^2 값, 작은 p-value:
변수 간에 관계가 있고, 그 관계가 통계적으로 유의미하다고 결론 내릴 수 있다.- 큰 𝜒^2 값, 큰 p-value:
표본 크기의 영향일 가능성이 크며, 관계가 유의미하지 않을 수 있다.
변수 간의 관계 강도를 더 잘 이해하려면 Cramér's V와 같은 추가 통계량을 사용할 수 있다.
Cramér's V는 𝜒^2 값을 표본 크기와 자유도로 조정하여, 관계 강도를 0과 1 사이의 값으로 나타낸다.