카이제곱검정(Chi-square test)이란?
05 Aug 2025 | Statistics개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있습니다.
데이터에 따른 분류
입력(x) - 출력(y)
- 수치 - 수치: 회귀모델
- 수치 - 범주(이진): 로지스틱회귀모델
- 범주 - 수치: t test, ANOVA
- 범주 - 범주: 카이제곱검정
모수적/비모수적
- 모수적: 데이터가 정규분포를 따름
- 비모수적: 정규분포에 대한 가정이 거의 없음 > 설명력이 떨어짐
카이제곱검정(Chi-square test)
범주형 데이터의 분포나 변수 간의 독립성을 검정하는 비모수 통계 방법
- 관측 빈도와 기대 빈도의 차이를 이용하여 가설을 검정하며
- 카이제곱 분포를 따르는 검정통계량을 사용
카이제곱 검정의 기본 원리
- 기본 아이디어: 관측값과 기대값의 차이가 우연에 의한 것인지 체계적인 것인지 판단
- 검정통계량: χ² = Σ[(관측빈도 - 기대빈도)² / 기대빈도]
- 분포: 카이제곱 분포 (Chi-square distribution)
- 자유도: 범주 수와 제약 조건에 따라 결정
카이제곱 검정의 기본 가정
- 독립성: 관측치들이 서로 독립적이어야 함
- 범주형 데이터: 명목형 또는 순서형 범주 데이터
- 충분한 빈도: 각 셀의 기대빈도가 5 이상 (Fisher의 정확검정 대안 고려)
- 무작위 표본: 모집단에서 무작위로 추출된 표본
카이제곱 검정의 종류
카이제곱 검정은 분석 목적에 따라 두 가지 주요 유형으로 나뉨
1. 적합성 검정 (Goodness of Fit Test)
- 목적: 관측된 데이터가 특정 분포나 비율을 따르는지 검정
- 사용 상황: 단일 범주형 변수의 분포 검정
- 예시: “실린더 수 분포가 균등한가?”, “성별 비율이 1:1인가?”
2. 독립성 검정 (Test of Independence)
- 목적: 두 범주형 변수가 서로 독립적인지 검정
- 사용 상황: 교차표(분할표)를 이용한 연관성 분석
- 예시: “성별과 선호도가 독립적인가?”, “치료법과 결과가 연관되어 있는가?”
예시
데이터 구조
- 관측치 수: 32개 (32대의 자동차)
- 변수 수: 11개 (모델명 + 10개 특성 변수)
- 데이터 타입: CSV 형식
- 결측치: 없음
변수 설명
변수명 | 한글명 | 데이터 타입 | 단위 | 설명 |
---|---|---|---|---|
model |
모델명 | 문자형 | - | 자동차 모델명 (예: Mazda RX4, Toyota Corolla) |
mpg |
연비 | 연속형 | miles/gallon | 연료 효율성 (갤런당 마일) |
cyl |
실린더 수 | 이산형 | 개 | 엔진 실린더 개수 (4, 6, 8) |
disp |
배기량 | 연속형 | cubic inch | 엔진 배기량 (세제곱인치) |
hp |
마력 | 연속형 | hp | 총 마력 |
drat |
뒤차축 비율 | 연속형 | - | 후방차축 기어비 |
wt |
중량 | 연속형 | 1000 lbs | 자동차 중량 (1000파운드 단위) |
qsec |
1/4마일 시간 | 연속형 | 초 | 1/4마일 주행 시간 |
vs |
엔진 형태 | 이진형 | - | V형 엔진(0) 또는 직렬 엔진(1) |
am |
변속기 타입 | 이진형 | - | 자동 변속기(0) 또는 수동 변속기(1) |
gear |
기어 수 | 이산형 | 개 | 전진 기어 개수 (3, 4, 5) |
carb |
카뷰레터 수 | 이산형 | 개 | 카뷰레터 개수 (1, 2, 3, 4, 6, 8) |
변수별 상세 정보
연속형 변수
- mpg (연비): 10.4 ~ 33.9 miles/gallon
- disp (배기량): 71.1 ~ 472.0 cubic inches
- hp (마력): 52 ~ 335 마력
- drat (뒤차축 비율): 2.76 ~ 4.93
- wt (중량): 1.513 ~ 5.424 (1000 lbs)
- qsec (1/4마일 시간): 14.50 ~ 22.90 초
범주형 변수
- cyl (실린더 수): 4기통(11대), 6기통(7대), 8기통(14대)
- vs (엔진 형태): V형 엔진(18대), 직렬 엔진(14대)
- am (변속기): 자동(19대), 수동(13대)
- gear (기어 수): 3단(15대), 4단(12대), 5단(5대)
- carb (카뷰레터): 1개(7대), 2개(10대), 3개(3대), 4개(10대), 6개(1대), 8개(1대)
독립성 검정
from scipy.stats import chi2_contingency
# 변속기 타입(am)
am_count = df['am'].value_counts() # 범주/수치 상관없이 사용
# 실린더 수(cyl)
cyl_count = df['cyl'].value_counts().sort_index() # 범주/수치 상관없이 사용
# 교차표 만드는 메소드 > .crosstab
contingency_table = pd.crosstab(df['am'], df['cyl'], margins=True)
# 합계 행렬 부분 삭제
observed = contingency_table.iloc[:-1,:-1]
# 합계부분 제거 후 , 모델에 넣기 위한 사전 작업
observed = contingency_table.iloc[:-1,:-1].values
# 카이제곱 검정을 통한 데이터 확인
chi2_stat, p_val, dof, expected = chi2_contingency(observed)
print(chi2_stat) # 카이제곱
print(p_val) # p-value
print(dof) # 자유도
print(expected) # 기댓값
# 8.740732951259268
# 0.012646605046107276 > 0.05보다 작다 = 귀무가설 기각, 대립가설 채택
# 2
# [[6.53125 4.15625 8.3125 ]
# [4.46875 2.84375 5.6875 ]]
실린더 수(cyl)와 변속기 유형(am) 사이의 독립성 검정에서는:
- H₀: 실린더 수와 변속기 유형은 서로 관련이 없다
- H₁: 실린더 수와 변속기 유형은 서로 관련이 있다
적합성 검정(Goodness of Fit Test)
2.1 언제 적합성 검정을 사용하는가?
상황 | 예시 질문 | 실무 적용 |
---|---|---|
균등성 검정 | “모든 범주가 똑같이 나타나는가?” | 주사위 공정성, 웹사이트 A/B 테스트 균등 배분 |
특정 비율 검정 | “예상한 비율과 일치하는가?” | 시장 점유율 예측 vs 실제, 유전자 비율 검정 |
이론 분포 검정 | “특정 확률 분포를 따르는가?” | 포아송 분포, 정규분포 적합성 |
2.2 검정 개념 및 가설
적합성 검정은 하나의 범주형 변수가 특정 이론적 분포와 일치하는지 검정
핵심 아이디어:
- 관측된 빈도 vs 기대되는 빈도 비교
- χ² = Σ[(관측값 - 기대값)²/기대값]
가설 설정:
- H₀: 관측 분포 = 기대 분포 (차이는 우연)
- H₁: 관측 분포 ≠ 기대 분포 (체계적 차이 존재)
결과 해석 가이드:
- p < 0.05: 기대 분포와 다르다 (H₀ 기각)
- p ≥ 0.05: 기대 분포와 일치한다고 볼 수 있다 (H₀ 채택)
# 관측빈도
observed_cyl = df['cyl'].value_counts().sort_index()
observed_cyl # 우리가 관측한 빈도는 11:7:14
# 기대빈도(이론상)
n_total = len(df)
n_categories = len(observed_cyl) # 3개 의미
expected_equal = np.repeat(n_total / n_categories, n_categories)
# 첫번째 인자를 두번째 인자만큼 반복 > 균등분포
# n_total / n_categories > 평균
print(n_total)
print(n_categories)
print(expected_equal) # 전체 카테고리합을 개수로 나눠서 균등하게 나눔(=균등분포표현)
# 32
# 3
# [10.66666667 10.66666667 10.66666667]
# 카이제곱 검정 실행
from scipy.stats import chi2_contingency, chisquare, fisher_exact
chi2_stat, p_val = chisquare(f_obs=observed_cyl.values, f_exp=expected_equal)
print(chi2_stat)
print(p_val)
# 2.3125
# 0.314663961018459 > 0.05보다 크다 > 귀무가설 채택 / 대립가설 기각
# => 기대분포와 일치