[CS300 #016] 통계적 추정과 가설 검정 — 표본으로 전체를 말하는 법
컴퓨터공학 300 주제 시리즈의 016번째 글이다. 전체 지도는 여기.
한 줄 요약
추정은 표본에서 모집단의 값(평균, 비율)을 짐작하고 그 불확실성을 신뢰구간으로 표현하는 일이다. 가설 검정은 “차이가 없다” 는 가정 아래에서 지금 본 데이터가 얼마나 드문지(p-값)를 계산해, 관측된 차이가 우연인지 판단하는 절차다.
왜 필요한가
“새 버전 배포 후 p95 응답 시간이 210ms 에서 225ms 가 됐다. 성능이 나빠졌나?” 측정값은 매번 흔들린다. 15ms 차이가 진짜 회귀인지, 그냥 측정 잡음인지 구분하지 못하면 멀쩡한 배포를 롤백하거나 진짜 회귀를 놓친다.
A/B 테스트, 벤치마크 비교, 용량 추정, 장애율 추정이 모두 같은 질문이다. “표본 몇 개로 전체에 대해 무엇을, 얼마나 확신하며 말할 수 있는가?” 통계적 추정과 검정은 이 질문에 답하는 표준 언어다.
핵심 개념
모집단, 표본, 추정량
- 모집단: 관심 대상 전체. 예: 이 서비스가 처리할 모든 요청의 응답 시간.
- 모수: 모집단의 특성값. 예: 진짜 평균 μ. 보통 알 수 없다.
- 표본: 실제로 측정한 일부. 예: 어제 측정한 요청 1,000 건.
- 추정량: 표본으로 모수를 짐작하는 식. 예: 표본 평균 x̄.
표본 평균은 모집단 평균의 불편 추정량이다. 즉 E[x̄] = μ 다. 표본 분산은 n 이 아니라 n−1 로 나눠야 불편 추정량이 된다. 파이썬 statistics.variance 는 n−1, statistics.pvariance 는 n 으로 나눈다.
표준오차
표본 평균도 확률변수다. 표본을 다시 뽑으면 값이 달라진다. 그 흔들림의 크기가 표준오차다.
SE(x̄) = σ / √n (σ 를 모르면 표본 표준편차 s 로 대신한다)
표본을 4 배 늘려야 표준오차가 절반이 된다. 측정을 조금 더 하는 것으로는 정밀도가 잘 안 오르는 이유다.
신뢰구간
중심극한정리(015번 글)에 따라 n 이 충분히 크면 x̄ 는 근사적으로 N(μ, σ²/n) 을 따른다. 그래서 μ 의 95% 신뢰구간은 근사적으로
x̄ ± 1.96 × s/√n
해석에 주의. “μ 가 이 구간에 있을 확률이 95%” 가 아니다. μ 는 고정된 값이고, 흔들리는 것은 구간이다. 정확한 뜻은 “이 절차로 구간을 만들기를 반복하면, 그중 약 95% 가 μ 를 포함한다” 다. NIST 핸드북도 신뢰구간을 이런 반복 절차의 성질로 설명한다(NIST/SEMATECH e-Handbook, What are confidence intervals?).
표본이 작으면 1.96 대신 t-분포의 값을 쓴다(t-구간). n 이 커지면 둘은 거의 같아진다.
가설 검정의 틀
- 귀무가설 H₀: 효과가 없다. 예: 배포 전후 평균 응답 시간이 같다.
- 대립가설 H₁: 효과가 있다. 예: 다르다(양측) 또는 늘었다(단측).
- 검정 통계량: 데이터가 H₀ 에서 얼마나 벗어났는지 재는 수. 예: (x̄₁ − x̄₂) / SE.
- p-값: H₀ 가 참이라고 가정할 때, 지금만큼 또는 더 극단적인 결과가 나올 확률.
- 판정: p-값이 미리 정한 유의수준 α(흔히 0.05)보다 작으면 H₀ 를 기각한다.
검정은 003번 글의 귀류법과 닮았다. “차이가 없다고 가정하면, 이런 데이터는 거의 나올 수 없다. 따라서 가정을 의심한다.” 다만 논리적 모순이 아니라 확률적으로 드물다는 것뿐이어서, 결론도 확률적으로 틀릴 수 있다.
두 종류의 오류
| H₀ 가 실제로 참 | H₀ 가 실제로 거짓 | |
|---|---|---|
| H₀ 기각 | 1종 오류(위양성), 확률 α | 올바른 탐지, 확률 1−β (검정력) |
| H₀ 유지 | 올바른 판단 | 2종 오류(위음성), 확률 β |
α 를 낮추면 위양성은 줄지만 진짜 효과를 놓치기 쉬워진다. 둘을 함께 줄이는 방법은 표본을 늘리는 것뿐이다.
흔한 오해
- p-값은 “H₀ 가 참일 확률” 이 아니다. H₀ 를 가정하고 계산한 데이터의 확률이다. 013번 글의 P(A ∣ B) 와 P(B ∣ A) 혼동과 같은 실수다.
- 유의하다 ≠ 중요하다. 표본이 수백만 개면 0.1ms 차이도 유의하게 나온다. 효과 크기와 신뢰구간을 함께 보고 실무적으로 의미 있는 차이인지 판단한다.
- 여러 번 검정하면 우연히 걸린다. 지표 20 개를 각각 α = 0.05 로 검정하면, 아무 효과가 없어도 적어도 하나가 유의하게 나올 확률이 1 − 0.95²⁰ ≈ 64% 다.
- 유의하지 않다 ≠ 차이가 없다. 표본이 작으면 검정력이 낮아서 진짜 차이도 못 잡는다.
직접 해 보기
배포 전후 응답 시간을 흉내 낸 데이터로 신뢰구간을 구하고, 순열 검정(permutation test)으로 p-값을 계산한다. 순열 검정은 “두 그룹 이름표가 의미 없다면(H₀), 이름표를 무작위로 섞어도 차이가 비슷하게 나와야 한다” 는 생각을 그대로 코드로 옮긴 것이라 분포 가정이 필요 없다.
데이터는 일부러 “진짜로 6% 느려진 배포” 로 만들었다. 같은 효과를 표본 300 개와 3,000 개로 각각 검정해 본다.
import random, statistics, math
from statistics import NormalDist
random.seed(1)
Z975 = NormalDist().inv_cdf(0.975)
def sample(median, n):
return [random.lognormvariate(math.log(median), 0.25) for _ in range(n)]
def ci95(xs):
m, s, n = statistics.mean(xs), statistics.stdev(xs), len(xs)
return round(m - Z975 * s / math.sqrt(n), 1), round(m + Z975 * s / math.sqrt(n), 1)
def mean(xs):
return sum(xs) / len(xs)
def perm_test(a, b, R=2000):
observed = mean(b) - mean(a)
pooled, k, count = a + b, len(a), 0
for _ in range(R):
random.shuffle(pooled)
if abs(mean(pooled[k:]) - mean(pooled[:k])) >= abs(observed):
count += 1
p = f"{count / R:.3f}" if count else f"< {1 / R}"
return round(observed, 1), p
# 진짜로 6% 느려진 배포. 표본 크기만 바꿔 본다.
for n in (300, 3000):
before, after = sample(200, n), sample(212, n)
print(n, ci95(before), ci95(after), perm_test(before, after))
# 다중 검정: 효과 없는 지표 20 개를 각각 검정하면?
print(round(1 - 0.95**20, 3))
실행 결과다(난수 시드를 고정했으므로 같은 결과가 나온다. 순열 검정이라 몇 초 걸린다).
300 (200.4, 212.6) (207.7, 221.0) (7.9, '0.099')
3000 (204.1, 207.8) (217.1, 221.1) (13.2, '< 0.0005')
0.642
표본 300 개에서는 p-값이 약 0.1 이라 유의수준 5% 에서 귀무가설을 기각하지 못한다. 효과는 분명히 있는데도 그렇다. “유의하지 않다 ≠ 차이가 없다” 의 실제 예다. 신뢰구간도 크게 겹친다.
같은 효과를 표본 3,000 개로 보면 신뢰구간이 좁아져 겹치지 않고, 섞어서 만든 2,000 번의 차이 중 관측값만큼 큰 것이 하나도 없다. 검정력은 표본 크기로 산다. 마지막 줄은 효과 없는 지표 20 개를 검정할 때 적어도 하나가 우연히 유의할 확률 64% 다.
현업에서는
- 벤치마크 비교. 성능 테스트는 여러 번 반복해서 분포를 비교한다. 한 번씩 돌려 숫자 두 개를 비교하는 것은 표본 크기 1 짜리 검정이다. 실행 순서와 워밍업 같은 체계적 차이도 통계로는 걸러지지 않으므로 실험 설계에서 막아야 한다.
- 카나리 배포. 새 버전을 일부 트래픽에만 내보내고 기존 버전과 오류율·지연을 비교하는 카나리 분석은 본질적으로 두 표본 비교다. 트래픽이 적은 시간대에는 표본이 작아 차이를 못 잡을 수 있으니, 관찰 시간을 표본 크기로 생각해야 한다.
- A/B 테스트에서 엿보기. 결과를 매일 들여다보다가 유의해지는 순간 멈추면 1종 오류율이 α 보다 훨씬 커진다. 표본 크기를 미리 정하거나, 순차 검정처럼 엿보기를 고려한 방법을 쓴다.
- 기준 문서. NIST 의 공학 통계 핸드북은 가설 검정의 절차와 해석을 실무자 관점에서 정리해 두었다(NIST/SEMATECH e-Handbook, What are statistical tests?).
확인 문제
- 표본 100 개의 평균이 50, 표준편차가 10 이다. 모평균의 95% 신뢰구간은 대략?
- 표준오차를 1/3 로 줄이려면 표본을 몇 배로 늘려야 하는가?
- “p = 0.03 이므로 귀무가설이 참일 확률은 3% 다” 는 맞는 해석인가?
- 지표 10 개를 각각 α = 0.05 로 검정할 때, 모두 효과가 없어도 적어도 하나가 유의할 확률은?
풀이
- 50 ± 1.96 × 10/√100 = 50 ± 1.96, 즉 약 (48.0, 52.0).
- 9 배. 표준오차는 √n 에 반비례한다.
- 아니다. p-값은 귀무가설이 참이라고 가정했을 때 이만큼 극단적인 데이터가 나올 확률이다.
- 1 − 0.95¹⁰ ≈ 0.401. (검정들이 독립이라고 가정할 때)