1 도입 — 단순 평균을 넘어서
지금까지 부트스트랩의 기본 절차 (단일 표본 평균의 CI) 를 다뤘다. 실무에서는 더 복잡한 자료와 통계량을 다룬다.
이 글은 (a) 회귀 부트스트랩 자세히, (b) 분류 모형 부트스트랩, (c) 시계열 + 클러스터 자료의 부트스트랩 변형을 다룬다.
2 회귀 부트스트랩 — 두 형태 비교
A-BUI7-3 에서 cases vs residual 부트스트랩을 소개. 이 글은 역학 사례 와 디테일 추가.
2.1 Cases Bootstrap
자료점 \((X_i, Y_i)\) 를 쌍으로 추출.
2.2 Residual Bootstrap
원 모형 적합 → 잔차 부트스트랩.
def residual_boot(X, Y, n_boot=5000):
n = len(Y)
X_design = np.column_stack([np.ones(n), X])
beta_orig = np.linalg.lstsq(X_design, Y, rcond=None)[0]
Y_hat = X_design @ beta_orig
residuals = Y - Y_hat
coefs = []
for _ in range(n_boot):
eps_b = np.random.choice(residuals, n, replace=True)
Y_b = Y_hat + eps_b
beta = np.linalg.lstsq(X_design, Y_b, rcond=None)[0]
coefs.append(beta)
return np.array(coefs)2.3 Wild Bootstrap
이분산성 (heteroscedasticity) 자료에서 residual bootstrap 부정확. Wild bootstrap 변형:
def wild_boot(X, Y, n_boot=5000):
n = len(Y)
X_design = np.column_stack([np.ones(n), X])
beta_orig = np.linalg.lstsq(X_design, Y, rcond=None)[0]
residuals = Y - X_design @ beta_orig
coefs = []
for _ in range(n_boot):
# 잔차에 ±1 랜덤 곱 (Rademacher distribution)
signs = np.random.choice([-1, 1], n)
Y_b = X_design @ beta_orig + residuals * signs
beta = np.linalg.lstsq(X_design, Y_b, rcond=None)[0]
coefs.append(beta)
return np.array(coefs)Wild bootstrap 은 각 잔차의 크기 보존 + 부호 무작위화. 이분산성에 robust.
이분산성 자료: \(X\) 값에 따라 잔차 분산이 변함. 예: 큰 \(X\) 에서 큰 분산.
Residual bootstrap: 잔차를 섞음 → 큰 \(X\) 의 잔차가 작은 \(X\) 자리로 → 분산 구조 깨짐.
Wild bootstrap: 잔차를 그 위치에 유지, 부호만 무작위 → 분산 구조 보존.
따라서 wild bootstrap 이 이분산성 자료에 더 적합.
A/B 테스트 자료에서 처치 그룹의 분산이 대조군과 다른 경우 wild bootstrap 권장.
2.4 회귀 계수 vs 예측의 CI
A-BUI7-3 에서 다뤘듯이 계수 CI 와 예측 CI/PI 가 다르다.
| CI 유형 | 의미 | 부트스트랩 |
|---|---|---|
| 계수 CI | \(\beta_j\) 의 불확실성 | \(\hat{\beta}^*_b\) 분포 |
| 예측 CI (\(x_0\)) | \(E(Y \mid x_0)\) 의 불확실성 | \(\hat{y}^*_b(x_0)\) 분포 |
| 예측 PI (\(x_0\)) | \(Y(x_0)\) 의 분포 | \(\hat{y}^*_b + \varepsilon^*_b\) 분포 |
PI 가 항상 더 넓다 (잔차 변동 추가).
3 분류 모형의 부트스트랩
3.1 ROC AUC CI
분류 모형 평가의 표준 지표. 부트스트랩으로 CI 계산:
import numpy as np
from sklearn.metrics import roc_auc_score
def auc_boot(y_true, y_score, n_boot=5000):
n = len(y_true)
aucs = []
for _ in range(n_boot):
idx = np.random.choice(n, n, replace=True)
# 양성/음성이 모두 있어야 AUC 정의 가능
if len(np.unique(y_true[idx])) > 1:
aucs.append(roc_auc_score(y_true[idx], y_score[idx]))
return np.array(aucs)3.2 Sensitivity, Specificity, PPV, NPV
모든 진단 지표의 CI 를 부트스트랩으로 계산 가능.
def diagnostic_boot(y_true, y_pred, n_boot=5000):
"""진단 지표 4 가지의 부트스트랩"""
n = len(y_true)
sens, spec, ppv, npv = [], [], [], []
for _ in range(n_boot):
idx = np.random.choice(n, n, replace=True)
yt, yp = y_true[idx], y_pred[idx]
tp = np.sum((yt == 1) & (yp == 1))
tn = np.sum((yt == 0) & (yp == 0))
fp = np.sum((yt == 0) & (yp == 1))
fn = np.sum((yt == 1) & (yp == 0))
if tp + fn > 0:
sens.append(tp / (tp + fn))
if tn + fp > 0:
spec.append(tn / (tn + fp))
if tp + fp > 0:
ppv.append(tp / (tp + fp))
if tn + fn > 0:
npv.append(tn / (tn + fn))
return sens, spec, ppv, npv3.3 Calibration
분류 모형의 예측 확률 정확성 (calibration) 도 부트스트랩으로 측정.
4 시계열 부트스트랩 — Block Bootstrap
4.1 동기
시계열 자료는 자기 상관 존재. 단순 부트스트랩은 자기 상관을 깨뜨림. 결과: 부정확한 SE.
4.2 Block Bootstrap
길이 \(\ell\) 의 연속 블록 단위로 추출.
def block_bootstrap(data, block_size, n_boot=5000):
n = len(data)
n_blocks = (n + block_size - 1) // block_size
boot_samples = []
for _ in range(n_boot):
sample = []
for _ in range(n_blocks):
start = np.random.randint(0, n - block_size + 1)
sample.extend(data[start:start + block_size])
boot_samples.append(np.array(sample[:n]))
return boot_samples블록 크기 권장: \(\ell \approx n^{1/3}\).
4.3 Stationary Bootstrap (Politis & Romano 1994)
블록 크기를 무작위 (기하 분포) 로. Block bootstrap 보다 약간 robust.
4.4 A/B 테스트의 시간 효과
A/B 테스트에 요일·시간대 패턴 이 있으면 자기 상관. Block bootstrap 권장.
# 일별 매출 시계열에서 요일 효과
daily_revenue = np.array([...]) # 30 일 자료
block_size = 7 # 1 주일 블록
boot_means = []
for _ in range(5000):
boot_sample = []
n_blocks = 30 // block_size + 1
for _ in range(n_blocks):
start = np.random.randint(0, 30 - block_size + 1)
boot_sample.extend(daily_revenue[start:start + block_size])
boot_means.append(np.mean(boot_sample[:30]))
ci = np.percentile(boot_means, [2.5, 97.5])이 절차가 요일 효과 보존 + 부트스트랩 추론.
5 클러스터 부트스트랩
5.1 동기
클러스터 자료 (학교, 병원, 사용자 반복 측정) 에서 클러스터 내 상관 존재. 단순 부트스트랩 부정확.
5.2 절차
클러스터 단위 로 복원 추출. 각 클러스터 내 자료는 그대로 유지.
def cluster_bootstrap(data, cluster_id, n_boot=5000):
clusters = np.unique(cluster_id)
n_clusters = len(clusters)
boot_samples = []
for _ in range(n_boot):
boot_clusters = np.random.choice(clusters, n_clusters, replace=True)
boot_data = []
for c in boot_clusters:
boot_data.extend(data[cluster_id == c])
boot_samples.append(np.array(boot_data))
return boot_samples5.3 A/B 테스트 응용
사용자가 여러 번 노출 되는 자료: 사용자 = 클러스터, 노출 = 클러스터 내 관측.
# 사용자 클러스터 부트스트랩
df = pd.DataFrame({
'user_id': [...], # 사용자 ID (반복)
'revenue': [...] # 노출별 매출
})
users = df['user_id'].unique()
boot_means = []
for _ in range(5000):
boot_users = np.random.choice(users, len(users), replace=True)
boot_data = pd.concat([df[df['user_id'] == u] for u in boot_users])
boot_means.append(boot_data['revenue'].mean())이 절차가 사용자 단위 독립성 가정 하의 robust CI.
6 가중 표본의 부트스트랩
6.1 Survey Weights
조사 자료에서 각 응답자에 가중치 부여 (모집단 비례). 부트스트랩에서 가중치 처리:
def weighted_boot(data, weights, n_boot=5000):
n = len(data)
weights = weights / weights.sum()
boot_means = []
for _ in range(n_boot):
idx = np.random.choice(n, n, replace=True, p=weights)
boot_means.append(np.mean(data[idx]))
return boot_means또는 Wild Bootstrap with weights 변형 사용.
7 베이즈 Bootstrap
전통 부트스트랩의 베이즈 해석. 거의 같은 결과.
8 부트스트랩 검정 vs CI
부트스트랩 CI 는 추정 도구. 부트스트랩 검정 도 가능 (다음 글 A-WOO14-4).
| 측면 | CI | 검정 |
|---|---|---|
| 목적 | 효과 크기 추정 | 가설 검정 |
| 출력 | (low, high) | p 값 |
| 절차 | 직접 부트스트랩 | \(H_0\) 강제 + 부트스트랩 |
9 Woodward 의 추가 사례
9.1 Risk Difference 의 CI
코호트 연구에서 RD = \(p_T - p_C\). 부트스트랩으로:
9.2 두 평균의 비율
전통 공식 Fieller 가 복잡. 부트스트랩 단순:
9.3 Trimmed Mean
20 % trimmed mean (양 극단 10 % 제외 평균) 의 CI:
def trimmed_mean(x, trim=0.1):
n = len(x)
sorted_x = np.sort(x)
return np.mean(sorted_x[int(n*trim):int(n*(1-trim))])
def trimmed_mean_boot(data, n_boot=5000):
return [trimmed_mean(np.random.choice(data, len(data), replace=True))
for _ in range(n_boot)]이상치에 robust 한 평균.
10 실무 권장
10.1 Robustness Check 절차
1. 전통 분석 + CI 계산
2. 부트스트랩 분석 + CI 계산 (여러 방법)
3. 결과 비교
일관 → 결과 강건
다름 → 자료 진단 + 부트스트랩 CI 우선
10.2 분야별 표준
| 분야 | 부트스트랩 표준 |
|---|---|
| 임상 RCT | BCa, \(B = 5000\) |
| 역학 | BCa or Percentile, \(B = 1000\) |
| A/B 테스트 | Percentile (빠름), \(B = 5000\) |
| 머신러닝 | Percentile (큰 자료), \(B = 1000\) |
| 논문 | BCa, \(B = 10000\) |
11 후속 — Bootstrap 가설 검정과 한계
다음 글 A-WOO14-4 는 부트스트랩 가설 검정 과 부트스트랩의 한계 를 다룬다.
12 관련 주제
선행 지식
후속 주제 (Phase A)
- A-WOO14-4 Bootstrap 가설 검정 + 한계
- A-WOO14-5 Permutation Tests
다른 카테고리 연결