1 이 절의 위치
앞선 §10.1.3에서 Delta Method로 추정량 \(\hat\theta = h(\hat p)\) 의 점근 분산을 근사했다:
\[ \widehat{\text{Var}}(h(\hat\theta)) \approx [h'(\hat\theta)]^2 \cdot \widehat{\text{Var}}(\hat\theta). \]
그런데 \(h'(\theta_0) = 0\) 이 되는 지점 — 예를 들어 \(h(p) = p(1-p)\) 에서 \(p = 1/2\) — 에서는 1차 근사가 붕괴된다. Delta Method는 “1차 Taylor 전개”에 의존하므로, 그 계수가 0이 되면 분산 추정이 0 또는 비정상적으로 작아진다.
§10.1.4 부트스트랩은 이 문제를 함수 형태에 무관하게 해결하는 비모수적 대안이다 (Casella & Berger, 2002, Ch.10).
2 부트스트랩의 핵심 아이디어
관측된 표본 \(\mathbf{x} = (x_1, x_2, \ldots, x_n)\) 으로부터 복원 추출(sampling with replacement)로 \(B\) 개의 재표본(resample)을 생성하고, 각 재표본에서 추정량을 계산하여 분산을 추정하는 방법이다.
- 비모수 부트스트랩: 경험적 분포 \(\hat{F}_n\) 에서 재표본
- 모수 부트스트랩: 추정된 모수를 가진 모형 \(f(x|\hat\theta)\) 에서 재표본
삼단계 유추:
모집단 F ─(표본 추출)→ 관측 표본 x₁,...,xₙ ─(통계 계산)→ θ̂
↓ ↓ ↓
(알 수 없다) 경험적 분포 F̂ₙ (분산은 어떻게 구하나?)
대신:
F̂ₙ ─(재표본 추출)→ 재표본 x₁*,...,xₙ* ─(통계 계산)→ θ̂*_i
(B번 반복)
↓
Var*(θ̂) = Var(θ̂*_1, ..., θ̂*_B)
즉, “모집단에서 표본을 뽑아 통계량의 분포를 파악”하는 작업을 “표본에서 재표본을 뽑아 추정량의 분포를 파악”으로 대체한다. 표본이 모집단을 대표하는 한, 재표본은 표본을 대표하고, 재표본 기반 분산은 실제 분산을 근사한다.
3 비모수 부트스트랩: 완전 열거 공식
크기 \(n\) 인 표본에서 복원 추출로 크기 \(n\) 인 재표본을 뽑는 방법의 수는 \(n^n\) 가지이다. 각 재표본에 대해 추정량 \(\hat\theta_i^*\) 를 계산하면, 부트스트랩 분산은 다음과 같이 정의된다.
\[ \text{Var}^*(\hat\theta) = \frac{1}{n^n - 1} \sum_{i=1}^{n^n} (\hat\theta_i^* - \bar\theta^*)^2, \]
여기서 \(\bar\theta^* = \frac{1}{n^n} \sum_{i=1}^{n^n} \hat\theta_i^*\) 는 재표본 추정량의 평균이다.
예시 — 평균의 분산 부트스트랩 추정 (Ex 10.1.19):
데이터 \(\{2, 4, 9, 12\}\) 에서 \(n=4\)이면 \(4^4 = 256\) 개의 재표본이 존재한다. 각 재표본의 평균 \(\bar x_i^*\) 를 계산하면 부트스트랩 분산 \(\text{Var}^*(\bar X) = 3.94\) 를 얻는다.
그런데 \(n > 15\) 이면 \(n^n\) 은 천문학적으로 커진다. \(n=24\) 이면 \(24^{24} \approx 1.33 \times 10^{13}\) 으로 완전 열거는 불가능하다. 해결책은 통계학의 본질로 되돌아가는 것: 재표본 중에서 \(B\) 개를 표본 추출한다.
4 비모수 부트스트랩: B 표본 근사
표본 \(\mathbf{x}\) 로부터 \(B\) 개의 재표본을 복원 추출하고, 각 재표본에서 \(\hat\theta_i^*\) 를 계산한다:
\[ \text{Var}_B^*(\hat\theta) = \frac{1}{B-1} \sum_{i=1}^{B} (\hat\theta_i^* - \bar{\hat\theta}^*)^2, \]
여기서 \(\bar{\hat\theta}^* = \frac{1}{B} \sum_{i=1}^{B} \hat\theta_i^*\) 이다.
- \(B\) 가 커질수록 \(\text{Var}_B^*(\hat\theta) \to \text{Var}^*(\hat\theta)\) (대수법칙에 의해).
- 실무에서 \(B = 1000 \sim 10000\) 이면 충분히 안정적인 분산 추정을 얻는다.
- \(\text{Var}_B^*(\hat\theta)\) 는 실제 분산의 추정량이 아니라 완전 열거 분산의 근사치(approximator)이다 (Lehmann, 1999).
표준오차는 분산의 제곱근으로 정의된다:
\[ \text{SE}^*_B(\hat\theta) = \sqrt{\text{Var}_B^*(\hat\theta)}. \]
5 Delta Method vs 부트스트랩: 핵심 비교
5.1 문제: \(h(p) = p(1-p)\) 에서 \(p = 1/2\)
이항 데이터 \(X \sim \text{Bin}(n, p)\) 에서 \(\hat p = X/n\) 이고, \(\widehat{p(1-p)} = \hat p (1 - \hat p)\) 이다.
1차 Delta Method:
\[ \widehat{\text{Var}}(\hat p(1-\hat p)) \approx [h'(\hat p)]^2 \cdot \frac{\hat p(1-\hat p)}{n}, \quad h'(p) = 1 - 2p. \]
\(\hat p = 1/2\) 이면 \(h'(1/2) = 0\) 이 되어 추정 분산이 0으로 붕괴된다.
부트스트랩은 \(h'\) 를 전혀 계산하지 않는다. 재표본에서 \(\hat p^*(1-\hat p^*)\) 를 직접 계산하므로 \(p = 1/2\) 부근에서도 올바른 분산을 추정한다.
결과 비교 (Casella & Berger Table 10.1.1, \(n = 24\), \(B = 1000\)):
| \(\hat p\) | 부트스트랩 | Delta Method (1차) | 참값 |
|---|---|---|---|
| \(1/4\) | 0.00508 | 0.00195 | 0.00484 |
| \(1/2\) | 0.00555 | 0.00022 | 0.00531 |
| \(2/3\) | 0.00561 | 0.00102 | 0.00519 |
모든 경우에서 부트스트랩이 참값에 더 가깝다. 특히 \(\hat p = 1/2\) 에서 Delta Method가 심각하게 과소추정하는 반면, 부트스트랩은 자동으로 교정된다.
왜 부트스트랩이 더 정확한가: Delta Method는 1차 Taylor 근사이므로 분산의 하한(lower bound) 역할을 한다 (§10.1.3의 식 10.1.7 참조). 부트스트랩은 “2차 정확도(second-order accuracy)”를 가지는 경우가 많아 Taylor 전개의 고차항까지 암묵적으로 반영한다.
6 모수 부트스트랩 (Parametric Bootstrap)
비모수 부트스트랩이 경험적 분포 \(\hat F_n\) 에서 재표본을 뽑는다면, 모수 부트스트랩은 추정된 모수를 가진 모형 \(f(x|\hat\theta)\) 에서 재표본을 뽑는다.
- 원본 데이터로 \(\hat\theta\) (예: MLE)를 추정한다.
- \(f(x|\hat\theta)\) 로부터 크기 \(n\) 인 재표본 \(B\) 개를 독립적으로 생성한다.
- 각 재표본에서 추정량 \(\hat\theta_i^*\) 를 계산하고 \(\text{Var}_B^*(\hat\theta)\) 를 구한다.
이 재표본은 원본 데이터의 복원 추출이 아니라, 플러그인 분포(plug-in distribution) \(f(x|\hat\theta)\) 에서 뽑은 진짜 랜덤 표본이다.
예시 (Ex 10.1.22): 9개의 관측값 \(\{-1.81, 0.63, 2.22, 2.41, 2.95, 4.16, 4.24, 4.53, 5.09\}\), \(\bar x = 2.71\), \(s^2 = 4.82\). 정규 분포를 가정하면 모수 부트스트랩은 \(X^* \sim N(2.71, 4.82)\) 에서 \(B=1000\) 표본을 생성한다.
결과: \(\text{Var}_B^*(S^2) = 4.33\). 정규 이론에 의한 분산 \(2(\sigma^2)^2/8 \approx 5.81\) (MLE 플러그인). 참값: \(\text{Var}(S^2) = 4.00\) (데이터가 실제로 \(N(\cdot, 4)\) 에서 생성됨).
모수 부트스트랩이 정규 이론 근사보다 참값에 더 가깝다.
비모수 vs 모수 부트스트랩 선택 기준:
| 상황 | 선택 |
|---|---|
| 모집단 분포 형태를 알고 있다 | 모수 부트스트랩 (더 효율적) |
| 분포 형태가 불확실하다 | 비모수 부트스트랩 (더 강건) |
| 표본이 작다 | 모수 부트스트랩 (외삽 효과) |
| 분포 형태가 맞지 않을 위험이 있다 | 비모수 부트스트랩 (모형 위험 없음) |
7 일치성 (Consistency)
부트스트랩 분산 추정량이 실제 분산에 수렴하는가?
두 단계로 분리해서 분석한다:
Part (a): \(B \to \infty\)
\[ \text{Var}_B^*(\hat\theta) \xrightarrow{B \to \infty} \text{Var}^*(\hat\theta). \]
이는 대수법칙에 의해 성립한다 (Exercise 10.15). 즉, 재표본 수 \(B\) 를 충분히 늘리면 완전 열거 부트스트랩 분산으로 수렴한다.
Part (b): \(n \to \infty\)
\[ \text{Var}^*(\hat\theta) \xrightarrow{n \to \infty} \text{Var}(\hat\theta). \]
이 부분이 “부트스트랩이 실제로 작동하는가”의 핵심이다. iid 표본에서는 일반적으로 성립하지만, 비독립 구조(시계열, 군집 데이터 등)에서는 성립하지 않을 수 있다.
- 극단 통계량 (Extreme statistics): 표본 최대값 \(X_{(n)}\) 의 분산 추정에는 부트스트랩이 일치하지 않는다. 재표본에는 원본 최대값보다 큰 값이 나올 수 없기 때문이다.
- 의존 구조가 있는 데이터: 시계열 데이터에는 블록 부트스트랩(block bootstrap)을 사용해야 한다.
- 표본 크기가 매우 작을 때: \(n < 10\) 이면 재표본의 다양성이 부족해 분산이 과소추정된다.
8 응용 분야
| 분야 | 활용 | 구체적 예시 |
|---|---|---|
| 기계학습 | 모형 성능 분산 추정 | 교차검증 정확도의 신뢰구간 |
| 임상시험 | 복잡한 통계량의 SE | 생존율 차이, 중앙값 생존 시간 |
| 계량경제 | 비선형 추정량 추론 | 도구변수 추정량, 비선형 회귀 계수 |
| 금융공학 | 포트폴리오 위험 추정 | VaR, Sharpe ratio의 표준오차 |
| A/B 테스트 | 비율 지표의 SE | 클릭율, 전환율 분산 추정 |
| 생태학 | 다양성 지수 추론 | Shannon entropy 의 신뢰구간 |
9 예시: 중앙값의 표준오차
정규 분포에서 중앙값의 표준오차는 이론적으로 \(\sqrt{\pi/2} \cdot \sigma/\sqrt{n}\) 이지만, 분포가 알려지지 않은 경우 부트스트랩이 유일한 실용적 방법이다.
손으로 추적 가능한 소규모 예시:
데이터: \(\{3, 7, 2, 9, 5\}\), 중앙값 \(\hat m = 5\).
재표본 3개를 예시로 들면:
| 재표본 | 값 | 중앙값 \(\hat m^*\) |
|---|---|---|
| \(\{7, 2, 9, 5, 3\}\) | 정렬: 2, 3, 5, 7, 9 | 5 |
| \(\{3, 3, 9, 7, 2\}\) | 정렬: 2, 3, 3, 7, 9 | 3 |
| \(\{5, 9, 9, 2, 7\}\) | 정렬: 2, 5, 7, 9, 9 | 7 |
\(B = 1000\) 을 반복하면 \(\text{SE}^*_B(\hat m)\) 을 얻는다.
10 코드 예시
10.1 Step 1: 순수 Python 구현 (원리 이해)
import numpy as np
import random
def bootstrap_se(data, estimator, B=1000, seed=42):
"""
비모수 부트스트랩 표준오차 계산.
Parameters
----------
data : list or array-like, 원본 표본
estimator : callable, 통계량 함수 (예: np.mean, np.median)
B : int, 재표본 수
seed : int, 재현성을 위한 난수 시드
Returns
-------
se : float, 부트스트랩 표준오차
"""
rng = np.random.default_rng(seed)
n = len(data)
data = np.array(data)
boot_estimates = []
for _ in range(B):
# 복원 추출 재표본
resample = rng.choice(data, size=n, replace=True)
boot_estimates.append(estimator(resample))
boot_estimates = np.array(boot_estimates)
# Var_B* = (1/(B-1)) * sum((θ̂_i* - θ̄*)²)
se = np.std(boot_estimates, ddof=1)
return se
# 예시 1: 평균의 SE (이론값 = σ/√n 과 비교)
data = [2.3, 1.8, 3.1, 2.7, 2.5, 3.4, 1.9, 2.8, 3.0, 2.2]
se_mean = bootstrap_se(data, np.mean, B=5000)
se_theory = np.std(data, ddof=1) / np.sqrt(len(data))
print(f"Bootstrap SE(mean) = {se_mean:.4f}")
print(f"Theoretical SE = {se_theory:.4f}")
# 예시 2: p*(1-p) 의 SE — Delta Method 붕괴 지점 근처
n = 24
p_hat = 0.5 # Delta Method 붕괴 지점
x = int(p_hat * n)
data_binom = [1] * x + [0] * (n - x) # 0/1 데이터
def p_1mp(arr):
"""추정량 h(p) = p*(1-p)"""
p = np.mean(arr)
return p * (1 - p)
se_boot = bootstrap_se(data_binom, p_1mp, B=5000)
# Delta Method (1차): h'(p) = 1 - 2p → 0 at p=0.5
h_prime = 1 - 2 * p_hat
se_delta = abs(h_prime) * np.sqrt(p_hat * (1 - p_hat) / n)
print(f"\np̂ = {p_hat}, n = {n}")
print(f"Bootstrap SE(p̂(1-p̂)) = {se_boot:.5f}")
print(f"Delta Method SE = {se_delta:.5f}") # ≈ 0
print(f"True SE (numeric) ≈ 0.0728")10.2 Step 2: scipy / 실무 활용
import numpy as np
from scipy import stats
def bootstrap_ci(data, estimator, B=2000, alpha=0.05, seed=42):
"""
부트스트랩 신뢰구간 계산 (백분위수 방법).
Parameters
----------
data : array-like
estimator : callable
B : int, 재표본 수
alpha : float, 유의수준 (기본 0.05 → 95% CI)
seed : int
Returns
-------
point_est : float, 원본 표본 추정값
ci : tuple (lower, upper), 신뢰구간
se : float, 부트스트랩 SE
"""
rng = np.random.default_rng(seed)
data = np.array(data)
n = len(data)
point_est = estimator(data)
boot_estimates = np.array([
estimator(rng.choice(data, size=n, replace=True))
for _ in range(B)
])
# 백분위수 방법 신뢰구간
ci_lower = np.percentile(boot_estimates, 100 * alpha / 2)
ci_upper = np.percentile(boot_estimates, 100 * (1 - alpha / 2))
se = np.std(boot_estimates, ddof=1)
return point_est, (ci_lower, ci_upper), se
# 실무 예시: Sharpe ratio의 신뢰구간
np.random.seed(0)
returns = np.random.normal(loc=0.01, scale=0.05, size=120) # 월간 수익률 120개월
def sharpe(r, rf=0.002):
"""단순 Sharpe ratio (월 기준)"""
return (np.mean(r) - rf) / np.std(r, ddof=1)
est, ci, se = bootstrap_ci(returns, sharpe, B=5000)
print(f"Sharpe ratio = {est:.4f}")
print(f"Bootstrap SE = {se:.4f}")
print(f"95% CI = ({ci[0]:.4f}, {ci[1]:.4f})")
# 모수 부트스트랩 예시
def parametric_bootstrap_se(data, estimator, B=2000, seed=42):
"""
모수 부트스트랩 (정규 분포 가정).
플러그인 분포: N(x̄, s²) 에서 재표본 생성.
"""
rng = np.random.default_rng(seed)
data = np.array(data)
mu_hat = np.mean(data)
sigma_hat = np.std(data, ddof=1)
n = len(data)
boot_estimates = np.array([
estimator(rng.normal(mu_hat, sigma_hat, size=n))
for _ in range(B)
])
return np.std(boot_estimates, ddof=1)
# S² 의 SE 비교: 비모수 vs 모수 부트스트랩
data_ex = np.array([-1.81, 0.63, 2.22, 2.41, 2.95, 4.16, 4.24, 4.53, 5.09])
se_nonparam = bootstrap_se(data_ex, np.var, B=5000)
se_param = parametric_bootstrap_se(data_ex, np.var, B=5000)
print(f"\nS² 의 SE 비교 (n=9):")
print(f" 비모수 부트스트랩 SE = {se_nonparam:.4f}")
print(f" 모수 부트스트랩 SE = {se_param:.4f}")
print(f" 정규 이론 SE ≈ {2 * (np.var(data_ex))**2 / (len(data_ex)-1):.4f} (2σ⁴/(n-1))")11 핵심 요약
| 항목 | 내용 |
|---|---|
| 핵심 아이디어 | 표본 → 모집단 유추를 재표본 → 표본 유추로 대체 |
| 비모수 부트스트랩 | 경험적 분포에서 복원 추출, 모형 가정 없음 |
| 모수 부트스트랩 | 플러그인 분포 \(f(x|\hat\theta)\) 에서 직접 생성 |
| Delta Method 대비 장점 | 비단조 함수, 복잡한 추정량에서도 자동 작동 |
| 일치성 조건 | iid 표본에서 \(n \to \infty\), \(B \to \infty\) 시 성립 |
| 실무 \(B\) 기준 | SE 추정: \(B \geq 1000\), 신뢰구간: \(B \geq 2000\) |
12 관련 주제
선행 지식
- 점근적 점추정: 효율성 (Asymptotic Point Estimation: Efficiency) — MLE 점근 정규성, 크래머-라오 하한
- 점근적 계산과 비교 (Asymptotic Calculations and Comparisons) — Delta Method, ARE
후속 주제
- 점근적 강건성 (Asymptotic Robustness) — M-추정, 영향함수
관련 개념
- 구간 추정 개요 (Interval Estimation Overview) — 부트스트랩 신뢰구간으로 확장
13 참고 문헌
- Casella, G. & Berger, R. L. (2002). Statistical Inference (2nd ed.). Duxbury. Ch.10.
- Efron, B. (1979). Bootstrap methods: Another look at the jackknife. Annals of Statistics, 7(1), 1–26.
- Efron, B., & Tibshirani, R. J. (1993). An Introduction to the Bootstrap. Chapman & Hall.
- Lehmann, E. L. (1999). Elements of Large-Sample Theory. Springer. §6.5.