Bootstrap CI 의 4 유형

Woodward 14.3 — Normal, Percentile, BC, BCa 의 도출과 역학 응용

Woodward Ch.14.3 의 부트스트랩 CI 4 가지 형태 — Normal, Percentile, BC (Bias-Corrected), BCa (Bias-Corrected accelerated) — 의 수학적 도출과 비교를 자세히 정리한다. 편향 보정의 의미, 가속도 모수의 역할, jackknife 와의 연결을 다룬다.

Experimentation
Fundamentals
저자

Kwangmin Kim

공개

2026년 05월 08일

1 도입 — 같은 부트스트랩, 다른 CI

부트스트랩 통계량 분포 \(\{\hat{\theta}^*_b\}\) 가 같아도, CI 구성 방법이 4 가지. 각 방법의 정확도와 사용 시점이 다르다.

A-BUI7-1 에서 4 유형을 짧게 소개했다. 이 글은 수학적 도출역학 응용 을 자세히 다룬다.

2 Method 1 — Normal Bootstrap CI

2.1 정의

Normal Bootstrap CI

부트스트랩 표집 분포가 정규에 근사 한다고 가정. SE 만 부트스트랩으로 추정.

\[ \text{CI}_{1-\alpha} = \hat{\theta} \pm z_{1-\alpha/2} \cdot \widehat{\text{SE}}_{\text{boot}} \]

여기서 \(\widehat{\text{SE}}_{\text{boot}} = \text{SD}\{\hat{\theta}^*_b\}\).

2.2 가정

  • 부트스트랩 분포가 정규
  • 추정량의 비편향 (편향 무시)

2.3 한계

  • 실제 부트스트랩 분포가 비대칭 이면 부정확
  • 편향 무시
  • 거의 사용되지 않음 (다른 방법이 더 나음)

3 Method 2 — Percentile Bootstrap CI

3.1 정의

Percentile Bootstrap CI

부트스트랩 분포의 경험적 분위수 를 직접 사용.

\[ \text{CI}_{1-\alpha} = \left(\hat{\theta}^*_{(\alpha/2 \cdot B)}, \hat{\theta}^*_{(1 - \alpha/2 \cdot B)}\right) \]

\(B\) 개 부트스트랩 통계량을 정렬 후, \(\alpha/2\)\(1 - \alpha/2\) 위치의 값.

3.2 장점

  • 단순, 직관적
  • 분포 가정 X
  • 비대칭 분포에 자연스러움

3.3 한계

  • 편향이 있으면 부정확
  • 비대칭 정도가 표본 크기에 의존 하면 부정확

3.4 Woodward 의 권장

“Percentile 은 큰 표본 에서 적절. 작은 표본에서는 BCa 권장.”

4 Method 3 — BC (Bias-Corrected) CI

4.1 동기

부트스트랩 분포의 중심 이 원 추정값과 다르면 (편향 존재), Percentile 부정확.

4.2 편향 측정

편향 보정 모수 \(\hat{z}_0\)

부트스트랩 분포에서 원 추정값보다 작은 비율:

\[ \hat{z}_0 = \Phi^{-1}\left(\frac{\#\{\hat{\theta}^*_b < \hat{\theta}\}}{B}\right) \]

\(\hat{z}_0 = 0\): 편향 없음 (Percentile 과 동일) \(\hat{z}_0 > 0\): 부트스트랩 분포가 원 추정의 왼쪽 으로 편향 (즉 부트스트랩 표본의 절반 이상이 원 추정값보다 작음) \(\hat{z}_0 < 0\): 부트스트랩 분포가 원 추정의 오른쪽 으로 편향

4.3 BC 분위수

조정된 분위수:

\[ \alpha_1 = \Phi(2\hat{z}_0 + z_{\alpha/2}) \] \[ \alpha_2 = \Phi(2\hat{z}_0 + z_{1-\alpha/2}) \]

CI:

\[ \text{CI}_{BC} = \left(\hat{\theta}^*_{(\alpha_1 \cdot B)}, \hat{\theta}^*_{(\alpha_2 \cdot B)}\right) \]

4.4 의미

편향 \(\hat{z}_0\) 가 0 이면 BC = Percentile. 편향이 있으면 분위수를 조정 해 보정.

직관 — BC 의 보정 의미

부트스트랩 분포가 원 추정의 왼쪽으로 편향 (\(\hat{z}_0 > 0\)):

  • Percentile 의 왼쪽 끝 (\(\alpha/2 = 2.5 \%\)) 은 너무 작은
  • 보정으로 분위수를 오른쪽으로 이동 → CI 가 오른쪽으로 이동

이는 체계적 편향 을 보정. 추정량이 과소 추정 경향 이면 CI 도 그 경향 반영하지 않도록.

A/B 테스트 사례: 매출 lift 의 부트스트랩이 우편향 (긍정적 우연이 더 자주 발생). BC 가 이 편향을 인식하고 CI 조정.

5 Method 4 — BCa (Bias-Corrected accelerated)

5.1 동기

BC 가 편향을 보정하지만, 분포의 비대칭성 (표본 크기에 따른 변화) 도 고려해야 한다. 이를 보정한 것이 BCa.

5.2 가속도 모수

가속도 모수 \(\hat{a}\)

분포의 비대칭성 을 측정. Jackknife (Leave-one-out) 사용:

\[ \hat{a} = \frac{\sum_{i=1}^{n} (\bar{\theta}_{(\cdot)} - \hat{\theta}_{(i)})^3}{6 \left(\sum_{i=1}^{n} (\bar{\theta}_{(\cdot)} - \hat{\theta}_{(i)})^2\right)^{3/2}} \]

여기서:

  • \(\hat{\theta}_{(i)}\): \(i\) 번째 자료를 제외 한 통계량
  • \(\bar{\theta}_{(\cdot)} = \frac{1}{n} \sum \hat{\theta}_{(i)}\)

5.3 분포 비대칭성의 의미

\(\hat{a}\)자료의 영향력 차이 를 측정. 이상치가 있으면 일부 \(\hat{\theta}_{(i)}\) 가 다른 값들과 매우 달라짐 → \(\hat{a}\) 큼.

5.4 BCa 분위수

\[ \alpha_1 = \Phi\left(\hat{z}_0 + \frac{\hat{z}_0 + z_{\alpha/2}}{1 - \hat{a}(\hat{z}_0 + z_{\alpha/2})}\right) \]

\[ \alpha_2 = \Phi\left(\hat{z}_0 + \frac{\hat{z}_0 + z_{1-\alpha/2}}{1 - \hat{a}(\hat{z}_0 + z_{1-\alpha/2})}\right) \]

CI:

\[ \text{CI}_{BCa} = \left(\hat{\theta}^*_{(\alpha_1 \cdot B)}, \hat{\theta}^*_{(\alpha_2 \cdot B)}\right) \]

5.5 한계 사례

  • \(\hat{z}_0 = 0\), \(\hat{a} = 0\): BCa = Percentile
  • \(\hat{z}_0 \neq 0\), \(\hat{a} = 0\): BCa = BC
  • 일반: BCa 가 가장 정확
직관 — Jackknife 와의 연결

BCa 의 가속도 \(\hat{a}\)Jackknife (1949 Quenouille) 에서 도출. Jackknife 는 부트스트랩 이전의 재추출 방법.

\(\hat{\theta}_{(i)}\) 는 한 명을 제외 한 자료의 통계량. 각 사람의 영향력 측정.

  • 이상치가 있는 경우: 그 사람을 제외하면 통계량이 크게 변화\(\hat{a}\)
  • 동질적 자료: \(\hat{a}\) 작음

따라서 \(\hat{a}\)자료의 영향력 분포 의 비대칭성을 정량화. BCa 가 이 비대칭을 CI 에 반영.

이 절차의 수학적 정당성 이 Efron 1987 의 Better Bootstrap Confidence Intervals 정리. 작은 표본에서 BCa 가 BC 보다 수렴이 빠름.

6 4 가지 방법의 비교

6.1 정확성 순서

일반적으로:

\[ \text{Normal} < \text{Percentile} < \text{BC} \leq \text{BCa} \]

6.2 사용 시점

상황 권장 방법
큰 표본, 정규 분포 Percentile (단순)
큰 표본, 비대칭 BC 또는 BCa
작은 표본 BCa
정밀 분석 (논문) BCa
빠른 탐색 Percentile

Woodward 의 권장: 대부분 BCa.

6.3 계산 비용

방법 추가 계산
Normal 0 (SE 만)
Percentile 0
BC \(\hat{z}_0\) 계산 (단순)
BCa \(\hat{z}_0 + \hat{a}\) (jackknife \(n\) 회)

BCa 가 가장 비싸지만 현대 컴퓨팅에서 무시 가능.

7 4 방법의 시뮬레이션 비교

7.1 시뮬레이션 설정

대수정규 분포 (강한 우편향) 에서 \(n = 30\) 표본 추출. 표본 평균의 95 % CI 를 4 방법으로 구성. 1000 회 반복하여 coverage (CI 가 진짜 평균을 포함하는 비율) 측정.

7.2 결과 (가상)

방법 Coverage (목표 95 %) 평균 CI 폭
Normal 88 % 1.20
Percentile 90 % 1.18
BC 93 % 1.25
BCa 94 % 1.27

비대칭 자료에서 BCa 가 목표 coverage 에 가장 가깝.

직관 — 시뮬레이션 결과의 의미

Coverage 가 95 % 보다 작으면 CI 가 너무 좁음 → 진짜 모수를 포함 못함 → 신뢰도 부족.

Normal 과 Percentile 은 비대칭 자료에서 coverage 부족 → CI 가 부정확.

BC 와 BCa 가 보정으로 coverage 향상. 단 CI 폭도 약간 넓어짐 (정직한 표현).

trade-off 가 BCa 권장의 정량적 근거.

8 A/B 테스트 응용

8.1 사례 — Lift 분석

A/B 테스트의 매출 lift (= \(\hat{p}_T / \hat{p}_C - 1\)) CI 계산.

매출 자료 우편향 → Percentile 부정확. BCa 권장.

import numpy as np
from scipy.stats import bootstrap

np.random.seed(42)
n_per = 1000
control_revenue = np.random.lognormal(4, 1.0, n_per)
treatment_revenue = np.random.lognormal(4.05, 1.0, n_per)

def lift(c, t):
    return t.mean() / c.mean() - 1

# 4 방법 비교 (수동 + scipy)
B = 5000

# Percentile
boot_lifts = []
for _ in range(B):
    c_b = np.random.choice(control_revenue, n_per, replace=True)
    t_b = np.random.choice(treatment_revenue, n_per, replace=True)
    boot_lifts.append(lift(c_b, t_b))
ci_perc = np.percentile(boot_lifts, [2.5, 97.5])

# BCa (scipy)
def lift_paired(idx):
    n_total = 2 * n_per
    c_idx = idx[idx < n_per]
    t_idx = idx[idx >= n_per] - n_per
    if len(c_idx) == 0 or len(t_idx) == 0:
        return 0
    return lift(control_revenue[c_idx], treatment_revenue[t_idx])

# 더 단순 — scipy 의 bootstrap
def lift_func(combined):
    c = combined[:n_per]
    t = combined[n_per:]
    return lift(c, t)

# 단순 percentile vs BCa 비교
print(f"관측 lift: {lift(control_revenue, treatment_revenue):.4f}")
print(f"\nPercentile 95 % CI: ({ci_perc[0]:.4f}, {ci_perc[1]:.4f})")

# BCa 계산 (자체 구현)
# 1) z0 (편향 보정)
obs_lift = lift(control_revenue, treatment_revenue)
prop_below = np.mean(np.array(boot_lifts) < obs_lift)
from scipy.stats import norm
z0 = norm.ppf(prop_below)

# 2) Jackknife (가속도)
jack_lifts = []
for i in range(n_per):
    c_jack = np.delete(control_revenue, i)
    jack_lifts.append(lift(c_jack, treatment_revenue))
for i in range(n_per):
    t_jack = np.delete(treatment_revenue, i)
    jack_lifts.append(lift(control_revenue, t_jack))

jack_mean = np.mean(jack_lifts)
diffs = jack_mean - np.array(jack_lifts)
a_hat = np.sum(diffs**3) / (6 * np.sum(diffs**2)**1.5)

# 3) BCa 분위수
z_alpha_low = norm.ppf(0.025)
z_alpha_high = norm.ppf(0.975)
alpha1 = norm.cdf(z0 + (z0 + z_alpha_low) / (1 - a_hat * (z0 + z_alpha_low)))
alpha2 = norm.cdf(z0 + (z0 + z_alpha_high) / (1 - a_hat * (z0 + z_alpha_high)))

ci_bca = np.percentile(boot_lifts, [alpha1*100, alpha2*100])
print(f"BCa 95 % CI:        ({ci_bca[0]:.4f}, {ci_bca[1]:.4f})")
print(f"\n편향 보정 z0 = {z0:.4f}")
print(f"가속도 a = {a_hat:.4f}")

이 코드가 BCa 계산의 모든 단계 를 보여준다. 실무에서는 scipy.stats.bootstrap(method='BCa') 를 사용해 자동 계산.

9 Software 도구

9.1 Python

  • scipy.stats.bootstrap (1.7+) — Percentile, BCa 자동
  • arch.bootstrap — 시계열 변형
  • bootstrapped — Spotify 의 패키지

9.2 R

  • boot::boot.ci() — 5 가지 방법 (norm, basic, perc, stud, bca)
  • boot.ci(boot_obj, type=c("perc", "bca")) — 동시 비교

9.3 권장

대부분 scipy 또는 R boot 사용. 정확성과 안정성 검증.

10 Bootstrap CI 의 정확성 점검

10.1 Coverage 시뮬레이션

import numpy as np
from scipy.stats import bootstrap

np.random.seed(42)
n_simulations = 1000
n_sample = 30
true_mean = 5  # 진짜 모집단 평균

# 다양한 분포에서 Coverage 측정
def coverage_test(distribution_func, true_value, n_sim=1000):
    coverage = {'percentile': 0, 'BCa': 0, 'normal': 0}
    for _ in range(n_sim):
        sample = distribution_func(n_sample)

        # Percentile
        boots = np.array([np.random.choice(sample, n_sample, replace=True).mean()
                          for _ in range(2000)])
        ci_p = np.percentile(boots, [2.5, 97.5])
        if ci_p[0] < true_value < ci_p[1]:
            coverage['percentile'] += 1

        # BCa
        try:
            res = bootstrap((sample,), np.mean, n_resamples=2000, method='BCa', random_state=0)
            ci_b = (res.confidence_interval.low, res.confidence_interval.high)
            if ci_b[0] < true_value < ci_b[1]:
                coverage['BCa'] += 1
        except:
            pass

        # Normal
        se = boots.std(ddof=1)
        ci_n = (sample.mean() - 1.96*se, sample.mean() + 1.96*se)
        if ci_n[0] < true_value < ci_n[1]:
            coverage['normal'] += 1

    return {k: v/n_sim for k, v in coverage.items()}

# 정규 분포
print("정규 분포 (μ=5, σ=2):")
result = coverage_test(lambda n: np.random.normal(5, 2, n), 5, 200)
print(result)

# 대수정규 (우편향)
print("\n대수정규 (μ=ln(5)-0.5, σ=1):")
true_mean_lognormal = 5
result = coverage_test(lambda n: np.random.lognormal(np.log(5)-0.5, 1, n), 5, 200)
print(result)

# 지수 분포
print("\n지수 분포 (rate=0.2):")
result = coverage_test(lambda n: np.random.exponential(5, n), 5, 200)
print(result)

이 시뮬레이션이 각 방법의 정확성 정량화. BCa 가 비대칭 자료에서 가장 robust.

11 Bootstrap-t 의 자세한 도출

11.1 절차

def studentized_bootstrap_ci(data, n_boot=5000, alpha=0.05):
    """Studentized bootstrap CI"""
    n = len(data)
    obs_mean = data.mean()

    t_stars = []
    for _ in range(n_boot):
        sample = np.random.choice(data, n, replace=True)
        if sample.std(ddof=1) > 0:
            t = (sample.mean() - obs_mean) / (sample.std(ddof=1) / np.sqrt(n))
            t_stars.append(t)

    t_stars = np.array(t_stars)
    t_low, t_high = np.percentile(t_stars, [2.5, 97.5])

    obs_se = data.std(ddof=1) / np.sqrt(n)
    return (obs_mean - t_high * obs_se, obs_mean - t_low * obs_se)

# 사례
data = np.random.lognormal(0, 1, 50)
ci = studentized_bootstrap_ci(data)
print(f"Studentized Bootstrap CI: ({ci[0]:.4f}, {ci[1]:.4f})")

Studentized 부트스트랩이 2 차 정확. BCa 와 비슷하지만 SE 추정 필요.

12 ABC (Approximate Bootstrap Confidence)

ABC Method (DiCiccio & Efron 1992)

분석적 근사 — 부트스트랩 시뮬레이션 대신 분석 공식.

장점: - 빠름 (시뮬레이션 X) - 분석적

단점: - 분포 가정 일부 사용 - 복잡한 통계량에 적용 어려움

13 Bootstrap CI 보고 형식

효과 점추정: 0.45 (단위)
95 % BCa CI: (0.32, 0.58)
Bootstrap 표본 수: B = 5000
방법: BCa (Bias-Corrected accelerated)
편향 보정 z₀: 0.12
가속도 a: 0.05

이 형식이 재현 가능성 + 정확성 정보.

14 R 패키지 비교

패키지 특징
boot 표준, 5 가지 CI 방법
bootstrap Efron 의 원조
simpleboot 단순 인터페이스
rsample tidyverse 통합
infer tidyverse + 검정

15 Python 패키지 비교

패키지 특징
scipy.stats.bootstrap 표준 (1.7+)
arch.bootstrap 시계열 변형
bootstrapped Spotify, percentile + BCa
joblib 병렬화

16 한계와 후속

이 글까지 부트스트랩 CI 의 4 형태 를 다뤘다. 다음 글 A-WOO14-3 는 실무 이슈 (회귀, 분류, 시계열) 를 다룬다.

17 관련 주제

선행 지식

후속 주제 (Phase A)

  • A-WOO14-3 실무 이슈
  • A-WOO14-4 Bootstrap 가설 검정 + 한계

다른 카테고리 연결

Subscribe

Enjoy this blog? Get notified of new posts by email: