콘텐츠로 이동

일원배치 분산분석: 모형과 가정

1. 일원배치 분산분석

A. 일원배치 분산분석이란

일원배치 분산분석(One-Way ANOVA)은 셋 이상의 독립 집단의 평균 사이에 유의한 차이가 있는지 판정하는 통계 기법이다. 두 집단만 비교할 수 있는 이표본 t-검정과 달리, 일원배치 분산분석은 여러 집단을 동시에 평가하는 방법을 제공하여, 쌍별 비교를 여러 번 수행할 때 참인 귀무가설을 잘못 기각하는 제1종 오류의 가능성을 줄여 준다.

일원배치 분산분석의 핵심 개념은 자료에서 관측된 전체 변동을 두 성분으로 분해하는 것이다: 집단 간 변동과 각 집단 내 변동. 이 두 변동 원천을 비교하여, 관측된 집단 평균의 차이가 우연으로 기대되는 정도보다 큰지를 판정한다.

구체적으로 일원배치 분산분석은 집단 간 분산과 집단 내 분산의 비로 계산되는 F-통계량을 쓴다. F-통계량이 1보다 유의하게 크면 집단 평균의 차이가 무작위 변동만으로 생길 수 있는 정도보다 크다는 뜻이며, 적어도 한 집단의 평균이 다른 집단과 유의하게 다름을 시사한다.

"집단 평균이 다르다"는 말이 그 자체로는 아무 정보도 주지 않는다는 점이 이 절의 핵심이다. 아래 두 그림은 집단 평균이 정확히 같다. 세 집단의 평균이 양쪽 모두 \(10,\ 12,\ 14\)이고 크기도 모두 \(n = 20\)이다. 달라진 것은 집단 안의 흩어짐 하나뿐이다.

같은 평균 차이도 집단 내 흩어짐에 따라 신호가 되기도 잡음이 되기도 한다

집단 간 제곱합 \(\text{SS}_B\)는 집단 평균과 표본크기만으로 정해지므로 양쪽 모두 \(160.0\)으로 완전히 같다. 왼쪽은 \(\sigma = 1.2\)여서 집단 내 제곱합이 \(\text{SS}_W = 82.1\)밖에 되지 않고, 그 결과 \(F = 55.56\)으로 \(p < 10^{-4}\)이다. 오른쪽은 \(\sigma = 6.0\)이어서 \(\text{SS}_W = 2052.0\)까지 부풀고 \(F = 2.22\), \(p = 0.1177\)이 되어 기각하지 못한다. 평균 차이는 한 치도 변하지 않았는데 결론이 뒤집혔다.

\(F\)가 비(ratio)인 이유가 여기 있다. 분자 \(\text{MS}_B = \text{SS}_B/(k-1)\)만 보면 두 그림이 같은 값 \(80.0\)을 주지만, 그 값이 큰지 작은지 판단할 잣대가 없다. 잣대는 같은 자료가 스스로 제공한다. 집단 안에서 관측값들이 이미 얼마나 흔들리는지를 \(\text{MS}_W\)로 재고, 집단 평균의 흩어짐이 그 흔들림보다 얼마나 더 큰지를 묻는 것이다. 왼쪽에서는 \(80.0 / 1.44 = 55.6\)배, 오른쪽에서는 \(80.0 / 36.0 = 2.2\)배다.

오른쪽 그림에서 두 번째·세 번째 집단의 점들이 첫 번째 집단의 점들과 거의 완전히 겹쳐 보인다는 사실에도 주목하라. 눈으로도 세 집단을 구별할 수 없다. \(F\) 검정은 이 시각적 판단을 수치로 옮긴 것이며, 그래서 "평균이 실제로 다른데도 기각하지 못하는" 오른쪽 같은 상황이 잘못이 아니라 자료가 가진 정보의 한계를 정직하게 보고한 결과다.

일원배치 분산분석의 가정 중 하나는 각 집단의 자료가 정규분포를 따르고 집단 사이의 분산이 대략 같다는 것(분산의 동질성)이다. 또한 관측값들이 서로 독립이어야 한다. 이 가정들이 어긋나면 부정확한 결론에 이를 수 있으므로 다른 접근이나 조정(예: Welch 분산분석이나 비모수 검정)이 필요할 수 있다.

전체적으로 일원배치 분산분석은 의학, 심리학, 농학, 경영학처럼 서로 다른 처치·조건·집단의 효과를 비교하려는 여러 분야에서 특히 유용하다. 다중 가설검정에 따르는 오류 위험을 통제하면서 여러 집단 사이의 차이를 간결하고 효율적으로 평가하게 해 준다.

일원배치 분산분석의 결과가 유의하면 어느 집단이 서로 다른지 짚어내기 위해 보통 추가 분석이 필요하다. 이 후속 과정은 흔히 사후검정(예: Tukey의 HSD, Bonferroni 보정)으로 이루어지며, 제1종 오류를 통제하면서 어느 집단 평균 쌍이 유의하게 다른지 판정하도록 돕는다.

B. 두 집단을 비교할 때 일원배치 분산분석과 t-검정

두 집단을 비교할 때 일원배치 분산분석과 t-검정은 공통점이 있지만 가정과 용도에서 중요한 차이도 있다.

공통점

  1. 목적: 둘 다 집단 평균을 비교하여 통계적으로 유의한 차이가 있는지 판정하는 데 쓰인다. 관측된 차이가 우연히 생겼을 가능성을 검정하도록 설계되었다.

  2. 귀무가설: 두 검정 모두 집단 평균 사이에 차이가 없다는 귀무가설을 평가한다. 다시 말해 두 집단에 대해 반증되기 전까지 평균이 같다고 가정한다.

  3. 해석: 둘 다 p-값을 제공하며 이를 통해 귀무가설을 기각할지 결정한다. p-값이 지정한 유의수준(예: 0.05)보다 작으면 귀무가설을 기각하고 평균 사이에 유의한 차이가 있다고 결론짓는다.

  4. 두 집단에서의 동치성: 분산이 같은 두 집단만 비교하는 경우 일원배치 분산분석과 스튜던트의 t-검정은 동치인 결과를 준다. 일원배치 분산분석의 F-통계량은 t-검정 t-통계량의 제곱과 같아서, 두 검정이 같은 p-값을 주고 같은 결론에 이른다.

주요 차이

  1. 분산에 대한 가정: t-검정에는 두 형태가 있다. 스튜던트의 t-검정과 Welch의 t-검정이다. 스튜던트의 t-검정은 두 집단의 분산이 같다고(분산의 동질성) 가정한다. 반면 Welch의 t-검정은 등분산을 가정하지 않아 집단 분산이 다를 때 더 적합하다. 일원배치 분산분석은 집단 사이의 등분산을 가정한다. 등분산성이라 부르는 이 가정은 검정의 신뢰성에 결정적이다. 가정이 어긋나면 표준 일원배치 분산분석이 적절하지 않을 수 있고 Welch 분산분석 같은 형태를 대신 써야 한다.

  2. 쓰임새: t-검정은 두 집단의 평균을 비교하도록 특별히 설계되었다. 비교할 집단이 둘뿐이면 더 간단하고 효율적이다. 일원배치 분산분석은 보통 셋 이상의 집단 평균을 비교하는 데 쓰지만 두 집단에도 쓸 수 있다. 집단이 둘뿐이면 대개 t-검정이 더 간명하며, 분산이 같다면 일원배치 분산분석도 같은 결과를 준다.

  3. 통계적 출력: t-검정은 t-통계량과 p-값을 준다. t-통계량은 집단 내 변동에 대비한 집단 평균의 차이를 나타낸다. 일원배치 분산분석은 F-통계량과 p-값을 준다. F-통계량은 집단 간 분산과 집단 내 분산의 비를 나타낸다. 두 집단에서는 F-통계량이 단순히 t-통계량의 제곱이다.

  4. 유연성과 확장성: t-검정은 두 집단 비교에 한정된다. 집단이 셋 이상이면 t-검정을 여러 번 수행할 때 제1종 오류(거짓 양성)의 위험이 커진다. 일원배치 분산분석은 둘 이상의 집단을 한 번에 비교할 수 있어 더 유연하다. 제1종 오류율을 통제하도록 설계되어 여러 집단을 비교할 때 더 적절하다.

각각을 언제 쓰는지에 대한 예

  • t-검정: 서로 다른 두 학습법을 쓴 학생들의 평균 점수를 비교한다고 하자. 두 집단(예: 방법 A 대 방법 B)의 분산이 비슷하면 스튜던트의 t-검정이 적절하다. 분산이 다르면 Welch의 t-검정을 써야 한다.

  • 일원배치 분산분석: 서로 다른 세 학습법(방법 A, B, C)을 쓴 학생들의 평균 점수를 비교한다고 하자. 이 경우 일원배치 분산분석이 적절한 선택이다. 집단이 둘뿐이어도 일원배치 분산분석을 쓸 수 있지만 대개는 t-검정이 더 간단하다.

요약

일원배치 분산분석과 t-검정은 집단 평균을 비교하여 유의한 차이가 있는지 판정한다는 공통 목표를 갖는다. 둘 다 평균이 같다는 귀무가설을 검정하고 해석을 위한 p-값을 준다. 그러나 분산에 대한 가정과 의도된 쓰임새가 다르다.

  • 분산이 같은 두 집단을 비교할 때에는 간단하고 효율적인 t-검정(스튜던트의 t-검정)이 흔히 더 나은 선택이다.
  • 분산이 다를 때 두 집단을 비교하려면 Welch의 t-검정이 선호된다.
  • 집단이 셋 이상일 때에는 여러 번의 t-검정보다 제1종 오류율을 잘 통제하는 일원배치 분산분석이 더 적절하다.

이렇게 특정 조건에서는 두 집단에 대해 일원배치 분산분석과 t-검정이 동치인 결과를 주지만, 분산 가정과 유연성의 차이 때문에 각 검정이 적합한 상황이 다르다.

C. 일원배치 분산분석의 귀무가설과 선형회귀의 비교

\[\begin{array}{cccccccc} &&\text{선형회귀}&&\text{일원배치 분산분석}\\ \text{모형}&&y=\alpha+\beta x+\text{noise} && y=\alpha+\sum_{i=1}^{k}\beta_i 1_{x\in C_i}+\text{noise} \\ \text{H}_0&&\beta=0 && \quad\beta_1=\cdots=\beta_k=0\\ \end{array}\]

일원배치 분산분석은 독립변수가 서로 다른 집단을 나타내는 범주형인 선형회귀 모형의 특수한 형태로 볼 수 있다. 전형적인 선형회귀에서는 설명변수 \(x\)가 연속형이고 종속변수 \(y\)와 \(x\)의 관계가 다음으로 표현된다:

\[y = \alpha + \beta x + \text{noise}\]

여기서 \(\alpha\)는 절편, \(\beta\)는 기울기, "noise"는 무작위 오차이다. 이 모형의 귀무가설 \(H_0\)은 \(\beta = 0\), 즉 \(x\)가 \(y\)에 영향을 주지 않는다는 것이다.

\[H_0: \beta = 0\]

반면 일원배치 분산분석은 여러 집단의 평균을 비교하여 관계를 모형화한다. 범주형 변수가 집단 \(C_1, C_2, \dots, C_k\)를 정의하고 모형은 다음과 같이 쓰인다:

\[y = \alpha + \sum_{i=1}^{k} \beta_i 1_{x \in C_i} + \text{noise}\]

여기서 \(1_{x \in C_i}\)는 \(x\)가 집단 \(C_i\)에 속하면 1, 아니면 0인 지시함수이다. \(\alpha\)는 전체 평균이고 각 \(\beta_i\)는 집단 \(C_i\)가 전체 평균에서 벗어난 정도를 나타낸다.

일원배치 분산분석의 귀무가설은 모든 집단의 평균이 같다는 것이며 다음으로 표현된다:

\[H_0: \beta_1 = \beta_2 = \cdots = \beta_k = 0\]

집단 평균들 사이에 유의한 차이가 없다는 뜻이다. 이 가설을 기각하면 적어도 한 집단의 평균이 다른 집단과 유의하게 다름을 시사한다.

2. 일원배치 분산분석의 가정

언제 일원배치 분산분석을 쓰는가

  • 독립변수: 일원배치 분산분석은 수준(집단)이 셋 이상인 독립변수(요인이라고도 한다)가 하나 있을 때 쓴다. 예를 들어 세 가지 식이요법이 체중 감량에 미치는 효과를 비교한다면 식이요법이 집단이 된다.

  • 종속변수: 종속변수(측정하는 것)는 연속형이어야 한다. 키, 몸무게, 시험 점수처럼 어떤 범위 안의 값을 가질 수 있다는 뜻이다.

일원배치 분산분석의 가정

일원배치 분산분석을 수행하기 전에 다음 가정들이 충족되어야 한다:

  • 관측의 독립성: 각 표본이 다른 표본과 독립이다. 자료는 무작위 과정을 통해 수집되어 각 집단의 관측값이 서로 독립임이 보장되어야 한다.

  • 정규성: 종속변수가 각 집단 안에서 근사적으로 정규분포를 따라야 한다. 표본이 작을 때 특히 중요하며 Q-Q 그림 같은 시각적 방법이나 Shapiro-Wilk 검정 같은 통계적 방법으로 확인할 수 있다. 표본이 크면 중심극한정리가 정규성 근사를 돕는다.

  • 분산의 동질성(등분산성): 집단 사이의 분산이 비슷해야(동질적이어야) 한다. 이 가정은 Levene 검정이나 Bartlett 검정으로 확인할 수 있다. 가정이 어긋나면 Welch 분산분석 같은 대안을 고려할 수 있다.

3. 한계

  • 가정에 대한 민감성: 일원배치 분산분석의 결과는 가정 위반, 특히 분산의 동질성과 정규성 위반에 민감할 수 있다.
  • 전체 차이만 탐지: 일원배치 분산분석은 집단 사이에 유의한 차이가 있는지는 탐지하지만 어느 집단이 다른지는 알려주지 않는다. 세부 비교에는 사후검정이 필요하다.

연습문제

연습문제 1. 어떤 연구자가 네 가지 매장 배치에 대한 평균 고객 만족도 점수를 비교하려 한다. 각 배치는 독립인 고객 20명으로 시험한다. 타당한 일원배치 분산분석에 필요한 세 가지 가정을 서술하고, 각 가정을 확인할 수 있는 진단 방법을 하나씩 제시하라.

풀이

세 가정은 다음과 같다:

  1. 관측의 독립성. 연구 설계를 검토하여 확인한다. 고객을 무작위로 뽑아 배치에 무작위로 배정해야 하며, 어떤 고객도 둘 이상의 집단에 나타나서는 안 된다.

  2. 정규성. 각 집단 안의 만족도 점수가 근사적으로 정규분포를 따라야 한다. 잔차의 Q-Q 그림이나 Shapiro-Wilk 검정으로 확인할 수 있다.

  3. 분산의 동질성(등분산성). 네 집단에서 만족도 점수의 분산이 대략 같아야 한다. Levene 검정으로 확인할 수 있다.

연습문제 2. 네 집단 평균의 모든 쌍을 비교하기 위해 이표본 \(t\)-검정을 여섯 번 따로 수행하면 왜 가족단위 제1종 오류율이 부풀려지는지 설명하라. 각 검정이 \(\alpha = 0.05\)를 쓴다면 여섯 검정 전체에서 거짓 양성이 적어도 하나 나올 확률의 상한을 계산하라.

풀이

각각 \(\alpha = 0.05\)인 독립인 검정 6개에서 제1종 오류를 적어도 한 번 범할 확률의 상한은

\[ 1 - (1 - 0.05)^6 = 1 - 0.95^6 \approx 1 - 0.735 = 0.265 \]

이다. 즉 가족단위 오류율이 약 \(26.5\%\)까지 올라가 명목 \(5\%\) 수준을 크게 넘어선다. 일원배치 분산분석은 하나의 F-검정으로 모든 집단 평균을 동시에 검정하여 이 부풀림을 피한다.

연습문제 3. \(k = 2\)이고 분산이 같은 두 집단에서 일원배치 분산분석의 F-통계량이 이표본(합동) \(t\)-통계량의 제곱과 같음을 보여라. SSB, SSW, 합동 \(t\)-통계량의 정의에서 시작하라.

풀이

크기가 \(n_1\), \(n_2\)이고 합동분산이 \(s_p^2 = \text{SSW}/(n_1 + n_2 - 2)\)인 \(k = 2\)개 집단에서:

\[ \text{SSB} = \frac{n_1 n_2}{n_1 + n_2}(\bar{Y}_1 - \bar{Y}_2)^2 \]
\[ F = \frac{\text{SSB}/1}{\text{SSW}/(N-2)} = \frac{n_1 n_2 (\bar{Y}_1 - \bar{Y}_2)^2}{(n_1+n_2) s_p^2} \]

합동 이표본 \(t\)-통계량은

\[ t = \frac{\bar{Y}_1 - \bar{Y}_2}{s_p \sqrt{1/n_1 + 1/n_2}} \]

이다. 제곱하면

\[ t^2 = \frac{(\bar{Y}_1 - \bar{Y}_2)^2}{s_p^2 (1/n_1 + 1/n_2)} = \frac{n_1 n_2 (\bar{Y}_1 - \bar{Y}_2)^2}{(n_1 + n_2) s_p^2} = F \]

이므로 \(k = 2\)일 때 \(F = t^2\)이다. \(\square\)

연습문제 4. 어떤 마케팅 팀이 세 광고 전략에서 집단 분산 \(s_1^2 = 4.2\), \(s_2^2 = 18.7\), \(s_3^2 = 5.1\)과 표본크기 \(n_1 = 15\), \(n_2 = 10\), \(n_3 = 20\)을 관측했다. 표준 일원배치 분산분석이 왜 오도하는 결과를 줄 수 있는지 설명하고 더 적절한 검정을 권하라.

풀이

가장 큰 분산(\(18.7\))이 가장 작은 분산(\(4.2\))의 네 배가 넘고 표본크기도 서로 다르다. 분산이 가장 큰 집단이 표본크기도 가장 작을 때(\(n_2 = 10\)) 표준 분산분석의 합동분산은 집단 2의 참 변동을 과소추정하고 나머지는 과대추정한다. 그 결과 F-검정이 관대해져서 명목 \(\alpha\) 수준보다 자주 \(H_0\)을 기각한다.

적절한 대안은 Welch의 일원배치 분산분석이다. 각 집단의 분산을 따로 추정하고 Welch-Satterthwaite 식으로 자유도를 조정하여 이분산 아래에서도 올바른 제1종 오류율을 유지한다.

연습문제 5. 연습문제 3의 항등식 \(F=t^2\)을 수치로 확인하고, 이 사실이 실무에서 무엇을 뜻하는지 정리하라.

풀이
import numpy as np
from scipy import stats

rng = np.random.default_rng(4242)
print("k = 2 일 때  F = t²")
for n1, n2 in [(10, 10), (12, 8), (30, 25)]:
    x = rng.normal(0, 1, n1)
    y = rng.normal(0.5, 1, n2)
    F, p_F = stats.f_oneway(x, y)
    t, p_t = stats.ttest_ind(x, y, equal_var=True)
    print(f"  n=({n1},{n2}):  F = {F:.6f},  t² = {t**2:.6f},  "
          f"차이 = {abs(F - t**2):.2e}")
    print(f"              p_F = {p_F:.6f},  p_t = {p_t:.6f}")
k = 2 일 때  F = t²
  n=(10,10):  F = 3.611317,  t² = 3.611317,  차이 = 0.00e+00
              p_F = 0.073526,  p_t = 0.073526
  n=(12,8):  F = 6.773407,  t² = 6.773407,  차이 = 2.66e-15
              p_F = 0.018002,  p_t = 0.018002
  n=(30,25):  F = 2.855746,  t² = 2.855746,  차이 = 4.44e-16
              p_F = 0.096923,  p_t = 0.096923

완전히 같다. \(p\) 값도 소수점 여섯째 자리까지 일치한다.

왜 그런가. \(k=2\)이면 \(\text{df}_1=1\)이고, \(F_{1,\nu}\) 분포는 정의상 \(t_\nu^2\)의 분포다. 게다가 \(\sqrt{F}\)가 \(|t|\)와 같으므로 오른쪽 꼬리 확률도 같아진다.

\[ P(F_{1,\nu}>t^2)=P(|t_\nu|>|t|) \]

실무적 함의 넷.

1 — 분산분석은 \(t\) 검정의 일반화다. 새로운 검정이 아니라 \(k\ge3\)으로 확장한 것이다.

2 — 방향을 잃는다. \(t\) 검정은 부호로 방향을 알려주지만 \(F\)는 제곱하므로 어느 쪽이 큰지 모른다. \(k=2\)에서는 \(t\) 검정을 쓰는 편이 낫다.

3 — 단측검정이 불가능하다. \(F\) 검정은 언제나 양측(오른쪽 꼬리 하나)이다. \(k=2\)에서 단측 가설을 검정하려면 \(t\)로 돌아가야 한다.

4 — \(k\ge3\)에서 "어느 방향"이라는 개념 자체가 사라진다. 평균이 셋이면 대소 관계가 여러 가지이므로, 옴니버스 \(F\)가 방향을 말하지 않는 것이 자연스럽다. 방향을 보려면 대비를 쓴다.

주의. 이 항등식은 합동 \(t\) 검정과의 관계다. 웰치 \(t\) 검정은 \(F\) 검정과 같지 않다. 분산이 다르면 두 결과가 갈린다.

연습문제 6. 연습문제 2가 구한 FWER의 상한과 실제 값이 얼마나 차이 나는지 모의실험으로 확인하라.

풀이

두 가지 계산.

방법 식 가정
본페로니 부등식 \(m\alpha\) 없음(상한)
독립 가정 \(1-(1-\alpha)^m\) 검정들이 독립
import numpy as np
from scipy import stats
from itertools import combinations

rng = np.random.default_rng(4242)
M, n = 5_000, 15

print(f"{'k':>3s} {'쌍 m':>5s} {'상한 mα':>9s} "
      f"{'독립가정 1-(1-α)^m':>19s} {'실제':>9s}")
for k in [3, 4, 5, 6]:
    m = k * (k - 1) // 2
    hit = 0
    for _ in range(M):
        g = [rng.standard_normal(n) for _ in range(k)]   # 평균이 모두 같다
        hit += any(stats.ttest_ind(g[i], g[j]).pvalue < 0.05
                   for i, j in combinations(range(k), 2))
    print(f"{k:3d} {m:5d} {min(1, 0.05 * m):9.4f} "
          f"{1 - 0.95**m:19.4f} {hit / M:9.4f}")
  k   쌍 m     상한 mα      독립가정 1-(1-α)^m        실제
  3     3    0.1500              0.1426    0.1176
  4     6    0.3000              0.2649    0.2088
  5    10    0.5000              0.4013    0.2940
  6    15    0.7500              0.5367    0.3776

세 값이 모두 다르다. \(k=6\)에서 상한 0.750, 독립 가정 0.537, 실제 0.380이다.

왜 실제가 가장 작은가. 쌍별 \(t\) 검정들이 독립이 아니기 때문이다. 예컨대 A-B와 A-C 비교가 같은 A 집단을 공유하므로 양의 상관을 갖는다. A의 평균이 우연히 크면 두 비교가 함께 커진다.

양의 상관이 FWER을 낮춘다. 검정들이 함께 움직이면 "적어도 하나"가 일어날 확률이 독립일 때보다 작아진다.

그럼에도 문제는 심각하다. \(k=6\)이면 모든 평균이 같은데도 38%가 뭔가를 발견한다.

본페로니 부등식이 상한인 이유.

\[ P\Bigl(\bigcup_{i=1}^m A_i\Bigr)\le\sum_{i=1}^m P(A_i)=m\alpha \]

어떤 상관 구조에서도 성립한다. 그래서 본페로니 보정(\(\alpha/m\))이 언제나 안전하지만, 실제 FWER이 더 작으면 지나치게 보수적이 된다.

이 표가 분산분석의 존재 이유를 설명한다. 옴니버스 \(F\) 검정 하나는 \(k\)가 몇이든 수준이 정확히 0.05다. "먼저 전체를 보고, 유의하면 쪼갠다"는 전략이 여기서 나온다.

다만 옴니버스가 만능은 아니다. 앞 절에서 본 대로 \(k\ge4\)에서 보호된 LSD는 부분 귀무에서 무너진다. 투키나 더넷 같은 전용 절차가 필요하다.

연습문제 7. 연습문제 4의 상황(\(s^2=(4.2,\ 18.7,\ 5.1)\), \(n=(15,10,20)\))에서 표준 분산분석이 얼마나 오도하는지 모의실험으로 재어라.

풀이
import numpy as np
from scipy import stats

rng = np.random.default_rng(6363)

def welch_anova(*g):
    k = len(g)
    n = np.array([len(x) for x in g], float)
    m = np.array([x.mean() for x in g])
    v = np.array([x.var(ddof=1) for x in g])
    w = n / v
    W = w.sum()
    m_tilde = (w * m).sum() / W
    tmp = np.sum((1 - w / W)**2 / (n - 1))
    F = ((w * (m - m_tilde)**2).sum() / (k - 1)) \
        / (1 + 2 * (k - 2) / (k * k - 1) * tmp)
    return F, stats.f.sf(F, k - 1, (k * k - 1) / (3 * tmp))

M = 10_000
sigma = np.sqrt([4.2, 18.7, 5.1])
ns = (15, 10, 20)
a = b = 0
for _ in range(M):
    g = [rng.normal(0, s, n) for s, n in zip(sigma, ns)]   # 평균 모두 0
    a += stats.f_oneway(*g).pvalue < 0.05
    b += welch_anova(*g)[1] < 0.05
print(f"σ² = (4.2, 18.7, 5.1),  n = {ns}")
print(f"  고전 F 의 실제 수준   {a / M:.4f}")
print(f"  Welch 의 실제 수준    {b / M:.4f}")
print(f"  분산비 최대/최소 = {max(sigma**2) / min(sigma**2):.2f}")
σ² = (4.2, 18.7, 5.1),  n = (15, 10, 20)
  고전 F 의 실제 수준   0.1138
  Welch 의 실제 수준    0.0512
  분산비 최대/최소 = 4.45

고전 \(F\)의 실제 수준이 0.114로 명목의 2.3배다. 웰치는 0.051로 정확하다.

왜 이 배치가 나쁜가. 분산이 가장 큰 집단(\(s^2=18.7\))의 표본이 가장 작다(\(n=10\)). 합동 \(\text{MSE}\)가 자유도로 가중되므로

\[ \text{MSE}=\frac{14\times4.2+9\times18.7+19\times5.1}{42} =\frac{58.8+168.3+96.9}{42}=7.71 \]

인데, 정작 둘째 집단 평균의 참 분산은 \(18.7/10=1.87\)이고 합동값이 주는 것은 \(7.71/10=0.771\)이다. 표준오차를 절반 이하로 과소추정한다.

연습문제 4의 답이 정확했다. "분산이 큰 집단의 표본이 작으면 관대해진다"는 진단이 2.3배라는 수치로 확인된다.

분산비 4.45가 경계인가. 흔히 "최대/최소 분산비가 4를 넘으면 위험"이라고 하는데, 표본크기가 균형이면 4.45에서도 견딜 만하다. 불균형과 결합할 때 치명적이 된다.

print(f"\n{'n':>16s} {'고전 F':>9s} {'Welch':>9s}")
for ns2 in [(15, 15, 15), (15, 10, 20), (10, 20, 15), (20, 5, 20)]:
    a = b = 0
    for _ in range(M):
        g = [rng.normal(0, s, n) for s, n in zip(sigma, ns2)]
        a += stats.f_oneway(*g).pvalue < 0.05
        b += welch_anova(*g)[1] < 0.05
    print(f"{str(ns2):>16s} {a / M:9.4f} {b / M:9.4f}")
               n      고전 F     Welch
    (15, 15, 15)    0.0642    0.0524
    (15, 10, 20)    0.1096    0.0505
    (10, 20, 15)    0.0313    0.0482
     (20, 5, 20)    0.1789    0.0567

같은 분산 구조인데 배분에 따라 0.031에서 0.179까지 움직인다.

\(n\) 큰 분산 집단(\(s^2=18.7\))의 \(n\) 수준
(15,15,15) 15 0.064
(15,10,20) 10 0.110
(10,20,15) 20 0.031(보수적)
(20,5,20) 5 0.179

규칙이 분명하다. 분산이 큰 집단의 표본이 작을수록 관대해지고, 클수록 보수적이 된다.

실무 권고 셋.

  1. 분산비를 확인한다. 집단별 표준편차를 반드시 보고한다.
  2. 분산이 다르면 웰치를 쓴다. 사전검정으로 고르지 않는다.
  3. 설계 단계에서 균형을 맞춘다. 최소한 분산이 큰 집단을 작게 하지 않는다.

연습문제 8. 연습문제 1이 든 세 가정 중 정규성이 깨지면 얼마나 위험한지 여러 분포에서 확인하라.

풀이
import numpy as np
from scipy import stats

rng = np.random.default_rng(6363)

def welch_anova(*g):
    k = len(g)
    n = np.array([len(x) for x in g], float)
    m = np.array([x.mean() for x in g])
    v = np.array([x.var(ddof=1) for x in g])
    w = n / v
    W = w.sum()
    tmp = np.sum((1 - w / W)**2 / (n - 1))
    m_tilde = (w * m).sum() / W
    F = ((w * (m - m_tilde)**2).sum() / (k - 1)) \
        / (1 + 2 * (k - 2) / (k * k - 1) * tmp)
    return F, stats.f.sf(F, k - 1, (k * k - 1) / (3 * tmp))

M = 10_000
gens = {"정규": lambda n: rng.standard_normal(n),
        "균등": lambda n: rng.uniform(-1, 1, n),
        "t(3)": lambda n: rng.standard_t(3, n),
        "지수": lambda n: rng.exponential(1, n),
        "로그정규": lambda n: rng.lognormal(0, 1, n),
        "코시": lambda n: rng.standard_cauchy(n)}
print(f"{'분포':>10s} {'고전 F':>9s} {'Welch':>9s} {'크러스컬·월리스':>15s}")
for label, gen in gens.items():
    a = b = c = 0
    for _ in range(M):
        g = [gen(15) for _ in range(3)]      # 세 집단이 같은 분포
        a += stats.f_oneway(*g).pvalue < 0.05
        b += welch_anova(*g)[1] < 0.05
        c += stats.kruskal(*g).pvalue < 0.05
    print(f"{label:>10s} {a / M:9.4f} {b / M:9.4f} {c / M:15.4f}")
        분포      고전 F     Welch        크러스컬·월리스
        정규    0.0522    0.0513          0.0477
        균등    0.0508    0.0535          0.0492
      t(3)    0.0485    0.0416          0.0497
        지수    0.0434    0.0493          0.0460
      로그정규    0.0353    0.0423          0.0472
        코시    0.0178    0.0134          0.0514

정규성 위반은 생각보다 덜 위험하다. 극단적인 로그정규에서도 고전 \(F\)의 수준이 0.036이다. 어긋나는 방향이 보수적이다.

분포 고전 \(F\) 진단
정규 0.052 정확
균등 0.055 거의 정확
\(t(3)\) 0.045 약간 보수적
지수 0.045 약간 보수적
로그정규 0.036 보수적
코시 0.018 매우 보수적

앞 절에서 본 이분산의 대가(0.60)와 비교하면 정규성 위반은 사소하다. 이것이 "분산분석은 정규성에 로버스트하다"는 통설의 근거다.

다만 검정력은 크게 잃는다. 수준이 보수적이라는 것은 곧 검정력 손실이다.

print(f"\n검정력 (참 차이 있음)")
print(f"{'분포':>10s} {'고전 F':>9s} {'크러스컬·월리스':>15s}")
shifts = {"정규": lambda n, d: rng.standard_normal(n) + d,
          "지수": lambda n, d: rng.exponential(1, n) + d,
          "로그정규": lambda n, d: rng.lognormal(0, 1, n) + d,
          "코시": lambda n, d: rng.standard_cauchy(n) + d}
for label, gen in shifts.items():
    a = c = 0
    for _ in range(M):
        g = [gen(15, d) for d in (0, 0.8, 1.6)]
        a += stats.f_oneway(*g).pvalue < 0.05
        c += stats.kruskal(*g).pvalue < 0.05
    print(f"{label:>10s} {a / M:9.4f} {c / M:15.4f}")
검정력 (참 차이 있음)
        분포      고전 F        크러스컬·월리스
        정규    0.9752          0.9673
        지수    0.9615          0.9935
      로그정규    0.5607          0.9281
        코시    0.0793          0.4556

꼬리가 두꺼우면 검정력이 무너진다. 로그정규에서 0.561, 코시에서 0.079로 사실상 아무것도 못 찾는다.

크러스컬·월리스가 훨씬 강력하다. 로그정규 0.928, 코시 0.456이다. 순위로 바꾸면 극단값의 영향이 사라지기 때문이다.

지수분포에서도 순위 검정이 앞선다(0.994 대 0.962). 정규자료에서만 \(F\)가 근소하게 유리하다(0.975 대 0.967).

결론 — 정규성 위반의 진짜 대가는 검정력이다.

관심 조치
수준(제1종 오류) 대체로 안전. 조치 불필요
검정력 꼬리가 두꺼우면 순위 검정이나 절사평균

가정 점검의 우선순위.

  1. 독립성 — 가장 치명적(다음 문제)
  2. 등분산 — 수준이 크게 무너짐(연습문제 7)
  3. 정규성 — 수준은 안전, 검정력이 문제

실무에서는 순서가 거꾸로다. 정규성 검정은 쉬워서 누구나 하고, 독립성은 아무도 확인하지 않는다.

연습문제 9. 연습문제 1의 세 가정 중 독립성이 깨지면 어떻게 되는지 확인하고, 대처법을 제시하라.

풀이

상황. 각 집단의 관측이 군집을 이루는 경우다. 예컨대 매장 배치를 시험하는데, 한 매장에서 고객 여러 명을 관측하면 같은 매장의 고객끼리 닮아 있다.

import numpy as np
from scipy import stats

rng = np.random.default_rng(9898)
M, n_cluster = 5_000, 6      # 집단마다 군집 6개

print(f"{'군집 크기':>9s} {'ICC':>5s} {'DEFF':>6s} {'고전 F':>9s} "
      f"{'군집평균 F':>11s}")
for m, icc in [(1, 0.0), (5, 0.1), (5, 0.3), (10, 0.3), (10, 0.5)]:
    deff = 1 + (m - 1) * icc
    s_between = np.sqrt(icc)
    s_within = np.sqrt(1 - icc) if icc > 0 else 1.0
    a = c = 0
    for _ in range(M):
        groups, cluster_means = [], []
        for _ in range(3):
            cl = rng.normal(0, s_between, n_cluster) if icc > 0 \
                else np.zeros(n_cluster)
            vals = np.concatenate([cl[j] + rng.normal(0, s_within, m)
                                   for j in range(n_cluster)])
            groups.append(vals)
        a += stats.f_oneway(*groups).pvalue < 0.05
        # 군집 평균을 분석단위로 삼는다
        cm = [np.array([x[j * m:(j + 1) * m].mean()
                        for j in range(n_cluster)]) for x in groups]
        c += stats.f_oneway(*cm).pvalue < 0.05
    print(f"{m:9d} {icc:5.1f} {deff:6.2f} {a / M:9.4f} {c / M:11.4f}")
    군집 크기   ICC   DEFF      고전 F      군집평균 F
        1   0.0   1.00    0.0464      0.0464
        5   0.1   1.40    0.1166      0.0476
        5   0.3   2.20    0.2704      0.0498
       10   0.3   3.70    0.4552      0.0498
       10   0.5   5.50    0.6078      0.0526

최악의 경우 수준이 0.608이다. 세 집단의 평균이 모두 같은데 60%를 기각한다.

DEFF와 함께 커진다.

ICC 군집 크기 DEFF 고전 \(F\)의 수준
0 1 1.0 0.047
0.1 5 1.4 0.117
0.3 5 2.2 0.270
0.3 10 3.7 0.455
0.5 10 5.5 0.608

군집 평균을 분석단위로 삼으면 완전히 해결된다(0.046~0.053). 관측 180개를 군집 18개로 줄이는 대가로 수준이 정확해진다. 관측 180개를 군집 18개로 줄이지만, 수준이 정확해진다.

정보를 얼마나 잃는가. 군집 안의 관측은 서로 닮아 있으므로 애초에 독립적인 정보가 아니었다. 유효 표본크기는

\[ N_{\text{eff}}=\frac{N}{\text{DEFF}} \]

이고, ICC \(=0.5\)·\(m=10\)이면 \(180/5.5=32.7\)이다. 군집 18개보다 조금 많은 정도라, 군집 평균으로 줄이는 것이 큰 손해가 아니다.

세 가지 대처법.

방법 장단
군집 평균을 분석단위로 단순·확실. 공변량 불가
혼합효과 모형 공변량·불균형 처리. 가정 필요
군집 로버스트 표준오차 군집이 많아야 함(30 이상)

알아채는 법 — 자료 수집 방식을 본다.

신호 예
여러 대상을 한 단위에서 관측 매장·학급·병원·농장
같은 대상의 반복 측정 반복측정 분산분석
시간적·공간적 인접 연속 생산 배치, 인접 구획
형제·쌍둥이 가족 단위 상관

"\(n\)이 크니 괜찮다"가 통하지 않는다. 군집 수가 늘지 않으면 \(n\)을 늘려도 정보가 거의 늘지 않고, 수준만 더 나빠진다.

설계 단계의 교훈. 군집 자료에서는 군집 수가 검정력을 지배한다. 매장 3개에서 고객 100명씩 보는 것보다 매장 30개에서 10명씩 보는 편이 훨씬 낫다.

연습문제 10. 일원배치 분산분석의 가정 점검 우선순위를 정리하라.

풀이

세 가정의 위험도 — 이 페이지에서 잰 값.

가정 최악의 수준 확인 방법
독립성 0.608 자료 수집 방식(검정 불가)
등분산 0.179 집단별 표준편차, 잔차 그림
정규성 0.018~0.055 정규분위수그림

순서가 중요하다. 위에서부터 확인한다.

① 독립성
    자료가 어떻게 수집되었는가?
    ├─ 군집·반복측정 → 혼합모형 / 군집 단위 분석
    └─ 단순 확률표본 → 계속
          ↓
② 등분산
    집단별 표준편차를 본다
    ├─ 비슷하고 n 도 균형 → 고전 F
    └─ 그 밖 → Welch 분산분석   ← 기본으로 권장
          ↓
③ 정규성
    정규분위수그림, 상자그림
    ├─ 대체로 정규 → 그대로
    ├─ 꼬리가 두꺼움 → 순위 검정 / 절사평균 (검정력 회복)
    └─ 심하게 치우침 → 변환 검토
          ↓
④ 검정 + 효과크기 + 사후비교

각 가정이 무엇을 망가뜨리는가.

가정 위반 수준 검정력 대처
독립성 크게 무너짐 — 혼합모형, 군집 단위
등분산 무너짐(양방향) 왜곡 Welch
정규성(꼬리) 보수적 크게 손실 순위·절사평균

정규성만 다른 성격이라는 점이 중요하다. 수준은 안전하므로 "거짓 발견"의 위험이 없다. 문제는 있는 것을 못 찾는 것이다.

점검 목록.

  • [ ] 관측이 독립인가 — 자료 수집 방식을 물었는가
  • [ ] 집단별 표준편차를 계산했는가
  • [ ] 표본크기가 균형인가
  • [ ] 분산이 큰 집단의 \(n\)이 작지 않은가
  • [ ] 상자그림·정규분위수그림을 그렸는가
  • [ ] 이상점이 있는가
  • [ ] 검정을 사전에 정했는가(사전검정으로 고르지 않았는가)

자주 하는 실수 다섯.

실수 대가
정규성만 확인하고 독립성은 건너뜀 수준이 0.61까지
등분산 사전검정으로 검정 선택 9장의 2단계 절차 문제
분산이 큰 집단을 작게 설계 관대한 검정
\(k\ge4\)에서 쌍별 \(t\) 반복 FWER 0.38(연습문제 6)
꼬리가 두꺼운데 그대로 \(F\) 검정력 0.08까지

한 문장. 분산분석의 세 가정은 위험도가 다르다. 확인하기 쉬운 것부터가 아니라 망가뜨리는 정도가 큰 것부터 보는 것이 옳다.


정리하며

일원배치 분산분석은 집단이 셋 이상일 때 평균을 한 번에 비교한다.

  • 왜 \(t\) 검정을 반복하지 않는가. 집단이 \(k\) 개면 쌍이 \(\binom k2\) 개이고, 9장에서 보았듯 각각 \(\alpha=0.05\) 로 검정하면 적어도 하나가 거짓 기각될 확률이 급격히 커진다. \(k=5\) 면 쌍이 10 개라 FWER 이 \(0.40\) 에 이른다.
  • 핵심은 변동의 분해다. 전체 변동을 집단 간과 집단 내로 쪼개고, 그 비를 본다. 집단 간이 집단 내보다 충분히 크면 평균이 다르다고 본다.
  • \(F\) 가 1 근처면 \(H_0\) 과 부합한다. 두 분산 추정값이 같은 것을 재고 있다는 뜻이기 때문이다.
  • 가정은 셋이다. 정규성, 등분산성, 독립성. 이 장의 상당 부분이 이 셋을 확인하고 위반에 대처하는 데 쓰인다.
  • 기각은 "어딘가 다르다"까지만 말한다. 어느 집단이 다른지는 사후검정이 답하며, 거기서 다시 다중검정 보정이 필요하다.

다음 절 \(F\)-검정 절차에서 그 계산을 단계별로 밟는다.