카이제곱 검정

이정훈·2026년 2월 8일

카이제곱 정의

  • 서로 독립적인 표준정규분포 확률변수들의 제곱합이 따르는 연속 확률분포
  • 개별 데이터의 z값의 제곱의 합을 분포로 표현
  • 분표준정규분포처럼 현실에 적용가능한 분포가 아니라 통게적 추론 및 검정을 위해 표준정규분포로부터 수학적으로 유도해낸 분포
    χ2=i=1kZi2\chi^2 = \sum_{i=1}^{k} Z_i^2

카이제곱 검정 종류

1. 모집단 분산의 변화를 검정하거나 신뢰구간을 추정

(n1)S2σ2χ2(n1)\frac{(n-1)S^2}{\sigma^2} \sim \chi^2(n-1)

표준정규분포의 제곱 형태(i(xiμ)2σ2\frac{\sum_i(x_i - \mu)^2}{\sigma^2})에서 표본 데이터로 가정하면 (i(xiXˉ)2σ2\frac{\sum_i(x_i - \bar{X})^2}{\sigma^2})이고 n1n-1 을 분모와 분자에 곱하여 위 식 유도

2. 응용버전인 적합성 검정, 독립성 검정, 동질성 검정

χ2=(OiEi)2Ei\chi^2 = \sum \frac{(O_i - E_i)^2}{E_i}

적합성 검정 (Goodness of Fit Test)

  • 관측된 데이터가 이론적으로 가정한 특정 분포(또는 비율)에 잘 맞는지를 검정하는 방법
  • 범주형 데이터(Categorical Data)의 빈도를 다루는 비모수 검정
  • 각 범주의 E[X]E[X]는 각범주가 독립이라고 가정했을 때 계산된 값
  • 가설 설정
    H0H_0: 관측된 분포는 가정한 분포와 같다
    H1H_1: 관측된 분포는 가정한 분포와 다르다
import pandas as pd
from scipy.stats import chi2

# 두 범주형 변수 설정 (예시를 위한 변수명)
# var1: 행(Row) 기준 범주형 데이터 (예: 고객 등급)
# var2: 열(Column) 기준 범주형 데이터 (예: 구매 여부)

from scipy import stats

# 1. 관측 빈도 (총 120회)
observed = [15, 28, 12, 17, 26, 22]

# 2. 이론적 기대 빈도 (공정한 주사위라면 각각 20회씩 나와야 함)
expected = [20, 20, 20, 20, 20, 20]  # 생략 시 자동으로 균등 분배됨


# 3. 적합도 검정 수행 (한번에 아래 계산 하는 법)
stat, p_val = stats.chisquare(f_obs=observed, f_exp=expected)

-----------------------------------------------------------------------
# ==========================================
# 3. 카이제곱 통계량 및 자유도 계산
# ==========================================
# 통계량 공식: Σ((기대값 - 관측값)^2 / 기대값)
chi2_stat = (((df_expected - df_observed) ** 2) / df_expected).sum().sum()

# 자유도: (행의 수 - 1) * (열의 수 - 1)
dof = (var1.nunique() - 1) * (var2.nunique() - 1)

# ==========================================
# 4. p-value 산출
# ==========================================
# 생존 함수(Survival function, 1 - CDF)를 사용하여 우측 꼬리 확률을 구함
p_value = chi2.sf(chi2_stat, dof)

print(f"카이제곱 통계량: {chi2_stat:.4f}")
print(f"자유도: {dof}")
print(f"p-value: {p_value:.4f}")

독립성 검정 (Test of Independence / 동질성 검정 (Test of Homogeneity)

  • 두 범주형 변수가 독립인지 연관성이 있는지 확인
  • 적합도 검정은 특정 분포와 비교, 독립성 검정은 두 변수끼리 비교
  • 가설 설정
    H0H_0: 두 변수는 서로 독립이다.
    H1H_1: 두 변수는 서로 독립이 아니다.
χ2=i=1rj=1c(OijEij)2Eij\chi^2 = \sum_{i=1}^{r} \sum_{j=1}^{c} \frac{(O_{ij} - E_{ij})^2}{E_{ij}}
df=(r1)×(c1)df = (r - 1) \times (c - 1)

# 1. 분할표 데이터 생성 (행: 서버, 열: 로그 유형)
# 데이터 의미: Server_A는 INFO 400개, WARN 80개, ERROR 20개 발생
data = np.array([
    [400, 80, 20],  # Server_A
    [350, 90, 60]   # Server_B (에러가 좀 더 많아 보임)
])

df = pd.DataFrame(data, 
                  index=['Server_A', 'Server_B'], 
                  columns=['INFO', 'WARN', 'ERROR'])

# 2. 카이제곱 독립성 검정 수행
# chi2: 통계량, p: p-value, dof: 자유도, expected: 기대 빈도
chi2, p, dof, expected = stats.chi2_contingency(data)

# 3. 결과 출력
print(f"카이제곱 통계량: {chi2:.4f}")  # 23.9216
print(f"p-값 (p-value): {p:.4f}")  # 0.0000 --> 귀무가설 기각, 연관이 없다.
print(f"자유도: {dof}")  # 2
profile
AngDDo

0개의 댓글