정규성/gof 체크, 분산검정
정규성 검정
| 구분 | Shapiro-Wilk 검정 | Kolmogorov-Smirnov (K-S) 검정 |
|---|---|---|
| 목적 | 단일 표본의 정규분포 검정 | 두 분포의 동일성 검정 (또는 단일 표본의 특정 분포 적합도 검정) |
| 방법론 | 모수적/순서통계량 기반 | 비모수적 (누적분포함수(CDF) 간의 최대 거리 측정) |
| 특징 및 한계 | 샘플 크기가 작을 때(주로 또는 ) 통계적 검정력이 높음. | 샘플 크기가 클 때 유용함. 연속형 분포에만 적용 가능하며, 정규성 검정 외에도 다양한 분포 비교에 범용적으로 사용됨. |
| 귀무가설 () | 데이터가 정규분포를 따른다. | 두 표본이 동일한 분포를 따른다. (또는 데이터가 특정 분포를 따른다.) |
| 대립가설 () | 데이터가 정규분포를 따르지 않는다. | 두 표본이 동일한 분포를 따르지 않는다. (또는 데이터가 특정 분포를 따르지 않는다.) |
| 데이터 유형 | 검정법 | 귀무가설() | 대립가설() | 특징 및 용도 |
|---|---|---|---|---|
| 범주형 | 카이제곱 적합도 검정 | 관측빈도가 기대빈도와 일치한다 | 관측빈도가 기대빈도와 일치하지 않는다 | 다항분포 등 범주형 변수의 비율 검정. 기대빈도 5 미만 셀이 20% 이상이면 피셔의 정확검정 고려. |
| 연속형 | K-S 검정 (1표본) | 데이터가 특정 분포(예: 정규분포)를 따른다 | 데이터가 특정 분포를 따르지 않는다 | 누적분포함수(CDF)의 최대 차이를 기반으로 검정. 비모수적 방법. 누적분포함수(CDF) 기반. 모집단의 모수를 미리 알고 있을 때만 유효함. |
| 릴리포스 검정 | 데이터가 정규(또는 지수) 분포를 따른다 | 데이터가 정규(또는 지수) 분포를 따르지 않는다 | 표본에서 모수를 추정할 때 사용하는 K-S 검정의 보정판. K-S 검정의 지나치게 보수적인 한계 극복. | |
| 샤피로-윌크 검정 | 데이터가 정규분포를 따른다 | 데이터가 정규분포를 따르지 않는다 | 표본 수가 적을 때(일반적으로 ) 정규성 검정에 가장 강력한 성능을 보임. 소표본() 정규성 검정에서 통계적 검정력(Power)이 가장 우수함. | |
| 앤더슨-달링 검정 | 데이터가 특정 분포를 따른다 | 데이터가 특정 분포를 따르지 않는다 | 분포의 꼬리(tail) 부분 차이에 가중치를 두어 K-S 검정보다 민감하게 적합도를 판단함. | |
| 자크-베라 검정 | 데이터가 정규분포를 따른다 | 데이터가 정규분포를 따르지 않는다 | 표본의 왜도(Skewness)와 첨도(Kurtosis)를 이용하여 정규성을 검정. 대용량 데이터에 적합. 대용량 데이터 및 금융 데이터 회귀분석 잔차 검정에 적합. | |
| 모델 적합(로지스틱), 모델 평가 | 호스머-레메쇼 검정 | 회귀 모형이 데이터에 적합하다 | 회귀 모형이 데이터에 적합하지 않다 | 로지스틱 회귀분석의 모델 적합도 평가. 데이터를 그룹화하여 관측치와 예측치 비교. 로지스틱 회귀 모델의 예측 확률과 실제 관측치의 일치 정도를 평가. |
범주형 gof
| 검정 방법 | 기반 원리 | 검정통계량 | 장점 (Pros) | 단점 (Cons) | 특징 및 실무 적용 | ADP / ML 활용 포인트 | 사용 라이브러리 및 함수 | 필수 전처리 및 파라미터 |
|---|---|---|---|---|---|---|---|---|
| 카이제곱 검정 | 빈도 편차 (L2-norm 유사) | 가장 직관적이고 범용적임. 명목형(Nominal) 범주 데이터에 제약 없이 적용 가능함. | 기대빈도 5 미만 범주를 병합(Binning)해야 하므로 꼬리 부분의 정보 손실이 발생함. | 가장 대중적임. 기대 빈도 5 미만 범주의 병합(Binning) 필수. | 범주형 피처의 클래스 불균형 확인 및 다항분포 비율 검정에 기본적으로 활용. | scipy.stats.chisquare | 기대빈도 5 미만 범주 병합(Binning) 필수 | |
| G-검정 | 우도비 (Likelihood-ratio) | 통계량의 가산성(Additivity)이 보장됨. 정보이론(KL-Divergence) 기반으로 수학적 엄밀성이 높음. | 관측빈도가 0인 범주가 있을 경우 로그 계산에서 처리 문제가 발생함. 소표본에서는 카이제곱보다 근사가 불안정함. | 통계량 가산성 보장. 정보이론 및 로그 선형 모형 적합에 유리. | 로그 선형 모형, 로지스틱 회귀 등 머신러닝 분류기의 우도(Likelihood) 기반 성능 평가에 유리. | scipy.stats.power_divergence | lambda_='log-likelihood' 파라미터 지정 필수 | |
| 이산형 K-S 검정 | 누적분포함수(CDF) 최대 차이 | 범주 병합이 필요 없어 원본 데이터의 정보 손실이 발생하지 않음. | 누적의 개념이 필요하므로 명목형 변수에는 쓸 수 없음(순서성 필수). 내부 계산 비용이 높음. | 병합에 따른 정보 손실 방지. 순서성 있는 이산 데이터에 적합. | 순위(Rank) 데이터나 순서형(Ordinal) 카운트 데이터의 전체적인 분포 적합도 검정에 강력함. | scipy.stats.ks_1samp | method='exact' 옵션으로 이산형 도약(Jump) 보정 | |
| 이산형 CvM 검정 | 누적분포함수(CDF) 차이 제곱합 | K-S 검정보다 분포 전체의 편차를 더 민감하게 반영하여 검정력이 높음. | 계산이 복잡하며 이산형 데이터에 대한 완벽한 라이브러리 지원이 제한적임. | K-S 검정보다 분포 전체의 편차를 더 민감하게 반영함. | 경험적 누적분포함수(eCDF)를 활용한 모델의 적합도 평가 및 잔차 분석에 활용. | scipy.stats.cramervonmises | 동률(Tie) 데이터 처리에 대한 주의 및 이산형 근사 필요 | |
| 분산지수 검정 (VMR) | 분산과 평균의 비율 (푸아송 특성) | 이산 데이터의 과대분산(Overdispersion) 또는 과소분산을 하나의 지표로 즉각 진단할 수 있음. | 분산과 평균의 관계(푸아송 특성)에만 초점을 맞추므로 범용적인 분포 비교에는 부적합함. | 카운트 데이터의 과대/과소 분산 여부 신속 파악. | 푸아송 회귀 모델을 적용할지, 음이항 회귀 모델로 우회할지 결정하는 사전 진단 도구로 필수적임. | 직접 수식 구현 (scipy.stats.chi2 활용) | 표본 분산 계산 시 비편향 추정량 자유도(ddof=1) 적용 |
import seaborn as sns
df = sns.load_dataset("titanic")
import numpy as np; import pandas as pd
import scipy.stats as stats
from scipy.stats import chisquare, power_divergence
# 예시 데이터: O (관측빈도), E (기대빈도)
O = df['class'].value_counts().values
E = [491, 200, 200] # 예시 기대빈도 (총합은 O와 같아야 함)
if '카이제곱':
chi_stat, chi_pval = stats.chisquare(f_obs=O, f_exp=E)
print(f"Chi-square Stat: {chi_stat:.4f}, p-value: {chi_pval:.4f}")
if 'G-검정 (우도비 검정)':
# 파라미터 lambda_='log-likelihood' 설정 필수
g_stat, g_pval = power_divergence(f_obs=O, f_exp=E, lambda_='log-likelihood')
print(f"G-test Stat: {g_stat:.4f}, p-value: {g_pval:.4f}")
if '이산형 K-S 검정':
from scipy.stats import ks_1samp, poisson
# 예시 원시 카운트 데이터 (빈도가 아닌 개별 관측치 배열)
data = np.array([2, 3, 3, 4, 2, 5, 3, 2, 1, 4, 3, 2, 0])
# 추정된 람다(평균)
lambda_est = np.mean(data)
# method='exact'를 사용하여 이산형 분포의 계단함수 형태를 반영
ks_stat, ks_pval = ks_1samp(data, poisson(mu=lambda_est).cdf, method='exact')
print(f"Discrete K-S Stat: {ks_stat:.4f}, p-value: {ks_pval:.4f}")
| 검정 방법 | 기반 원리 | 검정통계량 | 장점 (Pros) | 단점 (Cons) | 특징 및 실무 적용 | ADP / ML 활용 포인트 | 사용 라이브러리 및 함수 | 필수 전처리 및 파라미터 |
|---|---|---|---|---|---|---|---|---|
| 2표본 K-S 검정 | 경험적 누적분포함수(eCDF) 최대 차이 | 정규성 가정이 필요 없는 비모수 검정임. 분포의 위치, 형태 등 전반적 차이 포착에 유리함. | 분포의 양극단(Tail) 차이에 둔감함. 동률(Ties)이 많거나 이산형 데이터일 경우 검정력이 저하됨. | 두 독립 표본이 동일한 연속형 분포에서 추출되었는지 비교함. | Train 데이터와 Test/Serving 데이터 간의 데이터 표류(Data Drift) 및 공변량 시프트(Covariate Shift) 탐지에 핵심적으로 사용됨. | scipy.stats.ks_2samp | 연속형 변수 가정 필수. 결측치 제거 및 필요시 동률(Tie) 데이터 사전 처리. |
import statsmodels.api as sm
affairs = sm.datasets.fair.load_pandas(); df = affairs.data
# ===========================================================================================
#
# ===========================================================================================
import scipy.stats as stats
stats.shapiro(df['affairs']) # 샤피로-윌크 검정 수행
statistic, p_value = stats.ks_2samp(df['affairs'], df['affairs']) # 두 표본 간 검정 수행
단일 표본 분산 검정 (모분산 신뢰구간 검정)
| 검정 형태 | 귀무가설 () 문장 및 수식 | 대립가설 () 문장 및 수식 | 기각역 (Reject if) |
|---|---|---|---|
| 양측 검정 | 모집단 분산은 기준치와 같다. | 모집단 분산은 기준치와 다르다. | 또는 |
| 우측 단측 검정 | 모집단 분산은 기준치와 같다. | 모집단 분산은 기준치보다 크다 (산포 증가). | |
| 좌측 단측 검정 | 모집단 분산은 기준치와 같다. | 모집단 분산은 기준치보다 작다 (산포 감소). |
(여기서 n은 표본 크기, s2는 표본 분산, σ2는 귀무가설의 기준 분산이다.)
import numpy as np
from scipy import stats
# data = 특정 제조사의 금속 함유량 측정치 배열 (예: 1차원 numpy array)
n = len(data)
s_sq = np.var(data, ddof=1) # 표본 분산 (자유도 n-1)
sigma_0_sq = 1.3 # 불량 기준 분산
# 카이제곱 검정통계량 계산
chi2_stat = (n - 1) * s_sq / sigma_0_sq
# 단측 검정 (우측 꼬리 영역) p-value 계산
p_value = 1 - stats.chi2.cdf(chi2_stat, df=n-1)
print(f"Chi-square Statistic: {chi2_stat:.4f}, p-value: {p_value:.4f}")import numpy as np
import scipy.stats as stats
# 1. 예시 데이터 설정 및 기초 통계량 산출
# 모집단이 정규분포를 따른다고 가정
data = np.array([12.5, 13.1, 11.9, 14.2, 12.8, 13.5, 12.1, 13.8])
n = len(data)
# 표본 분산 산출 (불편추정량을 위해 ddof=1 필수)
s_sq = np.var(data, ddof=1)
df = n - 1 # 자유도
# 2. 신뢰수준 및 카이제곱 임계값 설정
confidence_level = 0.95
alpha = 1 - confidence_level
# 카이제곱 하측 임계값 (누적 확률 alpha/2)
chi2_lower = stats.chi2.ppf(alpha / 2, df)
# 카이제곱 상측 임계값 (누적 확률 1 - alpha/2)
chi2_upper = stats.chi2.ppf(1 - alpha / 2, df)
# 3. 모분산 신뢰구간 계산
# 주의: 상측 임계값(큰 값)으로 나누어야 하한값이 됨
ci_lower = (df * s_sq) / chi2_upper
# 주의: 하측 임계값(작은 값)으로 나누어야 상한값이 됨
ci_upper = (df * s_sq) / chi2_lower
print(f"표본 크기(n): {n}")
print(f"표본 분산(s^2): {s_sq:.4f}")
print("-" * 40)
print(f"카이제곱 하측 임계값: {chi2_lower:.4f}")
print(f"카이제곱 상측 임계값: {chi2_upper:.4f}")
print("-" * 40)
print(f"모분산의 {confidence_level*100:.0f}% 신뢰구간: [{ci_lower:.4f}, {ci_upper:.4f}]")
# (참고) 모표준편차(sigma)의 신뢰구간이 필요하다면 제곱근을 씌우면 된다.
# print(f"모표준편차 신뢰구간: [{np.sqrt(ci_lower):.4f}, {np.sqrt(ci_upper):.4f}]")
등분산 검정 (bartlett, levene, fligner)
여러 집단 간의 분산이 동일한지를 검정하는 통계적 방법
- 집단 간 분산의 동질성을 판단하는 데 사용
- 각 검정법은 가정하는 분포나 민감도에 따라 다름
세 가지 등분산 검정은 모두 “그룹 간의 분산이 동일한가?” ㅍ를 검정하지만, 데이터의 정규성과 이상치(Outlier)에 대한 민감도에 따라 선택 기준이 달라진다.
- 귀무가설 (H0): 모든 집단의 분산이 동일하다.
- 대립가설 (H1): 적어도 하나의 집단의 분산이 다르다.
| 검정 방법 | 데이터의 정규성 가정 | 이상치 민감도 | 통계적 기초 | 추천 상황 | Python 함수 |
|---|---|---|---|---|---|
| Bartlett | 매우 강함 | 높음 | 분포 기반 | 데이터가 엄격한 정규분포를 따를 때 | scipy.stats.bartlett |
| Levene | 낮음 | 보통 | 분포 기반 (med, mean 으로부터의 절대편차 이용) | 실무 일반 상황 (가장 보편적) | scipy.stats.levene |
| Fligner-Killeen | 없음 | 매우 낮음 | 데이터 실제값이 아닌, 비모수적 순위(Rank) 기반 | 이상치가 많거나 비정규성이 심할 때 | scipy.stats.fligner |
-
데이터의 정규성 가정
- 데이터가 정규분포를 따른다는 가정을 하는가?
-
민감도:
- Bartlett: 데이터가 정규성을 조금이라도 벗어나면 결과가 매우 부정확해지는 경향 (1종오류율 상승)
- Levene: 이상치(Outlier)에 덜 민감하며, 정규성을 따르지 않는 데이터에서도 준수한 성능을 보인다.
- FK: 정규성 가정이 전혀 필요 없으며, 이상치에 대해 극도로 강건(Robust)하다.
-
levene:
- 정규성 가정에서 자유롭다. 분산이 다를 때 중앙값(Median)이나 평균(Mean)으로부터의 절대 편차를 이용한다.
- 가장 기본적으로 추천되는 등분산 검정 (기본값인 center=‘median’ 사용 시 특히 강력함)
-
FK:
- 사용 시점: 데이터가 심하게 왜곡되어 있거나, 이상치가 많아 Levene 검정조차 신뢰하기 어려울 때 사용