Skip to Content

크루스칼-왈리스 검정 (Kruskal-Wallis Test)

아래는 **크루스칼-왈리스 검정(Kruskal-Wallis Test)**의 개념과 Python 예시를 정리한 내용입니다. 크루스칼-왈리스 검정은 세 개 이상의 독립된 집단 간 중앙값(또는 분포 위치)이 서로 다른지 비교하기 위한 비모수적 방법으로, **일원분산분석(ANOVA)**의 비모수적 대안이라고도 볼 수 있습니다.


1. 개념 정리

1.1 Kruskal-Wallis 검정이란?

  • Kruskal-Wallis 검정은 독립인 개의 집단( )에 대해, 해당 집단들의 중앙값이 모두 동일한지를 검정하는 비모수적 기법입니다. kk k≥3k \ge 3
  • 데이터를 **순위(rank)**로 바꾸어 일원분산분석과 유사한 아이디어로 분산 비교를 수행합니다.
  • 만약 정규성(각 집단이 정규분포를 이룬다) 혹은 등분산성(분산 동일) 가정이 불확실하거나 위배되는 경우에, 일원분산분석(ANOVA) 대신 Kruskal-Wallis 검정을 적용할 수 있습니다.

1.2 가설 설정

  • 귀무가설(H₀): 개의 집단(모집단)의 분포가 동일하며, 중앙값이 모두 같다. kk
  • 대립가설(H₁): 적어도 한 집단의 중앙값이 다르다(분포가 다르다).

Kruskal-Wallis 검정도 순위 기반 비모수 기법이므로, 주로 “중앙값 차이가 있는지”를 본다고 해석합니다.

1.3 적용 조건

  1. 각 집단은 독립적이어야 함(한 개체는 오직 한 집단에만 속함).
  2. 측정값이 서열척도(ordinal scale) 이상이어야 함(순서를 매길 수 있어야 함).
  3. 집단 간에 분포 형태가 완전히 달라지지 않는다는 전제가 어느 정도 필요(순위를 통한 비교이므로, 분포 모양이 극단적으로 다른 경우 해석 주의).
  4. 정규성이나 등분산성 가정은 필요 없음(비모수).

2. 검정 과정(개념)

  1. kk개 집단의 모든 데이터를 통합하고, 값의 크기순으로 정렬한 뒤 각각에 순위(rank)를 매긴다. (동점이면 평균 순위)
  2. 각 집단에 속한 데이터가 차지하는 순위의 합()을 계산한다. RiR_i
  3. Kruskal-Wallis 통계량(H) 공식에 따라 H 값을 계산하고, 이를 통해 p-value를 구한다. H=12N(N+1)∑i=1kRi2ni  −  3(N+1)H = \frac{12}{N(N+1)} \sum_{i=1}^{k} \frac{R_i^2}{n_i} ;-; 3(N+1)
  • NN: 전체 표본 크기() N=n1+n2+⋯+nkN = n_1 + n_2 + \dots + n_k
  • nin_i: 각 집단의 표본 크기
  • RiR_i: 집단 의 순위합 ii
  1. 검정 결과 p-value < → 귀무가설 기각(즉, 집단 중 적어도 하나는 중앙값이 다르다). α\alpha

3. Python 실습 예시

Python에서 Kruskal-Wallis 검정은 scipy.statskruskal 함수를 사용하면 됩니다.

3.1 라이브러리 임포트

import numpy as np import pandas as pd from scipy.stats import kruskal

3.2 예시 데이터 생성

  • 예) 세 가지 교육 방법(집단 3개: method_A, method_B, method_C)에 따른 시험 점수가 정규분포가 아니라 가정 → 비모수 검정 적용
  • 각 집단 표본 크기는 15명씩
np.random.seed(42) # method_A: 평균 70, 사분위 범위가 넓다고 가정(치우친 분포?) method_A = np.random.gamma(shape=5, scale=2, size=15) + 60 # method_B method_B = np.random.gamma(shape=5, scale=2, size=15) + 65 # method_C method_C = np.random.gamma(shape=5, scale=2, size=15) + 70 # 데이터프레임 구성 df_edu = pd.DataFrame({ 'score': np.concatenate([method_A, method_B, method_C]), 'group': ['A']*15 + ['B']*15 + ['C']*15 }) print(df_edu.head())

여기서는 감마분포(치우친 분포)로 데이터를 생성했으므로, 정규성 가정이 깨질 수 있다는 설정으로 Kruskal-Wallis를 사용한다 가정합니다.

3.3 Kruskal-Wallis 검정 수행

stat, p_value = kruskal(method_A, method_B, method_C) print("[Kruskal-Wallis Test]") print(f"H-statistic = {stat:.4f}, p-value = {p_value:.4f}") alpha = 0.05 if p_value < alpha: print("=> 귀무가설 기각: 세 그룹 중 적어도 한 그룹의 중앙값이 다름.") else: print("=> 귀무가설 채택(기각 실패): 중앙값 차이가 유의하지 않음.")
  • 여기서 결과의 stat(H 값)은 Kruskal-Wallis 통계량, **p_value*는 그에 대한 유의확률

3.4 사후검정 (Post-hoc test)

Kruskal-Wallis 결과가 유의하다면(귀무가설 기각), 어느 그룹들이 차이가 나는지 추가 비교가 필요합니다.

  • 비모수적 사후검정으로 Dunn’s test 또는 Conover’s test 등을 사용
  • Python에서는 scikit-posthocs 라이브러리의 posthocs.posthoc_conover 또는 posthocs.posthoc_dunn 등을 활용할 수 있습니다. (별도 설치 필요: pip install scikit-posthocs)

예시: Conover’s test

!pip install scikit-posthocs import scikit_posthocs as sp data = [method_A, method_B, method_C] # list of arrays # 한꺼번에 묶어서 posthoc posthoc_res = sp.posthoc_conover(data, p_adjust='bonferroni') print(posthoc_res)

p_adjust=‘bonferroni’는 다중비교 보정을 위한 옵션 중 하나.결과 테이블에서 각 집단 쌍(A-B, B-C, A-C)에 대한 p-value가 제공됨. p-value < 0.05면 해당 두 그룹 간 유의한 차이 있다고 해석.


4. 결과 해석 및 주의사항

  1. p-value < 0.05 (Kruskal-Wallis)
  • 적어도 한 집단의 중앙값이 다른 집단과 유의한 차이가 있다.
  • 자세히 어떤 그룹끼리 다른지 보려면 사후검정(Post-hoc) 필수.
  1. p-value >= 0.05
  • “집단 간 중앙값 차이가 통계적으로 유의하지 않음.”
  1. 비모수적이므로, 정규성 가정을 하지 않아도 됨.
  • 다만, 각 집단의 분포 형태가 심하게 달라지면(예: 한쪽은 극단적 비대칭, 다른 한쪽은 양극단 분포 등) 단순 “중앙값” 비교로 해석하기 어려울 수 있음.
  1. 독립성
  • Kruskal-Wallis 역시 집단 간 표본이 독립이어야 한다.
  1. 사후검정
  • ANOVA와 마찬가지로, 전체 검정(H₀ 기각) 후에는 구체적으로 어떤 집단 사이가 다른지 확인해야 의미가 있다.

5. 요약

  • Kruskal-Wallis 검정은 개의 독립 집단( )에 대한 중앙값 비교를 하는 비모수적 방법. kk k≥3k \ge 3
  • *일원분산분석(ANOVA)**의 비모수 버전으로 볼 수 있으며, 정규성·등분산성 가정이 불확실할 때 유용.
  • Python에서 scipy.stats.kruskal 함수를 사용해 쉽게 수행 가능. 결과 해석 시 유의하면, p-value < 0.05일 때 사후검정을 통해 구체적으로 어떤 그룹 간 차이가 존재하는지 파악하는 것이 중요.

참고문헌

  1. Kruskal, W. H., & Wallis, W. A. (1952). Use of ranks in one-criterion variance analysis. Journal of the American Statistical Association, 47(260), 583–621.
  2. Hollander, M., Wolfe, D. A., & Chicken, E. (2013). Nonparametric Statistical Methods (3rd ed.). Wiley.
  3. Conover, W. J. (1999). Practical Nonparametric Statistics (3rd ed.). Wiley.
  4. scipy.stats.kruskal 문서  이상으로 Kruskal-Wallis 검정에 대한 개념과 실습 예시를 살펴보았습니다. 세 개 이상의 독립집단에서 정규성 가정이 어렵거나, 표본 크기가 작아 비모수적 접근이 필요할 때 유용하게 활용할 수 있는 대표적 기법입니다.

  • 요약

Kruskal-Wallis Test 교안

1. 개요

Kruskal-Wallis test는 세 개 이상의 독립적인 집단 간 차이를 검정하는 비모수적 방법으로, 일원배치 분산분석(One-way ANOVA)의 비모수적 대안입니다.

1.1 특징

  • 정규성 가정이 필요하지 않음
  • 순위에 기반한 검정
  • 세 개 이상의 독립 집단 비교
  • 연속형 또는 순서형 종속변수

1.2 기본 가정

  • 독립성
  • 동일한 분포 형태
  • 순서형 이상의 측정 수준

2. 통계적 가설

2.1 귀무가설(H₀)

모든 집단의 분포가 동일하다

2.2 대립가설(H₁)

적어도 한 집단의 분포가 다르다

3. 검정 통계량

3.1 H 통계량

H=12N(N+1)i=1kRi2ni3(N+1)H = \frac{12}{N(N+1)}\sum_{i=1}^k\frac{R_i^2}{n_i} - 3(N+1) 여기서:

  • N: 전체 표본 크기
  • k: 집단 수
  • n_i: i번째 집단의 표본 크기
  • R_i: i번째 집단의 순위합

3.2 동률 보정

Hcorrected=H1(ti3ti)N3NH_{corrected} = \frac{H}{1-\frac{\sum(t_i^3-t_i)}{N^3-N}} 여기서:

  • t_i: 각 동률 그룹의 관측값 수

4. 실습

4.1 Python 구현

import numpy as np from scipy import stats # 예시 데이터 group1 = [2.9, 3.0, 2.5, 2.6, 3.2] group2 = [3.8, 3.7, 3.9, 3.6, 3.5] group3 = [2.8, 3.4, 3.7, 2.9, 3.1] # Kruskal-Wallis 검정 statistic, pvalue = stats.kruskal(group1, group2, group3) print(f'H-statistic: {statistic:.4f}') print(f'p-value: {pvalue:.4f}')

4.2 R 구현

# 데이터 준비 data <- data.frame( value = c(2.9, 3.0, 2.5, 2.6, 3.2, 3.8, 3.7, 3.9, 3.6, 3.5, 2.8, 3.4, 3.7, 2.9, 3.1), group = factor(rep(c("A","B","C"), each=5)) ) # Kruskal-Wallis 검정 kruskal.test(value ~ group, data=data)

5. 사후 검정

5.1 Dunn’s Test

from scikit_posthocs import posthoc_dunn # 데이터 준비 data = [group1, group2, group3] posthoc_dunn(data, p_adjust='bonferroni')

5.2 Mann-Whitney U with Bonferroni Correction

def pairwise_mannwhitney(groups, labels): n_groups = len(groups) results = [] for i in range(n_groups): for j in range(i+1, n_groups): stat, p = stats.mannwhitneyu(groups[i], groups[j]) results.append({ 'comparison': f'{labels[i]} vs {labels[j]}', 'statistic': stat, 'p_value': p * (n_groups * (n_groups-1)/2) # Bonferroni }) return results

6. 효과 크기

6.1 η² (Eta-squared)

η2=Hn1η² = \frac{H}{n-1}

6.2 ε² (Epsilon-squared)

ε2=Hk+1nkε² = \frac{H-k+1}{n-k}

def kw_effect_size(h_stat, n, k): eta_squared = h_stat / (n - 1) epsilon_squared = (h_stat - k + 1) / (n - k) return eta_squared, epsilon_squared

7. 실무 적용

7.1 분석 전 확인사항

  1. 독립성 검증
  2. 이상치 확인
  3. 분포 형태 유사성 검토

7.2 결과 보고

def report_kw_test(groups, labels): # 기술통계량 desc_stats = {label: { 'n': len(group), 'median': np.median(group), 'iqr': stats.iqr(group) } for label, group in zip(labels, groups)} # Kruskal-Wallis 검정 h_stat, p_val = stats.kruskal(*groups) # 효과 크기 n = sum(len(g) for g in groups) k = len(groups) eta_sq, eps_sq = kw_effect_size(h_stat, n, k) return { 'descriptive': desc_stats, 'test_results': { 'h_statistic': h_stat, 'p_value': p_val, 'effect_size': { 'eta_squared': eta_sq, 'epsilon_squared': eps_sq } } }

8. 연습문제

8.1 기초 문제

세 가지 교수법의 효과를 비교하려 합니다. 다음 데이터에 대해 Kruskal-Wallis 검정을 수행하세요.

method_A = [75, 68, 82, 69, 71] method_B = [85, 82, 88, 79, 83] method_C = [79, 73, 77, 81, 76]

8.2 심화 문제

  1. 위 데이터에 대한 사후 검정 수행
  2. 효과 크기 계산 및 해석
  3. 시각화를 통한 결과 표현

9. 해석 가이드

9.1 p-value 해석

  • p < α: 집단 간 차이 존재
  • p ≥ α: 유의한 차이 없음

9.2 효과 크기 해석

  • η² < 0.04: 작은 효과
  • 0.04 ≤ η² < 0.11: 중간 효과
  • η² ≥ 0.11: 큰 효과

참고문헌

  1. Kruskal, W. H., & Wallis, W. A. (1952). Use of ranks in one-criterion variance analysis. Journal of the American Statistical Association, 47(260), 583-621.
  2. Dunn, O. J. (1964). Multiple comparisons using rank sums. Technometrics, 6(3), 241-252.