Box's M Test

이정훈·2026년 2월 22일

Box's M Test

  • 여러 그룹 간의 공분산 행렬이 서로 동일한지(등공분산성)를 확인하는 다변량 통계 검정 방법
  • 하나의 변수에 대해 분산이 같은지 확인하는 '등분산 검정(Levene's Test 등)'을 변수가 여러 개인 다변량(Multivariate) 상황으로 확장한 버전
    -여러 개의 종속 변수를 동시에 분석하는 기법(LDA, MANOVA..)을 사용하기전에 "각 그룹의 공분산 행렬이 동일하다"라는 전제 조건을 만족시키기 위해 사용
  • 각 그룹별 공분산 행렬의 행렬식(Determinant)과, 전체 데이터를 통합하여 계산한 합동 공분산 행렬(Pooled Covariance Matrix)의 행렬식을 비교하여 계산
    • 행렬식은 다변량 공간에서 데이터가 퍼져있는 '부피(Volume)'를 의미

1. 가설 정의

H0H_0: 모든 그룹의 모집단 공분산 행렬은 동일하다. (Σ1=Σ2==Σk\Sigma_1 = \Sigma_2 = \dots = \Sigma_k)
H1H_1: 적어도 하나의 그룹의 모집단 공분산 행렬은 다르다.

2. 행렬식 비교

2.1 합동 공분산 행렬 계산

Sp=1Vi=1kviSiS_p = \frac{1}{V} \sum_{i=1}^k v_i S_i

2.2 Box-M 통계량 (MM) 계산

M=VlnSpi=1kvilnSiM = V \ln |S_p| - \sum_{i=1}^k v_i \ln |S_i|

2.3 카이제곱 근사를 위한 보정 계수 (CC) 계산

MM 통계량을 확률 분포(카이제곱 분포)를 이용해 검정하기 위해, 편향을 줄여주는 보정 계수 CC를 계산

C=2p2+3p16(p+1)(k1)(i=1k1vi1V)C = \frac{2p^2 + 3p - 1}{6(p+1)(k-1)} \left( \sum_{i=1}^k \frac{1}{v_i} - \frac{1}{V} \right)

2.4 최종 검정 통계량(χ2\chi^2) 및 자유도(dfdf) 계산

χ2M(1C)\chi^2 \approx M(1 - C)
df=p(p+1)(k1)2df = \frac{p(p+1)(k-1)}{2}

코드 예제

# 1. 붓꽃(Iris) 데이터 불러오기
iris = sns.load_dataset('iris')
dependent_cols = ['sepal_length', 'sepal_width', 'petal_length', 'petal_width']
group_col = 'species'

groups = iris[group_col].unique()
k = len(groups)                # 그룹의 개수 (3개)
p = len(dependent_cols)        # 변수의 개수 (4개)
N = len(iris)                  # 전체 데이터 개수 (150개)

for group in groups:
# 해당 그룹의 데이터만 추출
    sub_data = iris[iris[group_col] == group][dependent_cols]
    
    n_i = len(sub_data)
    v_i = n_i - 1              # 각 그룹의 자유도
    v_list.append(v_i)
    
    # 표본 공분산 행렬 계산 (S_i)
    S_i = sub_data.cov().values 
    S_list.append(S_i)
    
    # 공분산 행렬의 로그 행렬식 계산 (오버플로우 방지를 위해 slogdet 사용)
    _, log_det = np.linalg.slogdet(S_i)
    log_det_list.append(log_det)
    
V = sum(v_list)  # 전체 자유도 (N - k)

# --- 2단계: 합동 공분산 행렬(S_p) 계산 ---
S_p = np.zeros((p, p))
for i in range(k):
    S_p += (v_list[i] / V) * S_list[i]

# 합동 공분산 행렬의 로그 행렬식 계산
_, log_det_Sp = np.linalg.slogdet(S_p)

# --- 3단계: Box-M 통계량 (M) 계산 ---
sum_v_log_det = sum([v_list[i] * log_det_list[i] for i in range(k)])
M = V * log_det_Sp - sum_v_log_det

# --- 4단계: 카이제곱 근사를 위한 보정 계수 (C) 계산 ---
sum_inv_v = sum([1 / v for v in v_list])
term1 = (2 * p**2 + 3 * p - 1) / (6 * (p + 1) * (k - 1))
term2 = sum_inv_v - (1 / V)
C = term1 * term2

# --- 5단계: 최종 검정 통계량(Chi-square) 및 자유도(df) 계산 ---
chi2_stat = M * (1 - C)
df = p * (p + 1) * (k - 1) / 2

# --- 6단계: 유의확률 (p-value) 도출 ---
p_value = 1 - chi2.cdf(chi2_stat, df)

# 결과 출력
print("=== 수제 Box-M 검정 결과 (Iris 데이터) ===")
print(f"M 통계량: {M:.4f}")
print(f"카이제곱 통계량 (Chi2): {chi2_stat:.4f}")
print(f"자유도 (df): {df}")
print(f"p-value: {p_value:.6f}")
profile
AngDDo

0개의 댓글