기각역 시연¶
개요¶
기각역은 \(H_0\)을 기각하게 만드는 검정통계량 값들의 집합이다. 그 모양은 검정이 양측인지, 좌측인지, 우측인지에 따라 달라진다. 이 페이지에서는 세 경우 모두에 대해 \(t\)-분포 위의 기각역을 시각화하며, 원래 측정 단위(cm)와 표준화된 \(t\)-통계량 척도를 함께 보인다.
양측검정¶
유의수준 \(\alpha\)에서 \(H_0\colon \mu = \mu_0\) 대 \(H_1\colon \mu \neq \mu_0\)을 검정할 때, 검정통계량이 어느 쪽 꼬리에든 들어가면 기각한다:
임계값이 \(\alpha\)를 두 꼬리에 반씩 나눈다. 원래 단위로 옮기면 기각역은
보기 1. 기각역과 검정통계량. 평균 170 cm, 표준편차 8 cm인 정규분포에서 키 \(n = 250\)개를 만들어 \(H_0\colon \mu = 172\)를 \(\alpha = 0.05\) 양측으로 검정한다. 표본에서 \(\bar x = 169.9806\), \(s = 7.728430\)이 나왔다.
(1) 표준오차와 임계값을 구해 기각역을 \(t\) 척도와 cm 척도 둘 다로 적고, 검정통계량을 계산해 판정하시오.
(2) cm 척도 기각역의 반너비가 \(n\)에 어떻게 달려 있는지 쓰고, 그 반너비가 2 cm가 되려면 \(n\)이 얼마여야 하는지 구하시오.
풀이
(1) 해석적으로. 표준오차는
이다. 양측이므로 \(\alpha\)를 두 꼬리에 반씩 나누어 \(t_{0.025,\,249} = 1.969537\)을 쓴다. \(t\) 척도의 기각역은
이고, 양변에 \(\text{SE}\)를 곱하고 \(\mu_0\)을 더하면 cm 척도가 된다.
검정통계량은
이다. \(\lvert t \rvert = 4.1314 > 1.9695\)이므로 기각한다. cm 척도로 보아도 \(\bar x = 169.98\)이 왼쪽 경계 \(171.04\)보다 작으니 같은 결론이다. 두 척도는 같은 부등식을 단위만 바꿔 쓴 것이므로 언제나 같은 판정을 준다.
(2) 해석적으로. cm 척도 기각역의 반너비는
이다. \(t_{\alpha/2,\,n-1}\)은 \(n\)이 커지면 \(z_{\alpha/2} = 1.96\)으로 빠르게 수렴하므로, 사실상 \(h(n) \propto 1/\sqrt n\)이다. 표본을 네 배로 늘리면 기각역이 절반으로 좁아진다. \(h = 2\)가 되는 \(n\)은 \(z_{\alpha/2}\)로 어림하면
인데, 이 크기에서는 \(t\)가 아직 \(z\)보다 꽤 크므로 \(t\)로 다시 풀어야 한다. 아래 코드에서 보듯 답은 \(n = 60\)이다.
수치적으로.
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
np.random.seed(42)
data = stats.norm.rvs(loc=170, scale=8, size=250)
mu0 = 172
n = len(data)
df = n - 1
xbar = data.mean()
s = data.std(ddof=1)
se = s / np.sqrt(n)
alpha = 0.05
# 양측이므로 alpha를 두 꼬리에 반씩 나눈다. ppf에 1 - alpha/2를 넣는 이유다.
t_crit = stats.t.ppf(1 - alpha / 2, df)
t_stat = (xbar - mu0) / se
print(f"x-bar = {xbar:.2f}, SE = {se:.2f}")
print(f"t-stat = {t_stat:.4f}, t-crit = +/-{t_crit:.4f}")
# 기각역을 t 척도가 아니라 cm 척도로도 적어 둔다.
# 실무자에게는 "표본평균이 171.04 아래면 기각"이 t보다 읽기 쉽다.
print(f"Rejection boundaries: {mu0 - t_crit*se:.2f} and {mu0 + t_crit*se:.2f}")
print(f"더 정밀하게: x-bar = {xbar:.6f}, s = {s:.6f}, SE = {se:.6f}")
print(f" t = {t_stat:.6f}, 경계 "
f"{mu0 - t_crit * se:.6f} / {mu0 + t_crit * se:.6f}")
print(f" p = {2 * stats.t.sf(abs(t_stat), df):.3e}")
# (2) 반너비가 2 cm 아래로 내려가는 첫 n 을 찾는다.
# **격자에서 argmin/argmax 로 찾지 말 것.** 조건을 만족하는 칸이 하나도
# 없어도 0 을 돌려주므로, 조건을 만족하는 n 이 실제로 있는지부터 확인한다.
ns = np.arange(10, 400)
half = stats.t.ppf(0.975, ns - 1) * s / np.sqrt(ns)
ok = np.flatnonzero(half <= 2.0)
assert ok.size > 0, "반너비가 2 cm 이하가 되는 n 이 격자 안에 없다"
n2 = ns[ok[0]]
print(f"\n반너비 <= 2 cm 인 첫 n = {n2} (반너비 {half[ok[0]]:.4f} cm)"
f" 바로 앞 n = {n2 - 1} 은 {half[ok[0] - 1]:.4f} cm")
print(f"z 어림: n = {(stats.norm.ppf(0.975) * s / 2) ** 2:.1f}")
출력:
x-bar = 169.98, SE = 0.49
t-stat = -4.1314, t-crit = +/-1.9695
Rejection boundaries: 171.04 and 172.96
더 정밀하게: x-bar = 169.980617, s = 7.728430, SE = 0.488789
t = -4.131402, 경계 171.037312 / 172.962688
p = 4.927e-05
반너비 <= 2 cm 인 첫 n = 60 (반너비 1.9965 cm) 바로 앞 n = 59 은 2.0140 cm
z 어림: n = 57.4
(1)에서 손으로 구한 값이 모두 그대로 나왔다. \(\text{SE} = 0.488789\), \(t = -4.131402\), 경계 \(171.037312\)와 \(172.962688\)이 소수점 여섯째 자리까지 일치한다. (2)의 답도 \(n = 60\)이고, \(z\) 어림이 준 \(57.4\)는 세 칸 모자란다.
자료를 평균 170에서 만들었으니 \(H_0\colon \mu = 172\)는 실제로 거짓이고, 검정이 그것을 잡아냈다(\(\lvert t \rvert = 4.13 > 1.97\), \(p = 4.9\times10^{-5}\)).
주목할 것은 기각역의 좁기다. \(n = 250\)이라 표준오차가 \(0.49\) cm밖에 안 되고, 그래서 표본평균이 172에서 0.963 cm만 벗어나도 기각된다. 효과크기로 보면 \(d = 2/7.73 = 0.259\)로 코헨의 기준에서 "작은" 효과인데도 \(p\)가 \(5\times10^{-5}\)다. 표본이 크면 실질적으로 사소한 차이도 통계적으로 유의해진다. 그러므로 \(p\)-값만 보고 "큰 차이"라고 읽으면 안 되고, 효과크기와 신뢰구간을 함께 보아야 한다.
시각화¶
위쪽 그림은 \(H_0\) 아래 \(\bar{X}\)의 표본분포를 센티미터 단위로 보여주며 꼬리의 기각역을 색칠한다. 아래쪽 그림은 같은 검정을 \(t\)-통계량 척도로 보여주며 기각역은 단순히 \(|t| > t_{\text{crit}}\)이다.
보기 2. 기각역 그리기. 보기 1의 검정을 \(t\) 척도에서 그린다. 곡선은 \(H_0\) 아래 \(T\)의 밀도, 붉게 칠한 두 꼬리가 기각역, 파란 점선이 관측된 통계량이다.
(1) 이 그림에서 읽히는 것을 수치와 함께 적으시오.
(2) 이 그림이 가리는 것은 무엇인가. \(p\)-값을 이 그림에서 읽어 낼 수 있는가.
풀이
유도할 답이 있는 문제가 아니다. 그림에서 무엇이 읽히고 무엇이 읽히지 않는가가 이 보기의 전부이므로, 눈으로 본 것을 수치로 바꿔 가며 읽는다.
# 기각역은 자료를 보기 전에 정해지는 영역이다. 관측된 통계량이 칠해진
# 구역 안에 떨어지면 기각한다. p-값 방식과 결론은 언제나 같다.
x_t = np.linspace(-5, 5, 300)
y_t = stats.t.pdf(x_t, df)
# 그림에서 읽을 수치를 미리 찍어 둔다.
print(f"꼭대기 밀도 f(0) = {stats.t.pdf(0, df):.6f}")
print(f"임계값에서의 밀도 f(tc) = {stats.t.pdf(t_crit, df):.6f}")
print(f"관측값에서의 밀도 f(t) = {stats.t.pdf(t_stat, df):.8f}"
f" 꼭대기의 1/{stats.t.pdf(0, df) / stats.t.pdf(t_stat, df):.0f}")
print(f"칠한 꼬리 넓이 (한쪽) = {stats.t.sf(t_crit, df):.6f} (두쪽 합 "
f"{2 * stats.t.sf(t_crit, df):.4f})")
print(f"그림 밖 |t| > 5 의 질량 = {2 * stats.t.sf(5, df):.3e}")
print(f"P(|T| > |t|) = {2 * stats.t.sf(abs(t_stat), df):.3e}"
f" 칠한 왼쪽 꼬리의 {stats.t.cdf(t_stat, df) / stats.t.cdf(-t_crit, df):.4%}")
fig, ax = plt.subplots(figsize=(10, 4))
ax.plot(x_t, y_t, "tomato", lw=2)
ax.fill_between(x_t[x_t <= -t_crit], stats.t.pdf(x_t[x_t <= -t_crit], df),
color="tomato", alpha=0.5, label="Rejection region")
ax.fill_between(x_t[x_t >= t_crit], stats.t.pdf(x_t[x_t >= t_crit], df),
color="tomato", alpha=0.5)
ax.axvline(t_stat, color="blue", linestyle="--", label=f"t = {t_stat:.2f}")
ax.set_xlabel("t")
ax.set_ylabel("Density")
ax.legend()
plt.tight_layout()
plt.show()
출력:
꼭대기 밀도 f(0) = 0.398542
임계값에서의 밀도 f(tc) = 0.057714
관측값에서의 밀도 f(t) = 0.00010028 꼭대기의 1/3974
칠한 꼬리 넓이 (한쪽) = 0.025000 (두쪽 합 0.0500)
그림 밖 |t| > 5 의 질량 = 1.082e-06
P(|T| > |t|) = 4.927e-05 칠한 왼쪽 꼬리의 0.0985%

(1) 읽히는 것. 종 모양 곡선이 0에 봉우리를 두고 좌우대칭이다. 꼭대기 밀도가 \(0.398542\)로 표준정규의 \(0.398942\)와 거의 같은데, 자유도가 249라 \(t\)가 이미 정규에 매우 가깝기 때문이다. 붉게 칠한 두 꼬리는 \(\lvert t \rvert > 1.9695\)이고 넓이가 각각 \(0.025\), 합이 정확히 \(\alpha = 0.05\)다. 색칠된 넓이가 유의수준 그 자체라는 것이 이 그림이 가르치려는 바다.
파란 점선이 \(t = -4.13\)에 서 있고 왼쪽 기각역 안에 확실히 들어가 있다. 그러므로 기각이다. 점선 자리의 밀도는 \(0.00010\)으로 꼭대기의 \(1/3974\)이라, 곡선이 이 근처에서는 바닥에 눌려 보인다.
(2) 가리는 것 — 얼마나 깊이 들어갔는가. 그림만 보면 점선이 경계 \(-1.97\)보다 왼쪽에 있다는 것까지는 알 수 있지만, 그것이 "조금" 넘은 것인지 "한참" 넘은 것인지는 읽을 수 없다. 수로 보면 점선 왼쪽의 넓이는 \(2.46\times10^{-5}\)로 칠해진 왼쪽 꼬리 전체 \(0.025\)의 \(0.0985\%\), 곧 천분의 일이다. 선형 세로축에서는 이 넓이가 한 화소도 되지 않으므로 그림에서 \(p\)-값을 읽어 낼 길이 없다. \(p\)-값은 수로 보고해야 하고, 이런 그림은 판정의 논리를 보일 뿐 증거의 세기를 보이지 못한다.
가로 범위도 자의적이다. \(x\)를 \([-5, 5]\)로 잘랐는데 이 바깥의 질량은 \(1.08\times10^{-6}\)뿐이라 분포를 자르는 데에는 문제가 없다. 그러나 관측값이 \(t = -6\)이었다면 점선이 그림 밖으로 나가 아예 보이지 않았을 것이다. 통계량이 강할수록 그림이 못 쓰게 되는 셈이다.
\(H_1\)이 없다. 이 그림에는 \(H_0\) 아래의 분포 하나뿐이다. 그래서 2종 오류도 검정력도 여기서는 보이지 않는다. 그 둘을 보려면 \(H_1\) 아래의 분포를 겹쳐 그려야 하며, 9.2절의 두 분포 그림이 그 일을 한다.
끝으로, 이 그림은 \(t\) 척도라 자유도만 알면 자료와 무관하게 언제나 같은 모양이다. 자료가 하는 일은 파란 점선을 어디에 놓을지 정하는 것뿐이다. 거꾸로 말하면 cm 같은 실제 단위의 감각은 이 그림에서 완전히 사라진다. 보기 1에서 cm 척도 경계를 따로 적어 둔 이유가 그것이다.
단측검정¶
좌측검정¶
\(H_0\colon \mu = \mu_0\) 대 \(H_1\colon \mu < \mu_0\)에서는 기각역 전체가 왼쪽 꼬리에 있다:
우측검정¶
\(H_0\colon \mu = \mu_0\) 대 \(H_1\colon \mu > \mu_0\)에서는 기각역이 오른쪽 꼬리에 있다:
보기 3. 기각값 구하기. \(\text{df} = 100\), \(\alpha = 0.05\)에서 좌측·우측·양측 임계값을 본다.
(1) \(t\) 분포의 대칭성에서 \(t_{\alpha,\,\text{df}} = -t_{1-\alpha,\,\text{df}}\)를 보이고, 세 임계값을 구하시오.
(2) 단측검정의 임계값이 더 안쪽에 있으니 검정력이 크다. 비중심모수 \(\lambda = 2\)인 대립가설에서 그 이득이 얼마이고, \(\lambda = -3\)처럼 방향이 반대인 대립가설에서 그 대가가 얼마인지 수로 답하시오.
풀이
(1) 해석적으로. 밀도가 0에 대해 대칭이므로 누적분포함수가 \(F(-x) = 1 - F(x)\)를 만족한다. 정의상 \(F(t_{1-\alpha}) = 1-\alpha\)이므로
이고, \(F\)가 순증가라 \(\alpha\)를 주는 점은 하나뿐이다. 따라서 \(t_{\alpha} = -t_{1-\alpha}\)다.
단측이므로 \(\alpha\)를 나누지 않고 꼬리 하나에 5%를 통째로 준다. \(\text{df} = 100\)에서
이고, 같은 자유도의 양측 임계값은 \(\alpha\)를 반씩 나누므로
이다. \(1.6602 < 1.9840\)이라 단측 쪽 문턱이 더 낮다.
(2) 해석적으로. \(H_1\) 아래에서 \(T\)는 비중심모수 \(\lambda\)인 비중심 \(t\)를 따른다. 우측검정의 검정력은 \(P(T'_{100,\lambda} > 1.6602)\) 하나이고, 양측검정은 \(P(T'_{100,\lambda} > 1.9840) + P(T'_{100,\lambda} < -1.9840)\)이다. 문턱이 낮다는 것만으로 우측검정이 유리해지는 것은 \(\lambda > 0\)일 때뿐이고, \(\lambda < 0\)이면 우측검정의 검정력이 \(\alpha\)보다도 작아진다.
수치적으로.
df = 100
alpha = 0.05
x = np.linspace(-5, 5, 300)
y = stats.t.pdf(x, df)
# 단측이므로 alpha를 나누지 않는다. 꼬리 하나에 5%를 통째로 준다.
t_lo = stats.t.ppf(alpha, df)
print(f"Left-tailed critical value: {t_lo:.4f}")
t_hi = stats.t.ppf(1 - alpha, df)
print(f"Right-tailed critical value: {t_hi:.4f}")
t_two = stats.t.ppf(1 - alpha / 2, df)
print(f"Two-tailed critical value : +/-{t_two:.4f}")
print(f"대칭성 확인: t_lo + t_hi = {t_lo + t_hi:.1e}")
def power_one(lam): # 우측 단측검정
return stats.nct.sf(t_hi, df, lam)
def power_two(lam): # 양측검정
return stats.nct.sf(t_two, df, lam) + stats.nct.cdf(-t_two, df, lam)
print(f"\n{'lambda':>7} {'우측 단측':>10} {'양측':>8} {'차이':>9}")
for lam in (-3.0, -1.0, 0.0, 1.0, 2.0, 3.0):
p1, p2 = power_one(lam), power_two(lam)
print(f"{lam:>7.1f} {p1:>10.4f} {p2:>8.4f} {p1 - p2:>+9.4f}")
출력:
Left-tailed critical value: -1.6602
Right-tailed critical value: 1.6602
Two-tailed critical value : +/-1.9840
대칭성 확인: t_lo + t_hi = -6.7e-16
lambda 우측 단측 양측 차이
-3.0 0.0000 0.8440 -0.8440
-1.0 0.0042 0.1677 -0.1636
0.0 0.0500 0.0500 -0.0000
1.0 0.2573 0.1677 +0.0896
2.0 0.6337 0.5083 +0.1253
3.0 0.9090 0.8440 +0.0650
\(t_{0.05,100} + t_{0.95,100}\)이 \(-6.7\\times10^{-16}\)으로 부동소수점 반올림 한 단위에 지나지 않아 (1)의 대칭성이 확인된다.
이득. \(\lambda = 2\)에서 우측 단측검정의 검정력은 \(0.6337\), 양측검정은 \(0.5083\)이다. 차이가 \(0.1253\), 곧 12.5%포인트다. \(\lambda = 1\)에서는 \(0.0896\), \(\lambda = 3\)에서는 \(0.0650\)으로, 이득은 중간 세기의 효과에서 가장 크다. 효과가 아주 크면 둘 다 거의 1이라 차이가 사라지기 때문이다.
대가. \(\lambda = -3\)에서 양측검정의 검정력은 \(0.8440\)인데 우측 단측검정은 \(1.9\times10^{-6}\)이다. 사실상 0이다. 실제로 존재하는 큰 효과를 방향이 반대라는 이유만으로 통째로 놓친다. \(\lambda = 0\), 곧 \(H_0\)이 참일 때는 두 검정 모두 정확히 \(0.05\)를 주므로 1종 오류율에는 차이가 없다.
그러므로 단측검정은 반대 방향의 효과가 나와도 아무 조치를 하지 않을 때에만 정당하다. 그 판단은 자료를 보기 전에 끝나 있어야 한다.
해석¶
- 양측검정에서는 어느 방향에서든 \(H_0\)에 반하는 증거가 나올 수 있다. p-값은 \(2P(T \geq |t_{\text{obs}}|)\)이다.
- 단측검정에서는 한쪽 방향의 이탈만 보므로 그 방향의 효과를 탐지할 검정력은 커지지만 반대 방향에는 전혀 없다.
- 원래 단위의 기각역은 기각으로 이어지는 실제 측정값(예: cm 단위의 키)을 보여준다. 실무자에게는 \(t\)-통계량 척도보다 직관적인 경우가 많다.
- \(\alpha\)를 0.05에서 0.01로 낮추면 기각역이 줄어들고(임계값이 바깥으로 이동하고) \(H_0\)을 기각하는 데 더 강한 증거가 필요해진다.
연습문제¶
연습문제 1. \(n = 25\), \(\alpha = 0.05\), \(\mu_0 = 100\)인 양측검정에서 \(s = 15\)일 때 임계값을 \(t\) 단위와 원래 단위로 계산하라.
풀이
자유도: \(\text{df} = 24\). 임계 \(t\)-값은
표준오차는 \(SE = 15/\sqrt{25} = 3.0\)이다. 원래 단위의 기각 경계는
이므로 기각역은 \(\bar{x} < 93.81\) 또는 \(\bar{x} > 106.19\)이다. \(\square\)
연습문제 2. 참 효과가 가설의 방향에 있을 때 단측검정이 양측검정보다 강력한 이유를 설명하라. 그 대가는 무엇인가?
풀이
수준 \(\alpha\)의 단측검정에서는 기각확률 전체가 한쪽 꼬리에 몰리므로 임계값이 \(t_{\alpha/2}\)가 아니라 \(t_\alpha\)이다. \(t_\alpha < t_{\alpha/2}\)이므로 임계값을 넘기가 쉬워져 검정력이 커진다.
수치로 보면 \(n\)이 큰 \(\alpha = 0.05\)에서 단측 임계값은 \(z_{0.05} = 1.645\)이고 양측은 \(z_{0.025} = 1.960\)이다. 1.645와 1.960 사이의 검정통계량은 단측검정에서는 기각되지만 양측검정에서는 기각되지 않는다.
대가는 단측검정이 반대 방향의 효과에 대해 검정력이 0이라는 점이다. 양의 효과를 검정하는데 참 효과가 음수이면 그 효과가 아무리 커도 결코 \(H_0\)을 기각할 수 없다. \(\square\)
연습문제 3. (대칭인 분포에서) 양측검정의 p-값이 단측 p-값의 두 배임을 보여라. 이 관계가 깨질 수 있는 경우는?
풀이
(\(t\)-분포처럼) 대칭인 분포에서는 \(P(T \leq -|t|) = P(T \geq |t|)\)이다. 양측 p-값은
이 관계는 다음의 경우 깨진다:
- 검정통계량의 귀무분포가 비대칭일 때(예: 카이제곱, \(F\)-분포).
- 대응하는 분위수에서 두 꼬리의 확률질량이 같지 않을 수 있는 이산분포에 기반한 검정일 때. \(\square\)
연습문제 4. 어떤 연구자가 \(H_0\colon \mu = 50\)을 \(H_1\colon \mu > 50\)에 대해 검정하여 \(\text{df} = 29\)에서 \(t = 1.80\)을 얻었다. p-값을 구하고 \(\alpha = 0.05\)에서 판정하라.
풀이
우측검정의 p-값은
Python으로 1 - stats.t.cdf(1.80, 29)를 계산하면 \(\approx 0.0411\)이다.
\(0.0411 < 0.05\)이므로 \(H_0\)을 기각하고 5% 수준에서 \(\mu > 50\)이라는 유의한 증거가 있다고 결론짓는다. \(\square\)
연습문제 5. \(\alpha\)가 0.10에서 0.01로 줄어들 때 양측 기각역이 어떻게 변하는지 그리거나 기술하라. 제2종 오류의 확률은 어떻게 되는가?
풀이
\(\alpha\)가 줄어들면:
- 임계값 \(\pm t_{\alpha/2}\)가 0에서 더 멀어진다(예: \(n\)이 클 때 \(\alpha=0.10\)의 \(\pm 1.645\)에서 \(\alpha=0.01\)의 \(\pm 2.576\)으로).
- 각 꼬리의 색칠된 기각역이 줄어든다.
- \(H_0\)을 기각하기 어려워지므로 제1종 오류의 확률이 줄어든다.
그러나 제2종 오류의 확률(\(\beta\))은 커진다. 문턱이 엄격해지면 \(H_1\)이 참이어도 \(H_0\)을 기각하지 못할 가능성이 커진다. 검정력 \(= 1 - \beta\)가 줄어든다. 근본적인 맞바꿈을 보여준다: 표본크기를 함께 늘리지 않는 한 한쪽 오류를 줄이면 다른 쪽이 커진다. \(\square\)
연습문제 6. 기각역의 모양이 어디서 오는지 설명하라. 왜 평균 검정에서는 \(|t|>c\)이고 분산 검정에서는 양쪽 꼬리가 비대칭인가?
풀이
원리 — 기각역은 가능도비가 큰 쪽부터 채운다. 네이만-피어슨의 논리를 복합 대립가설로 확장하면, 기각역은
형태가 된다. 이 부등식을 통계량에 대해 풀면 모양이 나온다.
평균 검정 — 대칭. 정규 \(N(\mu,\sigma^2)\)에서 \(H_0:\mu=\mu_0\), \(H_1:\mu\ne\mu_0\)이면 우도비가
로 \(t^2\)의 증가함수다. 따라서 \(\Lambda\)가 작다는 것은 \(|t|\)가 크다는 것이고, 기각역이 \(|t|>c\)다. \(t\) 분포가 0에 대해 대칭이므로 양쪽 임계값의 절댓값이 같다.
분산 검정 — 비대칭. \(H_0:\sigma^2=\sigma_0^2\)에서 \(W=(n-1)S^2/\sigma_0^2\sim\chi^2_{n-1}\)인데, 카이제곱 분포가 비대칭이다. 동등꼬리 기각역
는 양쪽 꼬리 확률을 각각 0.025로 맞춘 것이지, 밀도의 높이를 맞춘 것이 아니다.
import numpy as np
from scipy import stats
for nu in [5, 10, 20, 50]:
lo = stats.chi2.ppf(0.025, nu)
hi = stats.chi2.ppf(0.975, nu)
print(f"ν = {nu:3d}: ({lo:7.3f}, {hi:7.3f}) "
f"중심 {nu}에서의 거리 {nu - lo:6.3f} / {hi - nu:6.3f} "
f"밀도 {stats.chi2.pdf(lo, nu):.5f} / {stats.chi2.pdf(hi, nu):.5f}")
ν = 5: ( 0.831, 12.833) 거리 4.169 / 7.833 밀도 0.06651 / 0.00999
ν = 10: ( 3.247, 20.483) 거리 6.753 / 10.483 밀도 0.02854 / 0.00817
ν = 20: ( 9.591, 34.170) 거리 10.409 / 14.170 밀도 0.01528 / 0.00650
ν = 50: ( 32.357, 71.420) 거리 17.643 / 21.420 밀도 0.00784 / 0.00462
경계에서 밀도가 다르다. \(\nu=5\)에서 왼쪽 임계점의 밀도가 오른쪽의 6.7배다. 이는 동등꼬리 구성이 최단 기각역이 아님을 뜻한다.
최단 기각역을 원한다면 양쪽 경계에서 밀도가 같도록 잡아야 한다. 그러면 꼬리 확률이 0.025씩이 아니게 되고, 대신 기각역의 길이가 최소가 된다.
왜 그래도 동등꼬리를 쓰는가.
- 단측 결론이 명확하다. "\(\sigma^2\)이 너무 크다"와 "너무 작다"를 각각 2.5%로 통제한다.
- 신뢰구간과의 쌍대성이 깔끔하다.
- 계산과 소통이 쉽다.
일반 규칙. 기각역의 모양은 검정통계량의 \(H_0\) 아래 분포가 결정한다. 대칭이면 대칭, 치우쳤으면 비대칭이다. 밀도의 비가 \(\nu=5\)의 6.7배에서 \(\nu=50\)의 1.7배로 줄어드는 것은 카이제곱이 정규에 가까워지기 때문이며, \(\nu\to\infty\)에서 1로 간다.
연습문제 7. 이산분포에서 기각역을 어떻게 정하는가? 무작위화 검정의 정의와, 실무에서 쓰지 않는 이유를 밝혀라.
풀이
문제. 앞서 본 대로 이항에서 \(\{X\ge15\}\)는 \(\alpha=0.0207\), \(\{X\ge14\}\)는 \(0.0577\)이다. 정확히 0.05인 기각역이 없다.
무작위화 검정. 경계값에서 확률 \(\gamma\)로 기각한다.
\(\gamma\)는 수준이 정확히 \(\alpha\)가 되도록 정한다.
import numpy as np
from scipy import stats
n, p0, alpha = 20, 0.5, 0.05
a_hi = stats.binom.sf(14, n, p0) # P(X ≥ 15)
pmf14 = stats.binom.pmf(14, n, p0)
gamma = (alpha - a_hi) / pmf14
print(f"P(X ≥ 15) = {a_hi:.5f}")
print(f"P(X = 14) = {pmf14:.5f}")
print(f"γ = {gamma:.4f} → 수준 {a_hi + gamma * pmf14:.5f}")
# 검정력 비교
for p1 in [0.6, 0.7, 0.8]:
pw0 = stats.binom.sf(14, n, p1)
pw1 = pw0 + gamma * stats.binom.pmf(14, n, p1)
print(f"p1 = {p1}: 비무작위화 {pw0:.4f} 무작위화 {pw1:.4f}")
P(X ≥ 15) = 0.02069
P(X = 14) = 0.03696
γ = 0.7928 → 수준 0.05000
p1 = 0.6: 비무작위화 0.1256 무작위화 0.2242
p1 = 0.7: 비무작위화 0.4164 무작위화 0.5683
p1 = 0.8: 비무작위화 0.8042 무작위화 0.8907
수준이 정확히 0.05가 되고 검정력이 크게 오른다. \(p_1=0.7\)에서 0.416에서 0.568로 36% 개선이다.
이론적으로는 최적이다. 네이만-피어슨 보조정리의 엄밀한 진술에는 이 무작위화가 들어 있으며, 무작위화 검정이 진짜 UMP 검정이다.
그런데 실무에서 쓰지 않는다. 왜인가.
-
같은 자료가 다른 결론을 준다. \(X=14\)를 관측하면 동전을 던져 결론을 정하는 셈이다. 재현 불가능하고, 두 연구자가 다른 답을 낸다.
-
설명할 수 없다. "당신의 약은 효과가 있습니다. 동전이 앞면이 나왔거든요"는 받아들여지지 않는다.
-
자료 외의 정보를 쓴다. 결론이 자료가 아니라 난수에 의존하는 것이 조건부성 원리에 어긋난다.
-
이득이 크지 않은 경우가 많다. \(n\)이 크면 이산성의 영향이 작아진다.
대신 쓰는 것.
| 방법 | 성격 |
|---|---|
| 보수적 검정 | 실제 수준이 낮은 것을 감수 |
| 중간-\(p\) | 무작위화의 "기댓값" 판. 재현 가능 |
| \(n\) 늘리기 | 근본적 해결 |
중간-\(p\)가 실질적인 답이다. 위 예에서 \(\gamma=0.793\) 대신 \(\gamma=0.5\)를 쓰는 것에 해당하며, 무작위화 없이 보수성의 상당 부분을 회복한다.
연습문제 8. 모수가 둘 이상이면 기각역이 영역이 된다. 타원형 기각역과 직사각형 기각역을 비교하라.
풀이
상황. \(H_0:\boldsymbol\mu=\mathbf0\)을 검정한다. 두 가지 기각역을 비교한다.
- 타원(호텔링 \(T^2\) 계열): \(\mathbf x^\top\Sigma^{-1}\mathbf x>\chi^2_{p,0.95}\)
- 직사각형(개별 검정 + 본페로니): 어느 좌표든 \(|x_j|>z_{1-\alpha/(2p)}\)
import numpy as np
from scipy import stats
rng = np.random.default_rng(3)
M, p = 40_000, 2
z = stats.norm.ppf(1 - 0.05 / (2 * p))
crit = stats.chi2.ppf(0.95, p)
print(f"{'ρ':>5s} {'타원 수준':>10s} {'본페 수준':>10s} "
f"{'타원 검정력':>12s} {'본페 검정력':>12s}")
for rho in [0.0, 0.5, 0.9]:
S = np.array([[1, rho], [rho, 1]])
L = np.linalg.cholesky(S)
Si = np.linalg.inv(S)
out = {}
for d in [np.zeros(2), np.array([2.0, 0.0])]:
x = rng.standard_normal((M, p)) @ L.T + d
ell = np.einsum("ij,jk,ik->i", x, Si, x) > crit
box = (np.abs(x) > z).any(1)
out[d[0]] = (ell.mean(), box.mean())
print(f"{rho:5.1f} {out[0.0][0]:10.4f} {out[0.0][1]:10.4f} "
f"{out[2.0][0]:12.4f} {out[2.0][1]:12.4f}")
ρ 타원 수준 본페 수준 타원 검정력 본페 검정력
0.0 0.0497 0.0485 0.4197 0.4253
0.5 0.0499 0.0464 0.5329 0.4175
0.9 0.0511 0.0366 0.9895 0.4144
타원은 상관과 무관하게 정확히 0.05다. \(\Sigma^{-1}\)이 상관을 자동으로 보정한다.
본페로니는 상관이 커질수록 보수적이 된다. \(\rho=0.9\)에서 실제 수준이 0.037이다. 두 검정이 거의 같은 사건이 되어 "둘 중 하나라도"의 이득이 사라지기 때문이다.
상관이 크면 타원이 압도적이다. \(\rho=0.9\)에서 0.990 대 0.414다. \((2,0)\) 방향의 이동은 두 좌표가 함께 움직인다는 \(H_0\)의 구조를 정면으로 위배하므로 마할라노비스 거리가 매우 커진다. 직사각형은 이 정보를 전혀 쓰지 못한다.
그렇다면 직사각형은 언제 유리한가 — 차원이 높고 효과가 희박할 때.
rng = np.random.default_rng(5)
print(f"{'p':>4s} {'타원 검정력':>12s} {'본페 검정력':>12s}")
for p in [2, 5, 10, 20]:
z = stats.norm.ppf(1 - 0.05 / (2 * p))
crit = stats.chi2.ppf(0.95, p)
d = np.zeros(p)
d[0] = 3.0 # 한 좌표만 이동, 상관 없음
x = rng.standard_normal((M, p)) + d
print(f"{p:4d} {np.mean((x**2).sum(1) > crit):12.4f} "
f"{np.mean((np.abs(x) > z).any(1)):12.4f}")
p 타원 검정력 본페 검정력
2 0.7703 0.7808
5 0.6281 0.6799
10 0.4931 0.5925
20 0.3560 0.5144
\(p\)가 커질수록 직사각형이 앞선다. \(p=20\)에서 0.514 대 0.356이다. 타원은 모든 방향의 잡음을 다 더하므로, 신호가 한 좌표에만 있으면 그것이 희석된다.
정리 — 기각역의 모양은 대립의 모양에 맞춘다.
| 대립의 성격 | 유리한 기각역 |
|---|---|
| 상관 구조를 위배하는 이동 | 타원 |
| 모든 좌표에 고르게 퍼진 효과 | 타원 |
| 소수 좌표에만 큰 효과(희박) | 직사각형/최댓값 |
| 방향이 예상됨 | 대비(1차원 투영) |
실무 권고. 직사각형은 어느 모수가 문제인지 바로 알 수 있다는 해석상의 장점도 크다. 타원이 기각되어도 원인을 알려면 사후 분석이 필요하다. \(p\)가 \(n\)에 가까우면 \(\Sigma\) 추정이 불안정해 타원 자체를 쓸 수 없다는 점도 고려한다.
연습문제 9. 편향된 검정이란 무엇인가? 카이제곱 분산검정이 편향됨을 보이고, 그 의미를 설명하라.
풀이
정의. 검정이 불편이라는 것은
즉 대립가설 아래의 기각확률이 언제나 \(\alpha\) 이상이라는 뜻이다. 그렇지 않으면 편향이다. 편향된 검정은 "참일 때보다 거짓일 때 덜 기각하는" 구간이 있어 비상식적이다.
import numpy as np
from scipy import stats
n = 10
nu = n - 1
lo = stats.chi2.ppf(0.025, nu)
hi = stats.chi2.ppf(0.975, nu)
print(f"기각역: W < {lo:.3f} 또는 W > {hi:.3f}")
print(f"{'σ²/σ0²':>8s} {'검정력':>10s}")
for r in [0.5, 0.7, 0.9, 0.95, 1.0, 1.05, 1.1, 1.3, 2.0]:
pw = stats.chi2.cdf(lo / r, nu) + stats.chi2.sf(hi / r, nu)
mark = " ← α 미만" if pw < 0.05 else ""
print(f"{r:8.2f} {pw:10.4f}{mark}")
기각역: W < 2.700 또는 W > 19.023
σ²/σ0² 검정력
0.50 0.2020
0.70 0.0808
0.90 0.0478 ← α 미만
0.95 0.0476 ← α 미만
1.00 0.0500
1.05 0.0550
1.10 0.0622
1.30 0.1113
2.00 0.3934
\(\sigma^2/\sigma_0^2=0.90\)과 \(0.95\)에서 검정력이 0.048 미만으로 \(\alpha=0.05\)보다 작다. \(H_0\)이 거짓인데도 참일 때보다 덜 기각한다. 편향이다.
왜 생기는가. 동등꼬리 기각역이 \(W\)의 분포가 비대칭이라는 사실을 반영하지 못한다. \(\sigma^2\)이 조금 작아지면 \(W\)의 분포가 왼쪽으로 이동하는데, 왼쪽 꼬리에서 얻는 기각확률보다 오른쪽 꼬리에서 잃는 것이 더 크다.
불편 검정으로 고치려면 임계값 \((a,b)\)를 다음 두 조건으로 정한다.
둘째 조건이 검정력함수가 \(\sigma_0^2\)에서 최소가 되게 만든다. 계산하면 \(a\,f(a)=b\,f(b)\) 꼴의 조건이 나오며, 앞 문제에서 본 "양 경계의 밀도를 맞추는" 구성과 닮았다.
실무적 의미.
-
편향의 크기가 작다. 위 표에서 0.0476 대 0.05로 0.24%포인트 차이다. 실무적으로는 무시할 만하다.
-
\(n\)이 커지면 사라진다. 카이제곱이 정규에 가까워지면서 비대칭이 줄기 때문이다.
-
그래도 개념적으로 중요하다. "최적 검정"을 정의하려면 무엇을 최적화할지 정해야 하는데, 불편성이 그 제약 중 하나다. 양측 대립에서 UMP가 없을 때 "일양최강력 불편(UMPU) 검정"을 찾는 것이 표준적인 길이다.
-
\(t\) 검정은 불편이다. 대칭 덕에 이런 문제가 없다. 실제로 양측 \(t\) 검정이 UMPU임이 알려져 있다.
연습문제 10. 기각역과 신뢰구간의 쌍대성을 그림으로 설명하고, 신뢰구간에서 기각역을 읽는 법을 정리하라.
풀이
두 관점.
- 기각역: \(\theta_0\)를 고정하고, 어떤 자료가 기각을 낳는지 본다. 표본공간의 부분집합이다.
- 신뢰구간: 자료를 고정하고, 어떤 \(\theta_0\) 가 기각되지 않는지 본다. 모수공간의 부분집합이다.
둘은 같은 집합의 두 단면이다. \((\mathbf x,\theta_0)\) 평면에서 "기각하지 않음" 영역을
로 두면, \(\theta_0\)를 고정한 가로 단면이 수용역이고 \(\mathbf x\)를 고정한 세로 단면이 신뢰구간이다.
import numpy as np
from scipy import stats
n, s, alpha = 25, 15.0, 0.05
t = stats.t.ppf(1 - alpha / 2, n - 1)
se = s / np.sqrt(n)
print("가로 단면 — μ0 를 고정했을 때의 수용역 (x̄ 의 범위)")
for mu0 in [95, 100, 105]:
print(f" μ0 = {mu0:3d}: ({mu0 - t * se:.3f}, {mu0 + t * se:.3f})")
print("\n세로 단면 — x̄ 를 고정했을 때의 신뢰구간 (μ 의 범위)")
for xbar in [98, 102, 107]:
print(f" x̄ = {xbar:3d}: ({xbar - t * se:.3f}, {xbar + t * se:.3f})")
print("\n쌍대성 확인")
for mu0, xbar in [(100, 105), (100, 107), (105, 107)]:
in_ci = abs(xbar - mu0) <= t * se
print(f" μ0={mu0}, x̄={xbar}: 구간에 {'포함' if in_ci else '미포함'}, "
f"검정은 {'비기각' if in_ci else '기각'}")
가로 단면 — μ0 를 고정했을 때의 수용역 (x̄ 의 범위)
μ0 = 95: (88.808, 101.192)
μ0 = 100: (93.808, 106.192)
μ0 = 105: (98.808, 111.192)
세로 단면 — x̄ 를 고정했을 때의 신뢰구간 (μ 의 범위)
x̄ = 98: (91.808, 104.192)
x̄ = 102: (95.808, 108.192)
x̄ = 107: (100.808, 113.192)
쌍대성 확인
μ0=100, x̄=105: 구간에 포함, 검정은 비기각
μ0=100, x̄=107: 구간에 미포함, 검정은 기각
μ0=105, x̄=107: 구간에 포함, 검정은 비기각
띠 모양. 수용역의 집합 \(A\)는 \((\bar x,\mu_0)\) 평면에서 기울기 1의 대각 띠다. 폭이 \(2t\,s/\sqrt n\)으로 일정하다. 가로로 자르면 수용역, 세로로 자르면 신뢰구간이 나온다.
신뢰구간에서 읽을 수 있는 것.
| 읽는 법 | 얻는 것 |
|---|---|
| 구간이 \(\theta_0\)를 담는가 | \(H_0:\theta=\theta_0\)의 기각 여부 |
| 구간이 0을 담는가 | "효과 없음"의 기각 여부 |
| 구간의 폭 | 검정의 정밀도(간접적으로 검정력) |
| \(\theta_0\)가 경계에 얼마나 가까운가 | \(p\)-값의 대략적 크기 |
| 구간이 실무적 문턱을 담는가 | 실무적 중요성 |
\(p\)-값까지 읽기. 대칭 구간이라면
로 근사할 수 있다. 구간의 반폭이 \(z\) 배의 표준오차이기 때문이다.
왜 구간이 더 유익한가. 검정은 하나의 \(\theta_0\)에 대한 답이지만, 구간은 모든 \(\theta_0\)에 대한 답을 한꺼번에 준다. 정보량이 비교가 안 된다. 이것이 "검정보다 구간을 보고하라"는 권고의 근거다.
정리하며¶
기각역은 \(H_0\) 을 기각하게 만드는 통계량 값들의 집합이며, 모양이 대립가설에서 나온다.
| 대립가설 | 기각역 | \(\alpha\) 배분 |
|---|---|---|
| \(\mu\ne\mu_0\) | 양쪽 꼬리 | \(\alpha/2\) 씩 |
| \(\mu>\mu_0\) | 오른쪽 꼬리 | 한쪽에 \(\alpha\) 전부 |
| \(\mu<\mu_0\) | 왼쪽 꼬리 | 한쪽에 \(\alpha\) 전부 |
- 양측검정은 임계값이 더 멀다. 같은 \(\alpha\) 를 둘로 나누기 때문이며, 그래서 단측검정이 해당 방향에서 검정력이 높다.
- 그렇다고 자료를 보고 단측으로 바꾸면 안 된다. 실질적인 \(\alpha\) 가 두 배가 되며, 방향은 사전에 정해야 한다.
- 두 척도가 같은 것을 말한다. 원래 단위(cm)의 기각역과 표준화된 \(t\) 척도의 기각역은 같은 경계를 다르게 적은 것이다. 그림에서 두 축을 함께 보면 그 대응이 드러난다.
- 기각역의 경계가 곧 \(p=\alpha\) 인 지점이므로, 임계값 방식과 \(p\) 값 방식이 언제나 같은 판정을 준다.
다음 절부터 일표본 검정을 하나씩 다룬다. \(\sigma\) 를 아는 \(z\) 검정에서 시작한다.