표준정규분포의 제곱 형태()에서 표본 데이터로 가정하면 ()이고 을 분모와 분자에 곱하여 위 식 유도
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}")
# 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