콘텐츠로 이동

분산분석 F-통계량 모의실험

개요

일원배치 분산분석 F-검정은 적어도 한 집단의 평균이 다른지 탐지하지만, 그 검정력은 집단 평균의 분리 정도, 집단 내 분산, 표본크기의 상호작용에 크게 좌우된다. 이 페이지에서는 신중하게 고른 아홉 가지 모수 설정에서 F-검정을 1000번씩 반복하는 Monte Carlo 모의실험으로 이 관계에 대한 직관을 쌓고, F-통계량의 분포와 기각률이 어떻게 달라지는지 살펴본다.

일원배치 분산분석의 F-통계량

집단이 \(k\)개이고 표본크기가 \(n_1, \dots, n_k\), 전체 표본크기가 \(N = \sum_{i=1}^{k} n_i\)일 때 F-통계량은

\[ F = \frac{\text{MST}}{\text{MSE}} = \frac{\text{SST} / (k - 1)}{\text{SSE} / (N - k)} \]

이다. 여기서 \(\text{SST}\)는 집단 간 제곱합, \(\text{SSE}\)는 집단 내 제곱합이다. 귀무가설 \(H_0: \mu_1 = \mu_2 = \cdots = \mu_k\) 아래에서 이 통계량은 \(F(k-1,\, N-k)\) 분포를 따른다. 유의수준 \(\alpha\)에서

\[ F > F_{\text{crit}} = F_{1-\alpha}(k-1,\, N-k) \]

이면 \(H_0\)을 기각한다.

모의실험 설계

각 시나리오는 지정된 평균 \(\boldsymbol{\mu}\), 표준편차 \(\boldsymbol{\sigma}\), 크기 \(\boldsymbol{n}\)을 갖는 정규 집단 셋을 생성하고 scipy.stats.f_oneway를 1000번 실행한다. 아홉 시나리오는 다양한 조건을 훑는다:

시나리오 평균 표준편차 크기
큰 분리, 등분산 \((3, 6, 9)\) \((6, 6, 6)\) \((10, 20, 30)\)
아주 작은 분리, 등분산 \((3, 3.1, 2.9)\) \((6, 6, 6)\) \((10, 20, 30)\)
아주 작은 분리, 이분산 \((3, 3.1, 2.9)\) \((6, 12, 18)\) \((10, 20, 30)\)
큰 분리, 큰 분산 \((3, 6, 9)\) \((10, 10, 10)\) \((10, 20, 30)\)
중간 분리, 큰 분산, 작은 \(n\) \((3, 5, 6)\) \((10, 10, 10)\) \((10, 10, 10)\)
중간 분리, 큰 분산, 큰 \(n\) \((3, 5, 6)\) \((10, 10, 10)\) \((5000, 5000, 5000)\)
분리 없음, 아주 큰 분산 \((3, 3, 3)\) \((100, 100, 100)\) \((10, 10, 10)\)
분리 없음, 이분산 \((3, 3, 3)\) \((1, 1, 2)\) \((10, 20, 30)\)
분리 없음, 작은 등분산 \((3, 3, 3)\) \((1, 1, 1)\) \((10, 20, 30)\)

핵심 모의실험 코드

simulate_f 함수는 각 정규분포에서 집단을 뽑고 반복마다 분산분석 F-통계량을 계산한다:

보기 1. 귀무분포는 \(\sigma\) 를 모른다. 모의실험을 돌리기 전에 무엇이 나와야 하는지를 먼저 정해 두자.

(1) 자료를 \(y_{ij} \mapsto a + c\,y_{ij}\) (\(c \ne 0\))로 바꾸어도 \(F\) 가 변하지 않음을 보이시오. 이로부터 \(H_0\) 아래 \(F\) 의 분포가 공통평균 \(\mu\) 와 공통 표준편차 \(\sigma\) 에 전혀 의존하지 않고 자유도만으로 정해짐을 결론하시오. 또 \(H_0\) 아래에서 \(p\)-값이 \(U(0,1)\) 을 정확히 따름을 보이시오.

(2) \(\boldsymbol\mu = (3,3,3)\), \(\boldsymbol n = (10,20,30)\) 에서 \(\sigma = 6\) 과 \(\sigma = 600\) 으로 각각 모의실험을 돌려 (1)을 확인하시오. \(F\) 의 평균·표준편차를 \(F(2,57)\) 의 이론값과 맞추고, 콜모고로프–스미르노프 검정으로 분포 전체를 견주시오.

풀이

(1) 해석적으로. 변환 \(z_{ij} = a + c\,y_{ij}\) 를 넣으면 평균도 같이 변한다.

\[ \bar z_{i\cdot} = a + c\,\bar y_{i\cdot}, \qquad \bar z_{\cdot\cdot} = a + c\,\bar y_{\cdot\cdot} \]

차를 만들면 \(a\) 가 사라지고 \(c\) 만 남는다.

\[ \bar z_{i\cdot} - \bar z_{\cdot\cdot} = c(\bar y_{i\cdot} - \bar y_{\cdot\cdot}), \qquad z_{ij} - \bar z_{i\cdot} = c(y_{ij} - \bar y_{i\cdot}) \]

그러므로 \(SSB \mapsto c^2 SSB\), \(SSW \mapsto c^2 SSW\) 이고 비를 만들면

\[ F = \frac{SSB/(k-1)}{SSW/(N-k)} \mapsto \frac{c^2 SSB/(k-1)}{c^2 SSW/(N-k)} = F \]

로 \(c^2\) 이 약분된다. \(F\) 는 위치·척도 변환에 불변이다.

이제 \(H_0\) 을 가정하자. \(y_{ij} = \mu + \sigma\varepsilon_{ij}\) 이고 \(\varepsilon_{ij} \sim N(0,1)\) 이라 쓸 수 있으므로, 위 불변성에 \(a = \mu\), \(c = \sigma\) 를 넣으면 \(y\) 로 잰 \(F\) 와 \(\varepsilon\) 으로 잰 \(F\) 가 같은 수다. 따라서 \(F\) 의 분포는 \(\mu\) 와 \(\sigma\) 에 전혀 의존하지 않고 \((k-1,\ N-k)\) 만으로 정해진다. 여기서는 \(F(2, 57)\) 이고

\[ E[F] = \frac{d_2}{d_2-2} = \frac{57}{55} = 1.0364, \qquad \operatorname{Var}(F) = \frac{2d_2^2(d_1+d_2-2)}{d_1(d_2-2)^2(d_2-4)} = 1.1551 \]

이다(표준편차 \(1.0748\)).

\(p\)-값은 더 간단하다. \(p = S_F(F)\) 이고 \(S_F\) 는 \(F(2,57)\) 의 생존함수다. \(F\) 가 연속확률변수이고 \(H_0\) 아래에서 정확히 그 분포를 따르므로, 확률적분변환에 의해

\[ P(p \le u) = P(S_F(F) \le u) = P(F \ge S_F^{-1}(u)) = u, \qquad 0 \le u \le 1 \]

로 \(p \sim U(0,1)\) 이다. 근사가 아니라 정확한 등식이다(정규성과 등분산이 성립하는 한). 그래서 \(\alpha = 0.05\) 에서 기각률이 정확히 \(0.05\) 여야 한다.

(2) 수치적으로.

import numpy as np
from scipy import stats

np.random.seed(42)      # 아래 출력을 재현하려면 고정한다

def simulate_f(mu, sigma, sizes, n_sim=1000):
    """지정한 평균/표준편차/크기로 집단을 만들고 F-검정을 n_sim번 반복한다."""
    F_vals, p_vals = [], []
    for _ in range(n_sim):
        # 집단마다 평균도 표준편차도 크기도 다를 수 있게 zip으로 묶는다.
        groups = [stats.norm.rvs(m, s, n)
                  for m, s, n in zip(mu, sigma, sizes)]
        F, p = stats.f_oneway(*groups)
        F_vals.append(F)
        p_vals.append(p)
    return np.array(F_vals), np.array(p_vals)


# (1) 의 불변성: 자료를 a + c*y 로 바꾸어도 F 가 그대로인가.
rng = np.random.default_rng(7)
y = [rng.normal(3, 6, m) for m in (10, 20, 30)]
F0, _ = stats.f_oneway(*y)
F1, _ = stats.f_oneway(*[100 + 7 * g for g in y])
print(f"원자료      F = {F0!r}")
print(f"100 + 7y 로 F = {F1!r}")

# sigma 를 100배 키워도 귀무분포가 같은가.
for sigma in (6, 600):
    F_vals, p_vals = simulate_f((3, 3, 3), (sigma,) * 3, (10, 20, 30), n_sim=10000)
    ks_F = stats.kstest(F_vals, stats.f(2, 57).cdf)
    ks_p = stats.kstest(p_vals, 'uniform')
    print(f"\nsigma = {sigma}")
    print(f"  F 의 평균 {F_vals.mean():.4f} (이론 {57 / 55:.4f}),  "
          f"표준편차 {F_vals.std(ddof=1):.4f} (이론 {np.sqrt(stats.f(2, 57).var()):.4f})")
    print(f"  F ~ F(2,57) 인가:  KS = {ks_F.statistic:.4f}, p = {ks_F.pvalue:.4f}")
    print(f"  p-값이 균등인가:   KS = {ks_p.statistic:.4f}, p = {ks_p.pvalue:.4f}")
    print(f"  기각률 = {np.mean(p_vals < 0.05):.4f}")

np.random.seed(42)   # 보기 2 의 출력을 그대로 재현하려고 씨앗을 되돌린다

출력:

원자료      F = 2.0897728316088156
100 + 7y 로 F = 2.0897728316088156

sigma = 6
  F 의 평균 1.0331 (이론 1.0364),  표준편차 1.0693 (이론 1.0748)
  F ~ F(2,57) 인가:  KS = 0.0055, p = 0.9212
  p-값이 균등인가:   KS = 0.0055, p = 0.9212
  기각률 = 0.0496

sigma = 600
  F 의 평균 1.0389 (이론 1.0364),  표준편차 1.0832 (이론 1.0748)
  F ~ F(2,57) 인가:  KS = 0.0083, p = 0.4886
  p-값이 균등인가:   KS = 0.0083, p = 0.4886
  기각률 = 0.0501

불변성이 비트 수준에서 확인된다. \(100 + 7y\) 로 바꾼 뒤의 \(F\) 가 원자료의 \(F\) 와 마지막 자리까지 같은 수다(\(2.0897728316088156\)). 유도한 \(c^2\) 약분이 반올림 오차조차 남기지 않았다.

\(\sigma\) 를 100배 키워도 귀무분포가 꿈쩍하지 않는다. \(\sigma = 6\) 과 \(\sigma = 600\) 에서 평균이 \(1.0331\) 과 \(1.0389\) 로 둘 다 이론값 \(1.0364\) 주위에 있고, 표준편차도 \(1.0693\) 과 \(1.0832\) 로 이론값 \(1.0748\) 을 감싼다. KS 검정은 \(p = 0.9212\) 와 \(p = 0.4886\) 으로 \(F(2,57)\) 과의 차이를 전혀 찾지 못한다. 기각률도 \(0.0496\) 과 \(0.0501\) 로 명목 \(0.05\) 와 맞는다(\(1\)만 번 반복의 표준오차가 \(0.0022\) 다).

눈여겨볼 것이 하나 더 있다. \(F\) 에 대한 KS 통계량과 \(p\)-값에 대한 KS 통계량이 같은 수다(\(0.0055\), \(0.0083\)). 우연이 아니다. \(p = S_F(F)\) 가 순감소 일대일 변환이므로 두 경험분포함수가 뒤집힌 꼴로 같고, 상한거리인 KS 통계량이 보존된다. 그러므로 "\(F\) 가 \(F(2,57)\) 을 따르는가"와 "\(p\) 가 균등한가"는 같은 질문이다.

각 시나리오마다 임계값과 경험적 기각률을 계산한다:

보기 2. 기각률을 모의실험 전에 맞혀 보기. 다섯 시나리오의 기각률은 모의실험 없이도 계산된다.

(1) 대립가설 아래에서 \(F\) 가 비중심 \(F\) 분포 \(F'(k-1,\,N-k;\,\lambda)\) 를 따르고

\[ \lambda = \frac{\sum_i n_i(\mu_i - \bar\mu)^2}{\sigma^2}, \qquad \bar\mu = \frac{\sum_i n_i \mu_i}{N} \]

임을 보기 1의 \(E[MSB]\) 계산과 이어서 설명하시오. 각 시나리오의 \(\lambda\) 를 손으로 구하고, 검정력이

\[ \text{power} = P\!\left(F'(k-1,\,N-k;\,\lambda) > F_{0.95}(k-1,\,N-k)\right) \]

임을 적으시오. \(\lambda = 0\) 이면 왜 검정력이 정확히 \(0.05\) 인가.

(2) 다섯 시나리오의 이론 검정력을 계산해 모의실험 기각률과 맞추시오. 표의 \(1000\) 번 반복으로 충분한지도 따지시오.

풀이

(1) 해석적으로. 보기 1(11.1절)에서 본 대로

\[ E[MSB] = \sigma^2 + \frac{\sum_i n_i(\mu_i-\bar\mu)^2}{k-1} \]

이었다. 정규성을 더하면 이 "들뜬 양"이 분포 수준으로 올라간다. \(\sqrt{n_i}\,\bar y_{i\cdot}\) 들을 모은 벡터를 집단 사이 방향으로 사영하면 그 제곱길이가 \(SSB\) 이고, 평균이 \(0\) 이 아닌 정규벡터의 제곱길이이므로

\[ \frac{SSB}{\sigma^2} \sim \chi'^2_{k-1}(\lambda), \qquad \lambda = \frac{\sum_i n_i(\mu_i-\bar\mu)^2}{\sigma^2} \]

인 비중심 카이제곱이 된다. 비중심모수는 "사영된 평균벡터의 제곱길이를 \(\sigma^2\) 으로 잰 것"일 뿐이다. 분모는 평균과 무관하므로 \(SSW/\sigma^2 \sim \chi^2_{N-k}\) 그대로이고 분자와 독립이다. 따라서

\[ F = \frac{SSB/(k-1)}{SSW/(N-k)} \sim F'(k-1,\ N-k;\ \lambda) \]

이다. \(\lambda\) 에 \(\sigma^2\) 이 분모로 들어 있다는 것이 핵심이다. 평균 차이를 키우는 것과 \(\sigma\) 를 줄이는 것과 \(n\) 을 늘리는 것이 모두 같은 방향으로 작용한다.

\(\lambda = 0\) 이면 비중심 카이제곱이 보통 카이제곱이 되어 \(F' = F\) 가 중심 \(F\) 분포이고, 임계값은 바로 그 분포의 \(95\%\) 분위수이므로 검정력이 정확히 \(0.05\) 다. 보기 1의 \(p \sim U(0,1)\) 과 같은 말이다.

\(\lambda\) 를 손으로 구해 보자. 첫 시나리오는 \(\boldsymbol\mu = (3,6,9)\), \(\boldsymbol n = (10,20,30)\), \(\sigma = 6\) 이므로 가중평균이

\[ \bar\mu = \frac{10(3)+20(6)+30(9)}{60} = \frac{420}{60} = 7 \]

이고

\[ \lambda = \frac{10(3-7)^2 + 20(6-7)^2 + 30(9-7)^2}{36} = \frac{160+20+120}{36} = \frac{300}{36} = 8.3333 \]

이다. \(\bar\mu\) 가 단순평균 \(6\) 이 아니라 가중평균 \(7\) 임에 유의하라. 큰 집단이 전체평균을 끌어당긴다.

(2) 수치적으로.

scenarios = [
    ("큰 분리, 등분산",        (3, 6, 9),       (6, 6, 6),      (10, 20, 30)),
    ("아주 작은 분리, 등분산", (3, 3.1, 2.9),   (6, 6, 6),      (10, 20, 30)),
    ("중간 분리, 큰 분산, n=10",  (3, 5, 6),    (10, 10, 10),   (10, 10, 10)),
    ("중간 분리, 큰 분산, n=5000",(3, 5, 6),    (10, 10, 10),   (5000, 5000, 5000)),
    ("분리 없음, 등분산",      (3, 3, 3),       (1, 1, 1),      (10, 20, 30)),
]

print(f"{'시나리오':<26} {'F_crit':>7} {'기각률':>8}")
for name, mu, sigma, sizes in scenarios:
    F_vals, p_vals = simulate_f(mu, sigma, sizes, n_sim=1000)
    df1 = len(mu) - 1                # k - 1
    df2 = sum(sizes) - len(mu)       # N - k
    # 임계값은 자유도만으로 정해진다. 자료와 무관하다.
    F_crit = stats.f.ppf(0.95, df1, df2)
    reject_pct = np.mean(F_vals > F_crit) * 100
    print(f"{name:<26} {F_crit:>7.3f} {reject_pct:>7.1f}%")

출력:

시나리오                        F_crit      기각률
큰 분리, 등분산                    3.159    68.1%
아주 작은 분리, 등분산                3.159     4.9%
중간 분리, 큰 분산, n=10            3.354     7.1%
중간 분리, 큰 분산, n=5000          2.996   100.0%
분리 없음, 등분산                   3.159     4.8%

평균이 모두 같은 마지막 시나리오에서 기각률 4.8%는 명목 5%와 어긋나지 않는다(모의실험 오차 0.7%p). 검정이 올바르게 보정되어 있다는 뜻이다.

셋째와 넷째 줄을 비교하면 표본크기의 힘이 드러난다. 평균과 분산이 완전히 같은데 집단당 10명에서는 검정력이 7.1%, 5,000명에서는 100%다. 검정력은 효과크기가 아니라 효과크기와 표본크기의 조합에서 나온다.

둘째 줄의 4.9%도 눈여겨보라. 평균이 3, 3.1, 2.9로 실제로 다르지만 차이가 표준편차 6에 비해 너무 작아 귀무 시나리오와 구별되지 않는다.

이제 이 다섯 수를 이론값과 맞춰 본다. 반복을 \(1000\) 에서 \(10000\) 으로 늘린다(\(n = 5000\) 짜리는 무거우므로 \(300\) 번만 돌린다).

import warnings

np.random.seed(2024)
print(f"{'scenario':<28}{'lambda':>10}{'theory':>9}{'sim':>8}{'MCse':>8}{'z':>7}")
with warnings.catch_warnings():            # 거대한 lambda 에서 나는 overflow 경고를 끈다
    warnings.simplefilter("ignore")
    for name, mu, sigma, sizes in scenarios:
        mu_a, n_a = np.array(mu, float), np.array(sizes, float)
        N, k = n_a.sum(), len(mu)
        mu_bar = (n_a * mu_a).sum() / N       # 표본크기로 가중한 평균
        lam = (n_a * (mu_a - mu_bar) ** 2).sum() / sigma[0] ** 2
        d1, d2 = k - 1, N - k
        crit = stats.f(d1, d2).ppf(0.95)
        power = 0.05 if lam == 0 else float(stats.ncf(d1, d2, lam).sf(crit))
        B = 300 if max(sizes) > 1000 else 10000
        F_vals, _ = simulate_f(mu, sigma, sizes, n_sim=B)
        sim = np.mean(F_vals > crit)
        se = np.sqrt(power * (1 - power) / B)
        z = (sim - power) / se if se > 0 else 0.0
        print(f"{name:<28}{lam:>10.4f}{power:>9.4f}{sim:>8.4f}{se:>8.4f}{z:>7.2f}")

출력:

scenario                        lambda   theory     sim    MCse      z
큰 분리, 등분산                       8.3333   0.7120  0.7059  0.0045  -1.34
아주 작은 분리, 등분산                   0.0134   0.0510  0.0475  0.0022  -1.57
중간 분리, 큰 분산, n=10               0.4667   0.0829  0.0839  0.0028   0.38
중간 분리, 큰 분산, n=5000           233.3333   1.0000  1.0000  0.0000   0.00
분리 없음, 등분산                      0.0000   0.0500  0.0539  0.0022   1.79

다섯 시나리오 모두 이론값과 맞는다. 표준화잔차 \(z\) 가 \(-1.57\) 에서 \(+1.79\) 사이에 있어 몬테카를로 요동으로 모두 설명된다.

시나리오 \(\lambda\) 이론 검정력 모의(\(B\) 회)
큰 분리, 등분산 \(8.3333\) \(0.7120\) \(0.7059\)
아주 작은 분리 \(0.0134\) \(0.0510\) \(0.0475\)
중간 분리, \(n=10\) \(0.4667\) \(0.0829\) \(0.0839\)
중간 분리, \(n=5000\) \(233.33\) \(1.0000\) \(1.0000\)
분리 없음 \(0\) \(0.0500\) \(0.0539\)

\(\lambda\) 하나가 모든 것을 설명한다. 셋째와 넷째 줄은 평균도 분산도 똑같고 \(n\) 만 \(10\) 에서 \(5000\) 으로 늘렸는데 \(\lambda\) 가 \(0.4667\) 에서 \(233.33\) 으로 \(500\) 배가 되고 검정력이 \(0.08\) 에서 \(1\) 로 간다. \(\lambda\) 가 \(n\) 에 비례하기 때문이다. 둘째 줄은 평균이 실제로 다른데도 \(\lambda = 0.0134\) 라 검정력이 \(0.0510\) 으로 명목수준과 사실상 구별되지 않는다. \(0.1\) 의 차이를 \(\sigma = 6\) 으로 재면 아무것도 아니라는 뜻이다.

\(1000\) 번 반복은 모자란다. 첫 줄의 이론값이 \(0.7120\) 인데 앞의 표에서 \(1000\) 번 반복이 준 값은 \(68.1\%\) 였다. \(B = 1000\) 에서의 표준오차가 \(\sqrt{0.712\times0.288/1000} = 0.0143\) 이므로 \(68.1\%\) 는 이론값에서 \(2.2\) 표준오차 떨어진 값이다. 틀렸다고 할 정도는 아니지만 드물게 뽑힌 쪽이고, 반복을 \(10000\) 으로 늘리자 \(0.7059\) 로 \(1.3\) 표준오차 안에 들어왔다. 기각률을 소수 첫째 자리까지 읽고 싶다면 \(B = 1000\) 으로는 부족하다.

해석

이 모의실험은 몇 가지 핵심 원리를 드러낸다:

  • 신호 대 잡음 비가 검정력을 좌우한다. 시나리오 1(큰 평균 분리, 중간 분산)은 높은 기각률을 주는 반면, 시나리오 4(같은 분리에 더 큰 분산)는 검정력이 뚜렷하게 떨어진다.
  • 표본크기가 잡음을 보상한다. 시나리오 5와 6(평균과 분산은 같고 \(n = 10\) 대 \(n = 5000\))을 비교하면 표본이 크면 중간 정도의 차이도 안정적으로 탐지할 수 있음을 알 수 있다.
  • 귀무 시나리오는 제1종 오류를 통제한다. 시나리오 7–9는 평균이 모두 같으므로 기각은 모두 거짓 양성이다. \(\alpha = 0.05\)에서 경험적 기각률이 5% 근처를 맴돌아야 검정이 잘 보정되었음을 확인해 준다.
  • 분산이 다르면 검정이 왜곡된다. 시나리오 2와 3(아주 작은 분리에서 등분산 대 이분산)을 비교하면, 분산과 집단 크기의 관계에 따라 이분산이 검정력을 낮추거나 제1종 오류를 부풀릴 수 있음이 드러난다.

표의 기각률만 보면 "5%가 나왔다"와 "68%가 나왔다"가 그저 두 숫자일 뿐이다. 그 숫자들이 어디서 오는지는 \(F\) 통계량의 분포를 통째로 그려 보아야 보인다. 아래는 \(n = (10, 20, 30)\), \(\sigma = 6\)으로 고정하고 평균만 바꿔 가며 \(F\)를 각각 2만 번 계산한 것이다.

귀무분포와 비중심분포, 그리고 기각률이 나오는 자리

왼쪽은 \(\boldsymbol{\mu} = (3, 3, 3)\), 곧 \(H_0\)이 참인 경우다. 모의실험 히스토그램이 이론밀도 \(F(2, 57)\) 곡선과 눈으로 구별되지 않을 만큼 겹친다. 모의실험이 옳다는 확인이자, \(F\) 통계량의 귀무분포가 자유도 두 개만으로 완전히 정해진다는 확인이기도 하다. 자료의 \(\sigma\)가 6이든 600이든 이 곡선은 움직이지 않는다. 분모가 분자와 같은 \(\sigma^2\)로 함께 커져 비에서 상쇄되기 때문이다. 임계값 \(F_{0.95}(2, 57) = 3.159\) 오른쪽 넓이가 명목 \(5\%\)이고, 모의실험에서 실제로 \(4.7\%\)가 나왔다.

같은 왼쪽 그림의 초록 점선이 \(\boldsymbol{\mu} = (3, 6, 9)\)일 때의 이론분포, 곧 비중심 \(F\) 분포다. 모양이 아예 달라진다. 귀무분포는 0에서 가장 높고 단조감소하는데, 비중심분포는 봉우리가 \(3.6\) 부근으로 밀려나고 꼬리가 길게 끌린다. 밀린 정도를 정하는 것이 비중심모수

\[ \lambda = \frac{\sum_i n_i(\mu_i - \bar{\mu})^2}{\sigma^2} = \frac{10(3-7)^2 + 20(6-7)^2 + 30(9-7)^2}{36} = \frac{300}{36} = 8.333 \]

하나다. 여기서 \(\bar{\mu} = 7\)은 표본크기로 가중한 평균임에 유의하라.

오른쪽은 두 상황의 모의실험 히스토그램을 같은 축에 겹치고 기각역을 분홍으로 칠한 것이다. 기각률이란 각 분포가 분홍 영역에 남기는 넓이일 뿐이다. 파랑은 거의 전부가 임계값 왼쪽에 몰려 있어 \(4.7\%\)만 남고, 초록은 상당 부분이 오른쪽으로 넘어가 \(71.2\%\)가 남는다. 비중심 \(F\)로 계산한 이론 검정력 \(0.7120\)과 소수 셋째 자리까지 일치한다. 표본크기를 키우거나 \(\sigma\)를 줄이면 \(\lambda\)가 커지면서 초록 분포가 더 오른쪽으로 밀리고, 분홍 영역에 남는 넓이가 커진다. 이것이 "검정력이 오른다"의 정확한 그림이다.

p-값 히스토그램은 보완적인 시각을 준다. 귀무가설 아래에서 p-값은 근사적으로 \([0, 1]\) 위에서 균등해야 하고, 대립가설 아래에서는 0 근처에 쌓인다.

연습문제

연습문제 1. 크기가 \((10, 20, 30)\)인 \(k = 3\)개 집단에서 평균이 모두 \(\mu_i = 5\)이고 \(\sigma_i = 1\)인 모의실험을 했더니 \(\alpha = 0.05\)에서 경험적 기각률이 4.8%였다. 검정이 올바르게 보정되었다고 볼 수 있는가? 근거를 밝혀라.

풀이

귀무가설 아래에서 기대 기각률은 \(\alpha = 0.05\)이다. 반복이 \(n_{\text{sim}} = 1000\)이면 관측된 비율이 근사적으로 \(\hat{p} \sim N(0.05,\, 0.05 \cdot 0.95 / 1000)\)을 따르므로 표준오차는 \(\sqrt{0.0000475} \approx 0.0069\)이다. 관측값 0.048은 0.05에서 표준오차 하나 이내에 있으므로 올바르게 보정된 검정과 전혀 어긋나지 않는다.

연습문제 2. 표본크기를 고정한 채 집단 내 표준편차 \(\sigma\)를 두 배로 하는 것이 집단 간 평균 분리를 절반으로 하는 것과 F-통계량에 같은 영향을 주는 이유를 직관적으로 설명하라.

풀이

F-통계량은

\[ F = \frac{\text{MST}}{\text{MSE}} \]

로 쓸 수 있다. 집단 간 평균제곱 \(\text{MST}\)는 \(n_i (\bar{y}_i - \bar{y})^2\)에 비례하므로 평균 분리 \(\delta\)의 제곱에 비례한다. 집단 내 평균제곱 \(\text{MSE}\)는 \(\sigma^2\)에 비례한다. 따라서 \(F \propto \delta^2 / \sigma^2\)이다. \(\sigma\)를 두 배로 하면 \(F\)가 4로 나뉘고, \(\delta\)를 절반으로 해도 \(F\)가 4로 나뉜다. 두 조작 모두 신호 대 잡음 비를 같은 배수만큼 줄인다.

연습문제 3. \(\sigma = 5\)일 때 \(k = 3\)개 집단에서 평균 차이 \(\delta = 2\)를 검정력 80%로 탐지하는 데 필요한 집단당 최소 표본크기를 추정하는 모의실험을 설계하라. 알고리즘을 의사코드로 기술하라.

풀이
for n in [10, 20, 30, 50, 100, 200, ...]:
    set mu = [0, delta, 0] = [0, 2, 0]
    set sigma = [5, 5, 5]
    set sizes = [n, n, n]
    run simulate_f(mu, sigma, sizes, n_sim=5000)
    compute rejection_rate = mean(p_vals < 0.05)
    if rejection_rate >= 0.80:
        return n

후보 표본크기를 차례로 시도하며 각 크기에서 많은 반복을 실행해 경험적 검정력을 계산한다. 기각률이 80%에 이르는 첫 \(n\)이 추정된 최소 표본크기이다. \(n_{\text{sim}} = 5000\) 이상을 쓰면 Monte Carlo 오차를 작게 유지할 수 있다.

연습문제 4. 세 집단의 평균이 같고 표준편차가 \((1, 1, 10)\), 표본크기가 \((50, 50, 5)\)라고 하자. 경험적 제1종 오류율이 명목 \(\alpha = 0.05\)에 가까울 것으로 기대하는가? 설명하라.

풀이

아니다. 고전적 F-검정은 등분산성을 가정한다. 분산이 가장 큰 집단(\(\sigma = 10\))의 표본크기가 가장 작으면(\(n = 5\)) 합동 MSE가 그 작은 집단 평균의 분산을 과소추정한다. 그러면 F-통계량이 평균적으로 부풀려져 제1종 오류율이 0.05를 크게 웃도는 관대한 검정이 된다. 이는 분산과 표본크기의 교란이 이분산 아래에서 표준 분산분석을 믿을 수 없게 만드는 예이며, Welch 분산분석이 적절한 대안이다.

연습문제 5. 귀무가설 아래에서 F-검정의 p-값은 \(\text{Uniform}(0, 1)\) 분포를 따라야 한다. 모의생성한 1000개의 p-값에 이를 확인하기 위해 적용할 수 있는 형식적 검정을 기술하고 그 가설을 진술하라.

풀이

Kolmogorov-Smirnov(KS) 적합도 검정이 적절하다. 가설은

\[ H_0: F_p = \text{Uniform}(0, 1), \qquad H_1: F_p \neq \text{Uniform}(0, 1) \]

이며 \(F_p\)는 모의생성된 p-값의 분포이다. Python에서는 scipy.stats.kstest(p_vals, 'uniform')이다. KS 통계량은 p-값의 경험적 누적분포함수와 \(\text{Uniform}(0, 1)\) 누적분포함수의 최대 차이를 잰다. \(H_0\)을 기각하지 못하면 귀무 시나리오에서 F-검정이 명목 수준으로 보정되어 있음을 확인해 준다. \(\square\)

연습문제 6. 연습문제 3의 의사코드를 실제로 실행하고, 비중심 \(F\) 분포로 구한 이론값과 대조하라.

풀이

이론. \(H_1\) 아래에서 \(F\)는 비중심 \(F\) 분포를 따르고, 비중심모수는

\[ \lambda=\frac{\sum_i n_i(\mu_i-\bar\mu)^2}{\sigma^2} \]

이다. 모의실험 없이 검정력을 바로 계산할 수 있다.

import warnings
warnings.filterwarnings("ignore", category=RuntimeWarning)  # ncf 의 내부 경고

import numpy as np
from scipy import stats

rng = np.random.default_rng(2025)

def power_theory(mu, sigma, n, alpha=0.05):
    """집단당 n 명일 때 비중심 F 로 구한 검정력."""
    mu = np.asarray(mu, float)
    k = len(mu)
    N = k * n
    lam = n * ((mu - mu.mean())**2).sum() / sigma**2
    crit = stats.f.ppf(1 - alpha, k - 1, N - k)
    return stats.ncf.sf(crit, k - 1, N - k, lam), lam

def power_sim(mu, sigma, n, M=3_000, alpha=0.05):
    rej = 0
    for _ in range(M):
        groups = [rng.normal(m, sigma, n) for m in mu]
        rej += stats.f_oneway(*groups).pvalue < alpha
    return rej / M

mu, sigma = [0, 2, 0], 5.0
print(f"{'n':>5s} {'λ':>9s} {'이론 검정력':>12s} {'모의 검정력':>12s}")
for n in [10, 20, 30, 50, 75, 100, 150]:
    th, lam = power_theory(mu, sigma, n)
    print(f"{n:5d} {lam:9.4f} {th:12.4f} {power_sim(mu, sigma, n):12.4f}")

for n in range(5, 500):
    if power_theory(mu, sigma, n)[0] >= 0.80:
        print(f"\n검정력 80% 에 필요한 군당 n = {n}")
        break
    n         λ       이론 검정력       모의 검정력
   10    1.0667       0.1288       0.1237
   20    2.1333       0.2279       0.2247
   30    3.2000       0.3303       0.3320
   50    5.3333       0.5225       0.5260
   75    8.0000       0.7113       0.7130
  100   10.6667       0.8371       0.8367
  150   16.0000       0.9555       0.9543

검정력 80% 에 필요한 군당 n = 92

이론과 모의가 소수점 둘째 자리까지 일치한다. 모의실험은 이론을 확인하는 수단이지 대체물이 아니다.

군당 92명이 필요하다. \(\delta=2\), \(\sigma=5\)이므로 표준화 효과가 크지 않다.

\(\lambda\)가 \(n\)에 정비례한다. \(n=10\)에서 1.067, \(n=100\)에서 10.667이다. 이것이 "표본을 늘리면 검정력이 오른다"의 정확한 표현이다.

\(\lambda\)의 구조를 보면 설계의 지렛대가 보인다.

\[ \lambda=\frac{n\sum_i(\mu_i-\bar\mu)^2}{\sigma^2} \]
조작 \(\lambda\)의 변화
\(n\)을 두 배로 두 배
평균 차이를 두 배로 네 배
\(\sigma\)를 절반으로 네 배

효과크기와 잡음이 제곱으로 들어간다. 표본을 두 배로 늘리는 것보다 측정을 정밀하게 해 \(\sigma\)를 줄이는 쪽이 훨씬 강력하다.

모의실험을 여전히 쓰는 이유. 이론 공식은 정규성과 등분산을 전제한다. 그 가정이 깨지면 비중심 \(F\) 공식이 맞지 않고, 그때는 모의실험이 유일한 수단이다. 다음 문제가 그 예다.

연습문제 7. 연습문제 4의 주장 — 큰 분산을 가진 집단의 표본이 작으면 제1종 오류율이 부풀어 오른다 — 를 모의실험으로 확인하고, 반대 배치도 함께 보라.

풀이
import numpy as np
from scipy import stats

rng = np.random.default_rng(707)

def welch_anova(*groups):
    """웰치의 일원배치 분산분석. (F, p, df2) 를 돌려준다."""
    k = len(groups)
    n = np.array([len(g) for g in groups], float)
    m = np.array([g.mean() for g in groups])
    v = np.array([g.var(ddof=1) for g in groups])
    w = n / v
    W = w.sum()
    m_tilde = (w * m).sum() / W
    A = (w * (m - m_tilde)**2).sum() / (k - 1)
    tmp = np.sum((1 - w / W)**2 / (n - 1))
    B = 1 + 2 * (k - 2) / (k * k - 1) * tmp
    F = A / B
    df2 = (k * k - 1) / (3 * tmp)
    return F, stats.f.sf(F, k - 1, df2), df2

M = 10_000
print(f"{'σ':>12s} {'n':>14s} {'고전 F':>9s} {'Welch F':>9s} "
      f"{'알렉산더·고번':>14s}")
for sig, ns in [((1, 1, 1), (50, 50, 5)),
                ((1, 1, 10), (50, 50, 5)),
                ((1, 1, 10), (5, 50, 50)),
                ((3, 2, 1), (10, 20, 30)),
                ((1, 1, 4), (20, 20, 20))]:
    a = b = c = 0
    for _ in range(M):
        g = [rng.normal(0, s, n) for s, n in zip(sig, ns)]   # 평균은 모두 0
        a += stats.f_oneway(*g).pvalue < 0.05
        b += welch_anova(*g)[1] < 0.05
        c += stats.alexandergovern(*g).pvalue < 0.05
    print(f"{str(sig):>12s} {str(ns):>14s} {a / M:9.4f} {b / M:9.4f} "
          f"{c / M:14.4f}")
           σ              n      고전 F   Welch F        알렉산더·고번
   (1, 1, 1)    (50, 50, 5)    0.0508    0.0585         0.0598
  (1, 1, 10)    (50, 50, 5)    0.5971    0.0568         0.0469
  (1, 1, 10)    (5, 50, 50)    0.0215    0.0558         0.0584
   (3, 2, 1)   (10, 20, 30)    0.1641    0.0559         0.0553
   (1, 1, 4)   (20, 20, 20)    0.0783    0.0500         0.0485

연습문제 4의 예측이 정확히 맞는다. 그리고 정도가 놀랍다.

배치 고전 \(F\)의 수준 판정
등분산 0.051 정확
큰 \(\sigma\) ↔ 작은 \(n\) 0.597 완전히 무너짐
큰 \(\sigma\) ↔ 큰 \(n\) 0.022 보수적
분산·크기 반대 방향 0.164 관대
등 \(n\), 이분산 0.078 약간 관대

평균이 모두 같은데 60%를 기각한다. 세 집단의 평균이 정확히 0으로 동일한 자료에서, 고전 \(F\) 검정이 절반 넘게 "차이가 있다"고 판정한다.

왜 그런가. 합동 \(\text{MSE}\)가 자유도로 가중평균된다.

\[ \text{MSE}=\frac{\sum_i(n_i-1)s_i^2}{N-k} \]

\(\sigma=10\)인 집단의 \(n\)이 5뿐이면 그 집단이 합동 분산에 거의 기여하지 못한다. 그래서 \(\text{MSE}\approx1\)이 되는데, 정작 그 집단의 평균은 표준오차 \(10/\sqrt5=4.5\)로 크게 흔들린다. 분자는 커지고 분모는 작으니 \(F\)가 폭발한다.

반대 배치는 보수적이다(0.022). 큰 분산 집단에 표본이 많으면 \(\text{MSE}\)가 그 집단을 충분히 반영해 오히려 과대평가된다.

등 \(n\)이면 비교적 안전하다(0.078). "분산분석은 표본크기가 같으면 이분산에 로버스트하다"는 통설의 근거인데, \(\sigma\) 비가 4:1이면 이미 0.078이다. 무조건 안전한 것은 아니다.

웰치 분산분석이 다섯 경우 모두에서 0.050~0.059로 안정적이다. 알렉산더·고번 검정도 비슷하다(0.047~0.060).

실무 결론. 9장의 웰치 \(t\) 검정과 같은 논리다. 등분산을 사전검정해 고르지 말고, 처음부터 웰치 분산분석을 쓴다. 등분산일 때 잃는 것은 수준이 0.051에서 0.059로 조금 올라가는 정도다.

연습문제 8. 연습문제 5의 콜모고로프·스미르노프 검정을 실제로 수행하라. 가정이 깨지면 \(p\) 값의 균등성이 어떻게 무너지는가?

풀이
import numpy as np
from scipy import stats

rng = np.random.default_rng(303)
M = 5_000

print(f"{'상황':>22s} {'KS D':>8s} {'KS p':>10s} {'기각률':>8s} "
      f"{'p<0.2 비율':>11s}")
setups = [("등분산 (10,20,30)", (6, 6, 6), (10, 20, 30)),
          ("이분산 큰σ↔작은n", (1, 1, 10), (50, 50, 5)),
          ("이분산 큰σ↔큰n", (1, 1, 10), (5, 50, 50)),
          ("등분산 (5,5,5)", (1, 1, 1), (5, 5, 5))]
for label, sig, ns in setups:
    pvals = np.empty(M)
    for i in range(M):
        g = [rng.normal(0, s, n) for s, n in zip(sig, ns)]
        pvals[i] = stats.f_oneway(*g).pvalue
    ks = stats.kstest(pvals, 'uniform')
    print(f"{label:>22s} {ks.statistic:8.4f} {ks.pvalue:10.4g} "
          f"{np.mean(pvals < 0.05):8.4f} {np.mean(pvals < 0.2):11.4f}")
                    상황     KS D       KS p      기각률    p<0.2 비율
        등분산 (10,20,30)   0.0083     0.8768   0.0484      0.2000
            이분산 큰σ↔작은n   0.5584          0   0.6024      0.7174
             이분산 큰σ↔큰n   0.2790          0   0.0240      0.0976
           등분산 (5,5,5)   0.0184    0.06713   0.0590      0.2162

등분산이면 균등성이 완벽하다. 첫 줄에서 \(D=0.0083\), KS \(p=0.88\)이고, \(P(p<0.2)\)가 정확히 0.2000이다.

이분산이면 분포 전체가 뒤틀린다.

상황 \(P(p<0.05)\) \(P(p<0.2)\) 진단
등분산 0.048 0.200 균등
큰\(\sigma\)↔작은\(n\) 0.602 0.717 0 쪽으로 쏠림
큰\(\sigma\)↔큰\(n\) 0.024 0.098 1 쪽으로 쏠림

KS 검정이 기각률 하나보다 훨씬 많은 것을 말해 준다. 셋째 줄의 기각률 0.024는 "보수적이구나" 정도로 보이지만, \(D=0.279\)는 분포 전체가 크게 어긋나 있음을 보여 준다.

\(n=5\)씩인 등분산 경우(마지막 줄)가 흥미롭다. KS \(p=0.067\)로 경계에 있고 기각률도 0.059로 살짝 높다. 정규자료·등분산인데도 \(n\)이 아주 작으면 완벽하지는 않다. 다만 실무적으로는 무시할 수준이다.

모의실험 점검의 표준 절차 셋.

  1. 기각률이 \(\alpha\)에 맞는가 — 가장 기본. 다만 \(\alpha\) 근처만 본다.
  2. KS 검정으로 균등성 전체를 본다 — 분포의 다른 부분도 확인.
  3. \(p\) 값 히스토그램을 그린다 — 어느 구간이 어긋났는지 눈으로 본다.

왜 \(p\) 값 전체를 보는가. 어떤 검정은 \(\alpha=0.05\)에서는 맞는데 \(\alpha=0.01\)에서 어긋난다. 기각률 하나만 보면 놓친다. KS 통계량은 모든 \(\alpha\)에 대한 최악의 오차를 재는 셈이다.

모의실험 오차도 함께 고려한다. \(M=5000\)이면 기각률의 표준오차가 \(\sqrt{0.05\cdot0.95/5000}=0.0031\)이다. 0.048과 0.050의 차이는 오차 범위 안이다.

연습문제 9. "정리하며"는 평균의 배치에 따라 검정력이 달라진다고 했다. 어떤 조건에서 그러한지 정확히 밝혀라.

풀이

먼저 배치가 상관없는 경우를 보자. \(\sum_i(\mu_i-\bar\mu)^2\)을 고정하면 어떨까?

import warnings
warnings.filterwarnings("ignore", category=RuntimeWarning)

import numpy as np
from scipy import stats

sigma, n, k = 5.0, 30, 4
crit = stats.f.ppf(0.95, k - 1, k * n - k)

print("① Σ(μ-μ̄)² 를 4 로 고정")
print(f"{'배치':>18s} {'중심화 평균':>30s} {'λ':>8s} {'검정력':>9s}")
for label, raw in [("하나만 높음", [3., 0, 0, 0]),
                   ("둘씩 갈림", [1., 1, -1, -1]),
                   ("고르게 퍼짐", [-1.5, -0.5, 0.5, 1.5]),
                   ("하나만 낮음", [0., 0, 0, -3.])]:
    mu = np.array(raw) - np.mean(raw)
    mu = mu / np.sqrt((mu**2).sum()) * 2.0        # Σ(μ-μ̄)² = 4
    lam = n * (mu**2).sum() / sigma**2
    print(f"{label:>18s} {str(np.round(mu, 3).tolist()):>30s} "
          f"{lam:8.4f} {stats.ncf.sf(crit, k - 1, k * n - k, lam):9.4f}")
① Σ(μ-μ̄)² 를 4 로 고정
                배치                         중심화 평균        λ       검정력
            하나만 높음 [1.732, -0.577, -0.577, -0.577]   4.8000    0.4115
             둘씩 갈림         [1.0, 1.0, -1.0, -1.0]   4.8000    0.4115
            고르게 퍼짐 [-1.342, -0.447, 0.447, 1.342]   4.8000    0.4115
            하나만 낮음  [0.577, 0.577, 0.577, -1.732]   4.8000    0.4115

네 배치의 검정력이 완전히 같다. \(F\) 검정은 평균들을 \(\sum_i(\mu_i-\bar\mu)^2\)이라는 하나의 수로만 본다. 배치의 모양은 전혀 모른다.

그렇다면 "배치에 따라 다르다"는 말은 무슨 뜻인가. 무엇을 고정하느냐에 달려 있다. 실무에서 자연스러운 것은 최댓값과 최솟값의 차이를 고정하는 것이다.

rng = np.random.default_rng(808)
sigma, n, k, R = 5.0, 10, 4, 5.0        # 범위(최대-최소) = 5 로 고정
crit = stats.f.ppf(0.95, k - 1, k * n - k)

print("② 범위(최대-최소)를 5 로 고정")
print(f"{'배치':>18s} {'중심화 평균':>28s} {'Σ(μ-μ̄)²':>10s} {'λ':>7s} "
      f"{'이론':>8s} {'모의':>8s}")
configs = {"하나만 높음": [R, 0., 0, 0],
           "둘씩 갈림": [R, R, 0., 0],
           "고르게 퍼짐": list(np.linspace(0, R, 4)),
           "가운데 둘이 같음": [0., R / 2, R / 2, R]}
for label, raw in configs.items():
    mu = np.array(raw, float)
    mu = mu - mu.mean()
    ss = (mu**2).sum()
    lam = n * ss / sigma**2
    th = stats.ncf.sf(crit, k - 1, k * n - k, lam)
    rej, M = 0, 5_000
    for _ in range(M):
        g = [rng.normal(m, sigma, n) for m in mu]
        rej += stats.f_oneway(*g).pvalue < 0.05
    print(f"{label:>18s} {str(np.round(mu, 2).tolist()):>28s} {ss:10.2f} "
          f"{lam:7.3f} {th:8.4f} {rej / M:8.4f}")
② 범위(최대-최소)를 5 로 고정
                배치                       중심화 평균   Σ(μ-μ̄)²       λ       이론       모의
            하나만 높음  [3.75, -1.25, -1.25, -1.25]      18.75   7.500   0.5711   0.5584
             둘씩 갈림       [2.5, 2.5, -2.5, -2.5]      25.00  10.000   0.7097   0.7056
            고르게 퍼짐     [-2.5, -0.83, 0.83, 2.5]      13.89   5.556   0.4396   0.4492
         가운데 둘이 같음        [-2.5, 0.0, 0.0, 2.5]      12.50   5.000   0.3992   0.4004

이번에는 크게 다르다. 같은 범위 5인데 검정력이 0.399에서 0.710까지 벌어진다.

배치 \(\sum(\mu-\bar\mu)^2\) 검정력
둘씩 갈림 25.00 0.710
하나만 높음 18.75 0.571
고르게 퍼짐 13.89 0.440
가운데 둘이 같음 12.50 0.399

가장 유리한 것은 절반씩 갈리는 배치다. 모든 평균이 극단에 몰려 있어 편차제곱합이 최대가 된다.

가장 불리한 것은 가운데가 비어 있는 배치다. 두 집단이 중앙에 있어 편차에 기여하지 않는다.

정확한 진술은 이렇다.

\(F\) 검정의 검정력은 평균들을 통해 오직 \(\sum_i n_i(\mu_i-\bar\mu)^2\)에만 의존한다. 이 양을 고정하면 배치는 무관하다. 다만 "범위"나 "최대 차이" 같은 다른 양을 고정하면 배치가 이 값을 바꾸므로 검정력이 달라진다.

실무적 함의 셋.

  1. 설계할 때는 \(\sum(\mu_i-\bar\mu)^2\)을 예상해야 한다. "가장 큰 차이"만으로는 부족하다.
  2. "하나만 다를 것 같다"면 \(F\) 검정이 비효율적이다. 대조군 대비 비교(더넷)나 대비검정이 낫다.
  3. \(F\) 검정은 방향을 모르는 옴니버스 검정이다. 구조를 안다면 그 구조에 맞춘 대비가 훨씬 강력하다.

연습문제 10. 분산분석 모의실험을 설계하고 해석하는 지침을 정리하라.

풀이

모의실험을 왜 하는가.

목적 예
이론 확인 비중심 \(F\) 공식이 맞는지(연습문제 6)
가정 위반의 대가 측정 이분산에서 수준이 0.60까지(연습문제 7)
이론이 없는 상황 비정규·군집·결측이 섞인 설계
표본크기 결정 이론 공식이 적용되지 않는 경우
직관 형성 \(\lambda\)의 세 요인이 어떻게 맞물리는지

설계 점검 목록.

  • [ ] 난수 씨앗을 고정했는가(재현성)
  • [ ] 반복 수 \(M\)이 충분한가 — 기각률의 표준오차 \(\sqrt{\alpha(1-\alpha)/M}\)
  • [ ] \(H_0\)가 참인 시나리오를 반드시 포함했는가(수준 확인)
  • [ ] 대립 시나리오가 실무적으로 의미 있는 크기인가
  • [ ] 가정 위반을 한 번에 하나씩 넣었는가
  • [ ] 비교 대상(대안 검정)을 함께 돌렸는가
  • [ ] \(p\) 값 전체를 확인했는가(기각률만이 아니라)

반복 수의 기준.

목적 권장 \(M\) 기각률의 표준오차
대략의 감 1,000 0.0069
보고용 10,000 0.0022
미세한 차이 판정 100,000 0.0007

본문의 \(M=1000\)은 "5%인지 6%인지"를 구분하기에 부족하다. 표준오차가 0.0069이므로 두 값의 차이(0.01)가 오차의 1.4배에 불과하다.

해석에서 자주 하는 실수 넷.

실수 교정
기각률 0.048과 0.052를 다르다고 봄 모의실험 오차를 계산한다
한 시나리오로 일반화 여러 조건을 훑는다
이론이 있는데 모의실험만 함 둘을 대조한다
검정력만 보고 수준을 확인 안 함 수준이 어긋나면 검정력 비교가 무의미

넷째가 가장 중요하다. 연습문제 7에서 고전 \(F\)의 "검정력"이 웰치보다 높게 나오는 상황이 있는데, 수준이 0.60이면 그 검정력은 아무 의미가 없다. 검정력 비교는 수준이 맞는 검정들 사이에서만 뜻이 있다.

이 페이지의 세 가지 발견을 다시 정리하면.

  1. \(\lambda=n\sum(\mu_i-\bar\mu)^2/\sigma^2\) 하나가 검정력을 결정한다. 이론과 모의가 정확히 일치한다(연습문제 6).
  2. 분산과 표본크기가 반대 방향이면 수준이 무너진다. 최악의 경우 0.60(연습문제 7).
  3. 평균의 배치는 \(\sum(\mu_i-\bar\mu)^2\)을 통해서만 작용한다(연습문제 9).

한 문장. 모의실험은 이론이 말하는 것을 확인하고, 이론이 침묵하는 곳에서 답을 얻는 도구다. 둘 중 어느 쪽인지를 아는 것이 설계의 첫걸음이다.


정리하며

\(F\) 검정의 검정력이 무엇에 좌우되는지를 모의실험으로 확인했다.

  • 세 가지가 함께 정한다. 집단 평균의 분리 정도, 집단 내 분산, 표본크기. 이 셋이 비중심모수 \(\lambda=\sum n_i(\mu_i-\bar\mu)^2/\sigma^2\) 하나로 묶인다.
  • \(H_0\) 이 참이면 \(F\) 가 \(F_{k-1,N-k}\) 를 따른다. 모의실험의 히스토그램이 이론 밀도와 맞아떨어지는 것이 검정의 타당성 확인이며, 기각률이 명목 \(\alpha\) 에 맞는지도 함께 본다.
  • \(H_0\) 이 거짓이면 분포가 오른쪽으로 밀린다. 비중심 \(F\) 가 되며, 밀린 정도가 곧 검정력이다.
  • \(\lambda\) 가 \(n\) 에 비례한다. 그래서 표본을 늘리면 검정력이 오르며, 작은 효과를 잡으려면 큰 표본이 필요하다는 4장·9장의 결론이 여기서도 반복된다.
  • 평균이 하나만 동떨어진 경우와 고르게 퍼진 경우가 다르다. 같은 분산이라도 배치에 따라 \(\lambda\) 가 달라지므로 검정력이 달라진다.

다음 절 Fisher 방법을 이용한 분산분석 수동 계산으로 넘어간다.