본문 바로가기
개발/Python

그룹 별 변수들의 차이 비교 (일원분산분석 vs Kruskal-Wallis 검정)

by 피로물든딸기 2025. 8. 10.
반응형

전체 링크

일원분산분석(One-Way ANOVA) vs Kruskal–Wallis 검정

- 세 개 이상의 독립 집단 간 차이가 있는지 검정

- 귀무가설 : 모든 집단의 평균(또는 중앙값)이 같다.

- 대립가설 : 적어도 한 집단은 평균(또는 중앙값)이 다르다.

  일원분산분석 Kruskal–Wallis 검정
데이터 조건 연속형 데이터
정규성등분산성 가정 필요
순위 기반(비모수)
정규성·등분산성 가정 불필요
검정 대상 평균의 차이 중앙값의 차이(또는 분포 위치 차이)
계산 방식 그룹 간 분산 / 그룹 내 분산 비율
(F-통계량)
전체 데이터를 순위로 변환 후 집단 간 순위합 비교
(H-통계량)
통계량 분포 F 분포 근사적으로 χ² 분포
민감도 이상치에 민감 이상치에 덜 민감

다음 데이터는 변수 X 그룹Y 그룹으로 이루어져 있다.

 

각 그룹에 대해 유의수준 5% 수준에서 Shapiro-Wilk 정규성 검정을 변수별로 각각 수행하고,

데이터의 정규성을 판단하라.

 

그룹 내 모든 변수가 모두 정규분포를 따른다면 일원분산분석을 수행하라. (유의수준 5%)

적어도 한 변수라도 정규분포를 따르지 않으면 Kruskal-Walis 검정을 수행하라. (유의수준 5%)

import pandas as pd
import numpy as np

np.random.seed(1234)

# DataFrame 예제 생성 (변수 6개, 관측치 50개)
df = pd.DataFrame({
    'X0': np.random.normal(loc=5, scale=2, size=50),      # 정규분포
    'X1': np.random.normal(loc=5, scale=2, size=50),      # 정규분포
    'X2': np.random.normal(loc=5, scale=2, size=50),      # 정규분포
    'Y0': np.random.normal(loc=0, scale=1, size=50),      # 정규분포
    'Y1': np.random.uniform(low=-2, high=2, size=50),     # 균등분포
    'Y2': np.random.exponential(scale=1, size=50),        # 지수분포
})

df.head()


먼저 그룹별, 그리고 각 그룹 내 변수별로 shapiro 정규성 검정을 시행한다.

정규성 검정의 귀무가설은 "해당 변수가 정규분포를 따른다."이다.

from scipy.stats import shapiro

groupX = ['X0', 'X1', 'X2']
groupY = ['Y0', 'Y1', 'Y2']

for cols in [groupX, groupY]:
    check = False
    for col in cols:
        stat, pval = shapiro(df[col]) # 귀무가설 : 정규분포를 따른다.        
        print(col, pval, stat)        
        if pval < 0.05 : check = True # 정규분포를 따르지 않는 경우
    
    print(check, cols)
    print()

 

그룹 XcheckFalse이므로, 귀무가설을 기각하지 못한다. 따라서 정규분포를 따르고, 일원분산분석을 시행한다.

그룹 Y는 적어도 하나의 변수가 정규분포를 따르지 않으므로 Kruskal-Walis 검정을 수행한다.

 

일원분산분석은 f_oneway를 이용해서 다음과 같이 검정하면 된다.

from scipy.stats import f_oneway

stat, pval = f_oneway(df['X0'], df['X1'], df['X2'])

 

만약 그룹 X의 변수가 매우 많다면 f_oneway에 변수를 넣기 까다로울 수 있다.

다음과 같이 각 변수를 리스트로 만들고, 언패킹 연산자(*)를 활용하면 간단하게 처리할 수 있다.

from scipy.stats import f_oneway

value = []
for col in groupX:
    value.append(df[col])

stat, pval = f_oneway(*value)
print(stat, pval)
if pval < 0.05 : print("귀무가설 기각, 변수들의 평균은 동일하지 않다.")
else : print("귀무가설 채택, 변수들의 평균은 동일하다.")

 

그룹 Y에 대한 Kruskal-Walis 검정은 kruskal을 이용하여 다음과 같이 처리할 수 있다.

from scipy.stats import kruskal

value = []
for col in groupY:
    value.append(df[col])

stat, pval = kruskal(*value)
print(stat, pval)
if pval < 0.05 : print("귀무가설 기각, 변수들의 중앙값은 동일하지 않다.")
else : print("귀무가설 채택, 변수들의 중앙값은 동일하다.")

반응형

댓글