콘텐츠로 이동

대안으로서의 붓스트랩

동기

이 장의 앞 절들은 비정규성을 탐지하는 도구 — Q-Q 그림, Shapiro-Wilk 검정, 왜도와 첨도 측도 — 를 제공했다. 이런 진단이 자료가 정규분포에서 크게 벗어남을 드러내면, 표준적인 모수적 방법(\(t\) 분포에 기초한 신뢰구간, \(\chi^2\)나 \(F\) 분포에 기대는 가설검정)이 표방하는 오류율을 더 이상 통제하지 못할 수 있다. 붓스트랩은 모집단 분포에 특정한 모수적 형태를 가정하지 않고 추론을 수행하는 길을 제공한다. 이론적 가정에서 표집분포를 유도하는 대신, 관측된 자료 자체에서 재표본추출하여 표집분포를 추정한다.

붓스트랩의 원리

붓스트랩의 핵심 발상은 개념적으로 단순하다. 고전 통계학에서는 통계량 \(T = T(X_1, X_2, \ldots, X_n)\)의 변동을 이해하기 위해 미지의 모집단 분포 \(F\)에서 표본을 반복해서 뽑는다고 상상한다. 실제로 \(F\)에서 새 표본을 뽑을 수는 없으므로, 붓스트랩은 \(F\) 자리에 경험분포함수 \(\hat{F}_n\)을 대신 놓는다. \(\hat{F}_n\)은 관측된 각 자료점에 확률 \(1/n\)을 부여한다.

\(\hat{F}_n\)에서 표본을 뽑는 것은 관측 자료에서 복원추출하는 것과 같다. 각 붓스트랩 표본 \(X_1^*, X_2^*, \ldots, X_n^*\)은 원래 표본과 크기가 같고 복원추출로 뽑히므로, 어떤 관측값은 여러 번 나타나고 어떤 것은 아예 나타나지 않을 수 있다.

알고리즘

비모수 붓스트랩의 절차는 다음과 같다.

  1. 관측된 표본 \(\mathbf{x} = (x_1, x_2, \ldots, x_n)\)에서 시작한다.
  2. \(b = 1, 2, \ldots, B\)에 대해:
    • \(\mathbf{x}\)에서 복원추출로 \(n\)개의 값을 뽑아 붓스트랩 표본 \(\mathbf{x}^{*b} = (x_1^{*b}, x_2^{*b}, \ldots, x_n^{*b})\)을 만든다.
    • 붓스트랩 복제값 \(\hat{\theta}^{*b} = T(\mathbf{x}^{*b})\)을 계산한다.
  3. 모음 \(\{\hat{\theta}^{*1}, \hat{\theta}^{*2}, \ldots, \hat{\theta}^{*B}\}\)이 \(T\)의 표집분포를 근사한다.

붓스트랩 복제 횟수 \(B\)는 표준오차 추정에는 보통 최소 1000, 신뢰구간 구성에는 최소 5000–10000을 쓴다.

붓스트랩 신뢰구간

백분위수 방법

가장 단순한 붓스트랩 신뢰구간은 붓스트랩 분포의 \(\alpha/2\) 분위수와 \(1 - \alpha/2\) 분위수를 그대로 쓴다.

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

95% 신뢰구간이면 \(B\)개 붓스트랩 복제값의 2.5번째와 97.5번째 백분위수이다.

백분위수 방법의 한계

백분위수 방법은 직관적이지만 붓스트랩 분포가 치우쳐 있거나 통계량이 편향되어 있으면 포함확률이 나쁠 수 있다. 변환에 불변이 아니어서 통계량의 단조변환이 포함확률을 바꿀 수 있다.

BCa(편향보정 가속) 방법

BCa 방법은 붓스트랩 분포의 편향과 치우침을 모두 조정한다. 두 개의 보정 인자로 백분위수 끝점을 수정한다.

  • 편향보정 \(\hat{z}_0\): 붓스트랩 분포의 중앙값이 원래 추정값 \(\hat{\theta}\)에서 얼마나 떨어져 있는지를 잰다
  • 가속 \(\hat{a}\): 참 모수값에 따라 \(\hat{\theta}\)의 표준오차가 변하는 속도를 반영한다

조정된 백분위수는

\[ \alpha_1 = \Phi\!\left(\hat{z}_0 + \frac{\hat{z}_0 + z_{\alpha/2}}{1 - \hat{a}(\hat{z}_0 + z_{\alpha/2})}\right), \quad \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) \]

여기서 \(\Phi\)는 표준정규 누적분포함수이고 \(z_{\alpha/2}\)는 표준정규 분위수이다. \(\hat{z}_0 = 0\)이고 \(\hat{a} = 0\)이면 BCa 방법은 백분위수 방법으로 환원된다. 실무에서 BCa 구간은 대체로 단순한 백분위수 방법보다 나은 포함확률을 제공한다.

보기 1. 소형주 펀드 수익률. 소형주 펀드의 연간 수익률(%) 관측값 12개를 생각하자.

풀이
\[ \mathbf{x} = \{-8.2,\; 3.1,\; 15.7,\; 2.4,\; -1.5,\; 22.3,\; 6.8,\; -3.4,\; 11.2,\; 1.9,\; 18.6,\; 7.5\} \]

표본평균은 \(\bar{x} = 6.37\%\), 표본표준편차는 \(s = 9.20\), 표본왜도는 \(0.257\)이다. 모집단 분포를 가정하지 않고 모평균의 95% 신뢰구간을 만들기 위해 붓스트랩을 적용한다.

1단계. 크기 12인 붓스트랩 표본을 복원추출로 \(B = 5000\)개 뽑는다.

2단계. 각 붓스트랩 표본의 평균을 계산하여 붓스트랩 분포 \(\{\hat{\theta}^{*1}, \ldots, \hat{\theta}^{*5000}\}\)을 만든다.

3단계. 붓스트랩 평균들을 정렬하여 2.5번째와 97.5번째 백분위수를 뽑는다.

아래 코드(난수 씨앗 42)를 실행하면 \(\hat{\theta}^*_{(0.025)} = 1.48\), \(\hat{\theta}^*_{(0.975)} = 11.33\)이 나온다. 모평균 수익률의 95% 백분위수 붓스트랩 신뢰구간은 \([1.48\%,\; 11.33\%]\)이다.

비교를 위해 표준 \(t\) 구간은

\[ \bar{x} \pm t_{0.025,\,11} \cdot \frac{s}{\sqrt{12}} = 6.37 \pm 2.201 \times \frac{9.20}{3.464} = 6.37 \pm 5.85 \]

곧 \([0.52\%,\; 12.21\%]\)이다.

붓스트랩 구간이 좁은 이유는 치우침 때문이 아니다

붓스트랩 구간의 폭은 \(9.84\), \(t\) 구간의 폭은 \(11.69\)로 붓스트랩 쪽이 좁다. 그러나 그 이유를 "자료의 치우침을 반영했기 때문"으로 설명하는 것은 옳지 않다. 이 표본의 왜도는 \(0.257\)로 가볍고, 붓스트랩 평균의 분포는 왜도가 \(0.07\)로 사실상 대칭이다.

진짜 이유는 평균에 대한 백분위수 붓스트랩이 분산을 \(1/n\)로 나눈 편향된 추정값으로 잡는다는 데 있다. 붓스트랩 표준오차 \(2.50\)은 \(s/\sqrt{n} = 2.66\)이 아니라 \(s_{n}/\sqrt{n} = 8.81/3.464 = 2.54\)에 대응한다. 표본이 작을수록 이 차이가 커지므로, 백분위수 붓스트랩 구간은 작은 표본에서 살짝 좁아지는 경향이 있다. 그래서 \(n\)이 작을 때는 BCa나 붓스트랩-t 구간이 권장된다.

붓스트랩 분포는 무엇을 흉내 내는가

붓스트랩이 "표집분포를 추정한다"는 말은 추상적으로 들린다. 실제로 무엇이 일어나는지는 진짜 표집분포를 볼 수 있는 인공 상황을 만들어 보면 분명해진다. 아래 왼쪽 칸에서 모집단은 왜도 \(4.75\)인 대수정규분포이고 \(n = 20\)이다. 회색 히스토그램은 이 모집단에서 20만 번 표본을 뽑아 그린 \(\bar{X}\)의 진짜 표집분포다. 현실에서는 모집단을 모르므로 이 그림을 그릴 수 없다.

붓스트랩 분포가 표집분포의 비대칭을 따라가는 모습과 두 구간의 포함률

주황 계단은 표본 하나에서 복원추출로 만든 붓스트랩 분포다(중심을 맞춰 겹쳤다). 파란 파선은 같은 표본의 \(t\) 근사, 곧 \(N(\bar{X}, s^2/n)\)이다. 회색 히스토그램이 오른쪽으로 길게 늘어진 비대칭 모양임에 주목하라. \(n = 20\)에서는 중심극한정리가 아직 일을 끝내지 못해 표집분포의 왜도가 \(1.06\)이나 된다. 파란 파선은 구조상 이 비대칭을 흉내 낼 수 없다. 좌우 대칭인 종 모양 말고는 그릴 수 있는 것이 없기 때문이다. 주황 계단은 표본 20개만으로도 오른쪽 꼬리가 더 길다는 사실을 잡아낸다. 이것이 "붓스트랩이 모양에 적응한다"는 말의 뜻이다.

그러나 적응한다고 해서 정확해지는 것은 아니다. 오른쪽 칸은 같은 모집단에서 두 구간의 실제 포함률을 1500번씩 재어 본 결과다. \(n = 10\)에서 \(t\) 구간이 \(0.863\), 백분위수 붓스트랩 구간이 \(0.825\)로 붓스트랩 쪽이 오히려 나쁘다. \(n = 20\)에서도 \(0.873\) 대 \(0.861\)이다. 두 곡선이 만나는 것은 \(n = 40\) 언저리이고, \(n = 160\)에서 \(0.937\)과 \(0.940\)으로 나란히 \(0.95\)에 다가간다.

왜 그런가. 앞의 보기에서 본 대로 백분위수 붓스트랩은 분산을 \(1/n\)로 나눈 편향된 형태로 잡으므로 구간이 조금 좁아지고, 게다가 작은 표본에서는 경험분포 \(\hat{F}_n\)이 모집단 \(F\)를 잘 흉내 내지 못한다. 관측값 10개로 만든 경험분포는 값 10개에 확률 \(1/10\)씩을 준 이산분포일 뿐이어서, 아직 보지 못한 꼬리를 알 도리가 없다.

정리하면 이렇다. 붓스트랩은 표집분포의 모양을 담을 수는 있지만 자료에 없는 정보를 만들어 내지는 못한다. 작은 표본에서 정규성이 의심스럽다는 이유로 붓스트랩으로 갈아타는 것은 해결책이 아니며, 표본이 작다는 문제는 어떤 방법으로도 풀리지 않는다. 붓스트랩의 진가는 표본이 어느 정도 있으면서 관심 통계량이 중앙값·상관계수·분위수처럼 이론적 표집분포를 구하기 어려울 때 드러난다.

붓스트랩이 통할 때

붓스트랩은 강력한 도구이지만 만능은 아니다. 그 타당성은 몇 가지 조건에 달려 있다.

  • 표본의 대표성. 붓스트랩은 관측된 자료에서 재표본추출하므로 원래 표본이 모집단을 대표해야 한다. 표본이 아주 작으면(\(n < 15\)) 경험분포가 \(F\)를 잘 근사하지 못해 붓스트랩 구간을 믿을 수 없다.

  • 통계량의 매끄러움. 붓스트랩은 자료의 매끄러운 함수인 통계량(평균, 회귀계수, 상관계수)에서 잘 작동한다. 표본최댓값처럼 매끄럽지 않은 통계량에서는 표준 비모수 붓스트랩이 실패할 수 있다.

  • 독립성. 표준 붓스트랩은 관측값이 독립이라고 가정한다. 시계열이나 군집 자료에는 블록 붓스트랩이나 군집 붓스트랩을 써야 한다.

붓스트랩, 변수변환, 비모수 검정의 비교

정규성이 무너지면 세 가지 대안이 있다. (1) 자료를 변환해 근사적 정규성을 얻은 뒤 표준 방법을 적용한다. (2) 분포 가정을 두지 않는 비모수 검정을 쓴다. (3) 붓스트랩을 쓴다. 변수변환은 모수적 해석 가능성을 유지하지만 적절한 변환을 찾아야 한다. 비모수 검정은 로버스트하지만 (임의의 모수에 대한 신뢰구간 구성이 아니라) 가설검정에 국한되는 경우가 많다. 붓스트랩은 사실상 어떤 통계량에도 적용할 수 있는 가장 유연한 선택지이지만 중간 이상의 표본크기와 더 많은 계산을 요구한다.

보기 2. 평균의 붓스트랩 표준오차에는 닫힌 꼴이 있다. 보기 1의 수익률 12개에 \(B = 5000\)으로 백분위수 붓스트랩을 돌리면 표준오차 \(2.50\%\), 95% 구간 \([1.48\%,\ 11.33\%]\)가 나온다. \(t\) 구간은 \([0.52\%,\ 12.21\%]\)이다.

(1) 자료를 고정했을 때 \(\operatorname{Var}^*(\bar X^*)\)를 해석적으로 구하시오. 그 값은 \(s/\sqrt{n} = 2.66\)과 \(s_{\hat F}/\sqrt{n} = 2.54\) 가운데 어느 것에 대응하는가. \(B\)를 키우면 모의실험이 그 값으로 가는지 확인하시오.

(2) 붓스트랩 구간의 폭 \(9.84\)가 \(t\) 구간의 폭 \(11.69\)보다 좁다. 그 차이 \(1.85\)를 세 조각으로 분해하여 각각 얼마인지 수로 대시오. 이 차이를 "붓스트랩이 자료의 치우침을 반영했기 때문"으로 설명해도 되는가.

풀이

(1) 해석적으로. 자료 \(\mathbf{x} = (x_1, \ldots, x_n)\)을 고정하고 생각한다. 붓스트랩 추출은 경험분포 \(\hat F_n\)에서의 독립동일분포 추출이고, \(\hat F_n\)은 각 \(x_i\)에 확률 \(1/n\)을 준다. 그러므로 붓스트랩 한 점 \(X^*\)의 평균과 분산은

\[ \mathbb{E}^*[X^*] = \sum_{i=1}^n \frac{1}{n} x_i = \bar x, \qquad \operatorname{Var}^*(X^*) = \sum_{i=1}^n \frac{1}{n}(x_i - \bar x)^2 = s_{\hat F}^2 \]

이다. 여기서 \(s_{\hat F}^2 = \frac{1}{n}\sum (x_i - \bar x)^2\)으로, \(n-1\)이 아니라 \(n\)으로 나눈 것이다. \(X_1^*, \ldots, X_n^*\)이 독립이므로

\[ \operatorname{Var}^*(\bar X^*) = \frac{1}{n^2}\sum_{i=1}^n \operatorname{Var}^*(X_i^*) = \frac{s_{\hat F}^2}{n} \]

곧 평균의 붓스트랩 표준오차는 \(s_{\hat F}/\sqrt{n}\)이다. 근사가 아니라 정확한 등식이다. \(B\)를 쓰는 모의실험은 이 값을 추정하는 수단일 뿐이고, \(B \to \infty\)에서 바로 이 값으로 간다.

이 표본에서는 \(s_{\hat F} = 8.8095\), \(\sqrt{n} = 3.4641\)이므로

\[ \frac{s_{\hat F}}{\sqrt{n}} = \frac{8.8095}{3.4641} = 2.5431 \]

이다. 그러므로 답은 \(s_{\hat F}/\sqrt{n} = 2.54\) 쪽이다. \(s/\sqrt{n} = 9.2012/3.4641 = 2.6562\)가 아니다. 두 값의 비는 \(\sqrt{(n-1)/n} = \sqrt{11/12} = 0.9574\)로, \(n\)이 작을수록 벌어진다.

(2) 수치적으로. 먼저 쪽에 실린 코드를 그대로 돌린다.

"""표본평균의 붓스트랩 신뢰구간.

치우친 자료에 비모수 붓스트랩을 적용하고, 정규성을 가정한 t 구간과
견준다. 붓스트랩은 분포를 가정하지 않고 자료 자체를 모집단으로 삼아
재표본을 뽑으므로, 정규성이 의심스러울 때 쓸 만한 대안이 된다.
"""

import numpy as np

# ===================================================================
# 자료 — 수익률 12개. 표본이 작고 치우쳐 있어 정규성을 믿기 어렵다.
# ===================================================================
data = np.array([-8.2, 3.1, 15.7, 2.4, -1.5, 22.3,
                  6.8, -3.4, 11.2, 1.9, 18.6, 7.5])

# ===================================================================
# 붓스트랩 — 자료에서 복원추출로 같은 크기의 재표본을 5000번 만들고
# 그때마다 평균을 기록한다. 그 5000개의 흩어짐이 곧 표본평균의
# 표집분포에 대한 추정이다.
# ===================================================================
rng = np.random.default_rng(42)
B = 5000
n = len(data)

bootstrap_means = np.array([
    np.mean(rng.choice(data, size=n, replace=True))
    for _ in range(B)
])

# ===================================================================
# 백분위 신뢰구간 — 재표본 평균들의 2.5·97.5 백분위점을 그대로 쓴다.
# t 구간과 달리 좌우가 대칭일 까닭이 없어, 치우친 자료에서는 한쪽이
# 더 길게 나온다. 그것이 오히려 자료를 제대로 담은 결과다.
# ===================================================================
ci_lower, ci_upper = np.percentile(bootstrap_means, [2.5, 97.5])

if __name__ == "__main__":
    print(f"Sample mean: {np.mean(data):.2f}%")
    print(f"Bootstrap SE: {np.std(bootstrap_means, ddof=0):.2f}%")
    print(f"95% Percentile CI: [{ci_lower:.2f}%, {ci_upper:.2f}%]")

출력:

Sample mean: 6.37%
Bootstrap SE: 2.50%
95% Percentile CI: [1.48%, 11.33%]

이제 (1)의 이론값과 맞춰 보고, 구간 폭을 분해한다.

import numpy as np
from scipy import stats

data = np.array([-8.2, 3.1, 15.7, 2.4, -1.5, 22.3,
                  6.8, -3.4, 11.2, 1.9, 18.6, 7.5])
n = len(data)
s_hat = data.std(ddof=0)      # 1/n 로 나눈 것. 경험분포의 표준편차다.
s = data.std(ddof=1)          # 1/(n-1) 로 나눈 보통의 표본표준편차

print(f"이론  s_hat/sqrt(n) = {s_hat:.4f} / {np.sqrt(n):.4f} = {s_hat/np.sqrt(n):.4f}")
print(f"대조  s/sqrt(n)     = {s:.4f} / {np.sqrt(n):.4f} = {s/np.sqrt(n):.4f}")

# B 를 키우면 몬테카를로 추정이 이론값으로 간다.
for B in [5_000, 50_000, 500_000]:
    rng = np.random.default_rng(42)
    idx = rng.integers(0, n, size=(B, n))
    boot = data[idx].mean(axis=1)
    print(f"B = {B:7d}  붓스트랩 SE = {boot.std(ddof=0):.4f}")

# 구간 폭을 세 단계로 분해한다.
t = stats.t.ppf(0.975, n - 1)
z = stats.norm.ppf(0.975)
print(f"t 구간 폭            = 2 x {t:.4f} x {s/np.sqrt(n):.4f} = {2*t*s/np.sqrt(n):.3f}")
print(f"t 를 z 로 바꾸면     = 2 x {z:.4f} x {s/np.sqrt(n):.4f} = {2*z*s/np.sqrt(n):.3f}")
print(f"s 를 s_hat 로 바꾸면 = 2 x {z:.4f} x {s_hat/np.sqrt(n):.4f} = {2*z*s_hat/np.sqrt(n):.3f}")

출력:

이론  s_hat/sqrt(n) = 8.8095 / 3.4641 = 2.5431
대조  s/sqrt(n)     = 9.2012 / 3.4641 = 2.6562
B =    5000  붓스트랩 SE = 2.4994
B =   50000  붓스트랩 SE = 2.5431
B =  500000  붓스트랩 SE = 2.5396
t 구간 폭            = 2 x 2.2010 x 2.6562 = 11.692
t 를 z 로 바꾸면     = 2 x 1.9600 x 2.6562 = 10.412
s 를 s_hat 로 바꾸면 = 2 x 1.9600 x 2.5431 = 9.969

(1)의 확인. 유도한 값은 \(2.5431\)이고 \(B = 5000\)의 모의실험은 \(2.4994\)를 주었다. 차이가 \(0.044\)인데, 표준편차 추정의 몬테카를로 오차가 대략 \(\mathrm{SE}/\sqrt{2B} = 2.543/100 = 0.025\)이므로 \(1.7\)배쯤 벗어난 셈이다. 우연으로 설명되는 크기다. \(B\)를 열 배로 키우면 \(2.5431\), 백 배로 키우면 \(2.5396\)(오차 척도 \(0.0025\))이 되어 이론값 주위를 맴돈다. \(B\)를 아무리 키워도 \(2.6562\) 쪽으로는 가지 않는다. 쪽에 적힌 \(2.50\%\)는 \(s/\sqrt{n}\)의 추정값이 아니라 \(s_{\hat F}/\sqrt{n}\)의 추정값이다.

여기서 눈여겨볼 것은 \(B\)가 지우는 오차와 \(n\)이 지우는 오차가 다른 것이라는 점이다. \(B\)를 키우면 몬테카를로 잡음만 사라지고 \(2.5431\)이라는 값 자체는 꼼짝하지 않는다. 그 값은 자료 12개가 정해 놓은 것이다. 붓스트랩 복제를 백만 번 한다고 표본이 커지지는 않는다.

(2) 폭의 차이는 치우침에서 오지 않는다. 분해하면 이렇다.

단계 폭 줄어든 양
\(t\) 구간 \(\bar x \pm t_{0.975,11}\, s/\sqrt{n}\) \(11.692\) —
분위수를 \(t_{0.975,11} = 2.2010\)에서 \(z_{0.975} = 1.9600\)으로 \(10.412\) \(1.280\)
척도를 \(s\)에서 \(s_{\hat F}\)로 \(9.969\) \(0.443\)
실제 붓스트랩 백분위수 구간 \(9.842\) \(0.127\)

세 조각의 몫이 \(1.280 : 0.443 : 0.127\)이다. 가장 큰 조각은 \(t\) 분위수를 잃은 것이다. 백분위수 붓스트랩은 \(n-1 = 11\)이라는 자유도 보정을 아예 하지 않으므로, 꼬리가 두꺼운 \(t_{11}\) 대신 정규 분위수에 해당하는 폭을 쓴다. 둘째 조각이 (1)에서 본 \(\sqrt{11/12}\) 축소다. 남은 \(0.127\)은 붓스트랩 분포가 정규가 아닌 데서 오는 몫과 \(B = 5000\)의 몬테카를로 잡음이 섞인 것이다.

그러므로 "치우침을 반영했기 때문"이라는 설명은 옳지 않다. 실제로 치우침은 거의 없다. 이 표본의 왜도는 \(g_1 = 0.2569\)(scipy.stats.skew의 기본값 bias=True)로 가볍고, 붓스트랩 평균 5000개의 왜도는 \(g_1 = 0.0719\)로 사실상 대칭이다. 구간의 좌우도 중심 \(\bar x = 6.367\)에서 왼쪽 \(4.883\), 오른쪽 \(4.958\)로 \(1.5\%\)밖에 차이 나지 않는다. 치우침이 폭을 \(1.85\)나 줄일 수는 없다.

쪽 앞의 경고 상자가 말하는 그대로다. 백분위수 붓스트랩이 작은 표본에서 좁아지는 것은 자료의 모양을 잘 담아서가 아니라 자유도 보정과 분산 보정을 둘 다 빼먹어서다. \(n\)이 작을 때 BCa나 붓스트랩-\(t\)를 권하는 이유가 여기 있다.

연습문제

연습문제 1. 정규성을 가정하지 않고 모평균의 신뢰구간을 구성하는 비모수 붓스트랩 절차를 기술하라.

풀이
  1. 크기 \(n\)인 원래 표본에서 (각각 크기 \(n\)인) 붓스트랩 표본 \(B\)개를 복원추출로 뽑는다.
  2. 각 붓스트랩 표본 \(b = 1, \dots, B\)에 대해 \(\bar{X}^*_b\)(붓스트랩 표본평균)을 계산한다.
  3. \(\bar{X}^*\)의 붓스트랩 분포에서 신뢰구간을 만든다.
  4. 백분위수 방법: \(B\)개 붓스트랩 평균의 \(\alpha/2\)와 \(1-\alpha/2\) 분위수를 쓴다.
  5. 붓스트랩-t 방법: 붓스트랩 t 통계량을 계산하고 그 분위수를 쓴다.
  6. 흔한 선택은 \(B = 10{,}000\)번의 붓스트랩 복제이다.

정규성 가정이 필요 없다. \(\bar{X}^*\)의 붓스트랩 분포가 \(\bar{X}\)의 표집분포를 흉내 내므로 치우쳤거나 꼬리가 두꺼운 자료에서도 타당한 추론이 가능하다.

연습문제 2. 붓스트랩이 실패하거나 성능이 나쁜 경우는 언제인가? 두 조건을 들어라.

풀이
  1. 작은 \(n\)에서의 극단 분위수: 붓스트랩은 원래 표본의 범위를 벗어나는 값을 만들어 낼 수 없다. 작은 \(n\)에서 극단 분위수(예: 99번째 백분위수)를 추정하면 꼬리의 변동을 과소평가한다.

  2. 종속 자료: 표준 비모수 붓스트랩은 관측값이 독립동일분포라고 가정한다. 자료가 종속이면(시계열, 공간 자료) 개별 관측값을 재표본추출하는 것이 종속 구조를 파괴하여 타당하지 않은 결과를 낸다. 블록 붓스트랩이나 정상 붓스트랩이 필요하다.

추가로: (3) \(n\)이 매우 작을 때(경험분포가 모집단을 잘 근사하지 못한다), (4) 불규칙한 통계량(예: 표본최댓값, 붓스트랩 분포가 제대로 수렴하지 않는다).

연습문제 3. 자료가 오른쪽으로 치우쳤을 때 평균의 붓스트랩 신뢰구간과 t 구간을 비교하라. 어느 쪽의 포함확률이 더 나을 것으로 기대되는가?

풀이

중간 정도의 \(n\)을 갖는 오른쪽 치우침 자료에서는 붓스트랩 백분위수 구간의 포함확률이 더 나을 것으로 기대된다. 표집분포의 대칭성을 가정하지 않기 때문이다.

\(t\) 구간 \(\bar{X} \pm t_{\alpha/2} s/\sqrt{n}\)은 \(\bar{X}\)를 중심으로 대칭이지만, \(\bar{X}\)의 참 표집분포는 (자료에서 물려받아) 치우쳐 있다. 그래서 \(t\) 구간은 한쪽을 과다 포함하고 다른 쪽을 과소 포함한다.

붓스트랩 백분위수 구간은 이 비대칭을 자연스럽게 포착한다. \(\bar{X}^*\)의 붓스트랩 분포가 치우쳐 있으면 구간도 비대칭이 되어 참 표집분포에 더 잘 맞는다. 치우친 자료에서 최선의 성능을 원한다면 편향보정 가속(BCa) 붓스트랩 구간이 권장된다.

연습문제 4. 자료의 중앙값에 대한 95% 붓스트랩 신뢰구간을 계산하는 Python 코드를 작성하라.

풀이
import numpy as np

rng = np.random.default_rng(42)
data = rng.exponential(scale=5, size=50)  # skewed data

B = 10000
boot_medians = np.array([
    np.median(rng.choice(data, size=len(data), replace=True))
    for _ in range(B)
])

ci_lower = np.percentile(boot_medians, 2.5)
ci_upper = np.percentile(boot_medians, 97.5)
print(f"Sample median: {np.median(data):.3f}")
print(f"95% Bootstrap CI: ({ci_lower:.3f}, {ci_upper:.3f})")

출력:

Sample median: 3.243
95% Bootstrap CI: (1.831, 5.420)

중앙값의 표집분포에는 간단한 닫힌 형태의 공식이 없지만, 붓스트랩은 평균일 때와 똑같은 절차로 구간을 준다. 백분위수 방법을 쓴 것이다. 이 구간은 정규성 가정 없이 타당하며, 반복문 안에서 계산하는 통계량만 바꾸면 어떤 통계량(평균, 중앙값, 상관 등)에도 쓸 수 있다.


정리하며

부트스트랩은 분포 가정 없이 추론한다.

  • \(F\) 자리에 \(\hat F_n\) 을 넣는 것이 전부다. 모집단에서 반복 표집한다는 상상을, 관측 자료에서 복원추출하는 실제 계산으로 바꾼다.
  • 글리벤코–칸텔리가 근거다. \(\hat F_n\) 이 \(F\) 로 균등수렴하므로 그 위에서의 계산이 참 표집분포에 가까워진다.
  • 변환과 달리 척도를 바꾸지 않는다. 원래 단위로 답을 주므로 해석이 그대로 유지된다. 변환의 가장 큰 대가를 치르지 않는다.
  • 만능은 아니다. 표본이 모집단을 대표하지 못하면 그 편향을 복제하고, 최댓값이나 꼬리 분위수처럼 극단에 의존하는 통계량에서는 실패한다.
  • 17장에서 본격적으로 다룬다. 여기서는 정규성 위반의 대처법으로서 자리를 잡는다.

다음 절 비모수 방법으로 넘어간다.