데이터 분석

[Scipy] 등분산성 검정 본문

Python/Scipy

[Scipy] 등분산성 검정

딱한아이 2025. 2. 6. 18:00

1) 등분산성 검정

  • scipy의 stats에서 이를 위한 bartlett-killen, levene, fligner 등이 있음
  • 둘 이상의 정규성을 만족하는 데이터 집합에 대해 모분산이 같은 지 확인하기 위한 검정에는 bartlett 사용
  • 정규성을 만족하지 않는 경우 levene, fligner를 사용

 

2) 등분산성 검정의 가설

  • H0(귀무가설) : 등분산성을 만족한다
  • H1(대립가설) : 등분산성을 만족하지 못한다

'p-value > 유의수준', '검정통계량 < 임계값'인 경우에 귀무가설을 유의수준 하에서 기각하지 못한다. 즉, 등분산성을 만족한다고 할 수 있다.

 

 

3) 등분산성 검정의 종류

  • bartlett test : 정규성을 충족하며, 데이터셋의 크기가 서로 다른 2개 이상의 집단 간에도 사용 가능
    - 카이제곱 검정을 사용하여 그룹 간 분산 차이를 비교
    - 단, 정규성이 만족되지 않으면 검정 결과를 신뢰할 수 없음

  • levene test : 정규성을 충족하지 않는 비모수 데이터에 사용 가능
    - 각 값과 중앙값 간의 절대 편차를 사용해 분산 차이를 비교
    - 정규성을 충족하지 않는 데이터에 비교적 안정적인 결과 제공

  • fligner test : 정규성을 충족하지 않는 비모수 데이터에 사용 가능
    - 순위 기반의 검정을 수행하여 분산 차이를 비교
    - 정규성이 크게 위배되는 경우에도 가장 강건한 검정 방법

 

실습

1) iris 데이터 - 정규성을 만족하는 경우


✅정규성 검정

품종별 sepal_length 값을 그룹을 나누어, 각 그룹의 정규성 검정을 수행한다.

import pandas as pd
import seaborn as sns

# 데이터 로드
iris = sns.load_dataset('iris')

# 품종별 그룹을 나누어 sepal_length 값을 저장
target = 'sepal_length'
groups = [x.to_list() for name, x in iris.groupby('species')[target]]
gA, gB, gC = groups

from scipy.stats import bartlett, shapiro

# 정규성검정
_, pvalueA = shapiro(gA)
_, pvalueB = shapiro(gB)
_, pvalueC = shapiro(gC)

print(pvalueA, pvalueB, pvalueC) # 0.4595131499174534 0.4647370359250263 0.25831474614079086

 

세 그룹 모두 p값이 유의수준 0.05보다 크므로, 정규성을 만족한다. 따라서 등분산성 검정을 위해 bartlett 검정 방법을 사용한다.

 

✅등분산성 검정

# (1) bartlett 검정
statistic, pvalue = bartlett(gA, gB, gC)
print(f'검정통계량:{statistic:.4f}, p값:{pvalue:.4f}') # 검정통계량:16.0057, p값:0.0003

# (2) levene 검정
from scipy.stats import levene
statistic, pvalue = levene(*groups, center = 'mean')
print(f'검정통계량:{statistic:.4f}, p값:{pvalue:.4f}') # 검정통계량:7.3811, p값:0.0009

# (3) fligner 검정
from scipy.stats import fligner
statistic, pvalue = fligner(*groups, center = 'trimmed', proportiontocut = 0.05)
print(f'검정통계량:{statistic:.4f}, p값:{pvalue:.4f}') # 검정통계량:13.1934, p값:0.0014

 

우선 bartlett 검정 결과 p값이 유의수준 0.05보다 작아, 귀무가설을 기각한다. 따라서 각 그룹 간 분산에 통계적으로 유의한 차이가 있다고 볼 수 있다. 나머지 levene, fligner 검정 결과도 동일함을 확인했다.

 

 

2) tips 데이터 - 정규성을 만족하지 않는 경우

 

✅정규성 검정

요일별 total_bill 값을 그룹을 나누어, 각 그룹의 정규성 검정을 수행한다.

import seaborn as sns
import pandas as pd

# 데이터 로드
tips = sns.load_dataset('tips')

# 요일별 그룹을 나누어 total_bill 값을 저장
target = 'total_bill'
groups = [x.to_list() for name, x in tips.groupby('day')[target]]
gA, gB, gC, gD = groups

from scipy.stats import levene, shapiro

# 정규성 검정
_, pvalueA = shapiro(gA)
_, pvalueB = shapiro(gB)
_, pvalueC = shapiro(gC)
_, pvalueD = shapiro(gD)

print(f'{pvalueA:.5f}, {pvalueB:.5f}, {pvalueC:.5f}, {pvalueD:.5f}') # 0.00003, 0.04086, 0.00001, 0.00357

 

네 그룹 모두 p값이 유의수준 0.05보다 작으므로, 정규성을 만족하지 못한. 따라서 등분산성 검정을 위해 levene, fligner 검정 방법을 사용한다.

 

✅등분산성 검정

# (1) levene 검정
from scipy.stats import levene
statistic, pvalue = levene(*groups, center = 'median')
print(f'검정통계량:{statistic:.4f}, p값:{pvalue:.4f}') # 검정통계량:0.6654, p값:0.5741

# (2) fligner 검정
from scipy.stats import fligner
statistic, pvalue = fligner(*groups, center = 'trimmed', proportiontocut = 0.05)
print(f'검정통계량:{statistic:.4f}, p값:{pvalue:.4f}') # 검정통계량:4.5325, p값:0.2094

 

검정 결과, p값이 유의수준 0.05보다 크므로 각 그룹 간 분산에 통계적으로 유의한 차이가 없다. 즉, 등분산성을 만족한다.

'Python > Scipy' 카테고리의 다른 글

[Scipy] 정규성 검정  (1) 2025.01.13