정규성/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_divergencelambda_='log-likelihood' 파라미터 지정 필수
이산형 K-S 검정누적분포함수(CDF) 최대 차이범주 병합이 필요 없어 원본 데이터의 정보 손실이 발생하지 않음.누적의 개념이 필요하므로 명목형 변수에는 쓸 수 없음(순서성 필수). 내부 계산 비용이 높음.병합에 따른 정보 손실 방지. 순서성 있는 이산 데이터에 적합.순위(Rank) 데이터나 순서형(Ordinal) 카운트 데이터의 전체적인 분포 적합도 검정에 강력함.scipy.stats.ks_1sampmethod='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 검정조차 신뢰하기 어려울 때 사용