백분위수법¶
동기¶
가장 단순한 붓스트랩 신뢰구간은 붓스트랩 분포의 분위수를 그대로 쓴다. \(\hat{\theta}\)의 표본분포가 정규라고 가정하는 대신, 백분위수법은 구간의 양 끝점을 붓스트랩 복제값에서 직접 읽는다. 그 결과 구간이 본질적으로 적응적이다. 치우침을 존중하고, 모수의 자연스러운 경계를 존중하며, 표준오차 공식이 전혀 필요 없다.
단순함에도 불구하고 백분위수법에는 잘 알려진 이론적 한계가 있다. 이 절에서는 방법을 제시하고, 언제 잘 작동하는지 설명하며, 더 정교한 방법이 필요한 상황을 밝힌다.
정의 1. 백분위수 붓스트랩 신뢰구간¶
관측자료에서 복원추출하여 각 재표본에서 통계량 \(\hat{\theta}\)를 계산해 얻은 붓스트랩 복제값을 \(\hat{\theta}^{*(1)}, \ldots, \hat{\theta}^{*(B)}\)이라 하자. 수준 \(1 - \alpha\)의 백분위수 붓스트랩 신뢰구간은
이며 \(\hat{\theta}^*_{(q)}\)는 붓스트랩 분포의 \(q\)번째 분위수이다. 95% 신뢰구간(\(\alpha = 0.05\))은 붓스트랩 복제값의 2.5 백분위수부터 97.5 백분위수까지이다.
실제로 복제값을 오름차순으로 정렬하여 \(\hat{\theta}^*_{[1]} \le \hat{\theta}^*_{[2]} \le \cdots \le \hat{\theta}^*_{[B]}\)라 하면, 하한은 \(\hat{\theta}^*_{[\lfloor B \cdot \alpha/2 \rfloor]}\), 상한은 \(\hat{\theta}^*_{[\lceil B \cdot (1-\alpha/2) \rceil]}\)이다.
알고리즘¶
- 관측 통계량 \(\hat{\theta} = g(x_1, \ldots, x_n)\)을 계산한다.
- \(B\)개의 붓스트랩 복제값 \(\hat{\theta}^{*(1)}, \ldots, \hat{\theta}^{*(B)}\)을 생성한다.
- 복제값을 오름차순으로 정렬한다.
- \(100(1-\alpha)\%\) 신뢰구간은
백분위수 구간에 필요한 B
백분위수법에서는 극단 분위수가 안정될 만큼 \(B\)가 커야 한다. \(B = 1{,}000\)이면 2.5 백분위수는 25번째로 작은 값이라 그런대로 쓸 만하지만 잡음이 있다. \(B = 10{,}000\)이면 250번째 값이 되어 훨씬 안정적이다. 신뢰구간에는 최소 \(B = 5{,}000\)을 권한다.
백분위수법이 작동하는 이유¶
백분위수법에는 우아한 정당화가 있다. \(\hat{\phi} = m(\hat{\theta})\)가 분산이 일정한 정규분포를 갖게 하는 단조변환 \(\phi = m(\theta)\)가 존재한다고 하자. 그러면 \(\hat{\phi}\)는 (위치 이동을 제외하고) 추축량이고, \(\phi\)에 대한 백분위수 구간의 포함확률이 정확하다. \(m\)이 단조이므로 되돌리면
가 된다. \(\theta\) 척도의 백분위수 구간이 \(\phi\) 척도의 구간을 되돌린 것과 동일하므로, 사용자가 \(m\)을 알 필요 없이 정규화 변환이 자동으로 반영된다.
변환 불변성
백분위수법은 변환 불변이다. 임의의 단조증가 함수 \(m\)에 대해 \(\phi = m(\theta)\)이면 \(\phi\)의 백분위수 구간은 정확히 \([m(\hat{\theta}^*_{(\alpha/2)}), m(\hat{\theta}^*_{(1-\alpha/2)})]\)이다. 정규근사 구간 \(\hat{\theta} \pm z_{\alpha/2} \cdot \widehat{\text{SE}}\)에는 이 성질이 없다.
이 주장은 말로 들으면 미덥지 않다. 척도를 바꾸었는데 답이 그대로라니, 정말 그런지 한 자료에서 확인해 보자.

\(\text{LogNormal}(0, 1)\)에서 \(n = 40\)을 뽑아 평균의 붓스트랩 복제값 \(B = 40000\)개를 만들었다. 왼쪽은 그 복제값에 로그를 취한 것으로 거의 대칭이고, 오른쪽은 원 척도로 오른쪽 꼬리가 길다. 두 그림은 같은 4만 개 숫자이며, 눈금만 다르다. 어느 쪽에서 구간을 만들어야 옳은지는 이론이 답해 준다. 표본분포를 정규에 가깝게 만드는 척도, 즉 로그 척도이다.
오른쪽 칸의 네 막대가 결론이다. 원 척도에서 바로 읽은 백분위수 구간이 \([0.9652,\ 1.5945]\)이고, 로그 척도에서 읽은 뒤 지수변환해 되돌린 구간도 \([0.9652,\ 1.5945]\)이다. 소수 넷째 자리까지 같다. 이유는 정의에서 곧바로 나온다. \(\log\)가 단조증가이므로 \(\text{Quantile}_q(\log \bar{x}^*) = \log(\text{Quantile}_q(\bar{x}^*))\)이고, 분위수를 읽고 변환하든 변환하고 읽든 순서가 상관없기 때문이다.
정규근사 구간은 그렇지 않다. 원 척도에서 \([0.9464,\ 1.5780]\), 로그 척도를 거치면 \([0.9817,\ 1.6229]\)로 하한이 \(3.7\%\) 차이 난다. 평균과 표준오차는 분위수와 달리 단조변환과 교환되지 않기 때문이다. 문제는 어느 쪽이 맞느냐를 사용자가 판단해야 한다는 점이다. 로그 척도가 낫다는 것을 알려면 표본분포의 모양을 이미 알고 있어야 하는데, 그 모양을 모르기 때문에 붓스트랩을 쓰는 것이다.
백분위수법의 가치가 여기에 있다. 정규화 변환 \(m\)이 무엇인지 몰라도, 그것을 찾아 적용한 뒤 되돌린 것과 똑같은 답을 준다. 다만 이 우아함이 포함확률을 보장하지는 않는다. 아래에서 보듯 애초에 그런 \(m\)이 존재하지 않는 통계량에서는 변환 불변성이 지켜 줄 것이 없다.
장점¶
- 단순함: 표준오차 공식이 필요 없다.
- 변환 불변성: 임의의 단조 재모수화에 구간이 자동으로 적응한다.
- 모수 경계를 존중한다: \(\theta \ge 0\)이고 모든 붓스트랩 복제값이 음이 아니면 구간도 음이 아니다.
- 모양을 포착한다: 붓스트랩 분포가 비대칭이면 신뢰구간도 비대칭이 된다.
한계¶
백분위수법은 1차 정확도를 갖는다. 즉 포함확률 오차가 \(O(n^{-1/2})\)이다. 중간 정도의 표본크기에서 눈에 띄는 과소·과대 포함이 생길 수 있다. 오차의 주된 원천은 다음과 같다.
편향. \(\hat{\theta}^*\)의 붓스트랩 분포가 \(\hat{\theta}\)에서 벗어난 곳에 중심을 두면(즉 붓스트랩에 편향이 있으면) 백분위수 구간이 잘못된 방향으로 이동한다. 예를 들어 \(\hat{\theta}\)가 \(\theta\)를 체계적으로 과대추정하면 붓스트랩 복제값이 \(\theta\)보다 위에 중심을 두고, 백분위수 구간도 너무 높아진다.
정규화 변환이 없는 치우침. \(\hat{\theta}\)의 표본분포를 근사적으로 정규로 만드는 단조변환이 존재하지 않으면, 백분위수 구간의 한쪽 포함확률이 크게 틀릴 수 있다.
포함확률이 나쁠 수 있다
모의실험 연구에 따르면 명목수준이 95%일 때 백분위수법의 실제 포함확률이 85--90%에 그칠 수 있다. 표본분산, 오즈비, 소표본 상관계수처럼 치우친 통계량에서 특히 그렇다. BCa와 붓스트랩-\(t\) 방법이 이 결함을 다룬다.
보기 1. 중앙값의 신뢰구간. 오른쪽으로 치우친 분포에서 \(n = 25\)인 표본을 얻었고 표본중앙값이 \(\hat{\theta} = 14.3\)이라 하자.
풀이
백분위수 붓스트랩 절차:
- 중앙값의 붓스트랩 복제값 \(B = 10{,}000\)개를 생성한다.
- 복제값을 정렬한다.
- 95% 신뢰구간은 \([\hat{\theta}^*_{[250]}, \hat{\theta}^*_{[9750]}]\)이다.
정렬된 붓스트랩 중앙값이 \(\hat{\theta}^*_{[250]} = 11.8\), \(\hat{\theta}^*_{[9750]} = 16.5\)였다고 하자. 95% 백분위수 구간은 \([11.8, 16.5]\)이다.
이 구간이 관측된 중앙값 \(14.3\)을 중심으로 비대칭임에 주목하라. 하한까지의 거리 \(2.5\)가 상한까지의 거리 \(2.2\)와 다르며, 이는 표본분포의 치우침을 반영한 것이다.
정규구간과의 비교¶
정규 붓스트랩 구간은 붓스트랩 표준오차를 쓴다.
이 구간은 언제나 \(\hat{\theta}\)를 중심으로 대칭이며 모수의 자연스러운 경계를 넘어갈 수 있다. 백분위수 구간은 두 문제를 모두 피하지만 붓스트랩 분포의 편향에 취약하다.
기본(추축) 붓스트랩 구간은 편향을 보정하려 한다.
분위수가 뒤바뀐 것에 주목하라. 기본 구간은 백분위수 구간의 1차 편향을 보정하지만 변환 불변성을 잃는다.
연습문제¶
연습문제 1. 백분위수 구간의 변환 불변성을 수치로 확인하라. 로그정규 자료의 평균에 대해 (a) 원 척도에서 백분위수 구간을 구한 것과 (b) 로그 척도에서 구간을 구한 뒤 지수변환한 것을 비교하라. 정규근사 구간에서는 어떤가?
풀이
import numpy as np
rng = np.random.default_rng(0)
n = 40
x = rng.lognormal(0, 1, n)
B = 20000
idx = rng.integers(0, n, (B, n))
m = x[idx].mean(axis=1) # 원 척도 붓스트랩 복제값
lm = np.log(m) # 로그 척도 복제값
# 백분위수 구간
print(np.round(np.percentile(m, [2.5, 97.5]), 4))
print(np.round(np.exp(np.percentile(lm, [2.5, 97.5])), 4))
# 정규근사 구간
th = x.mean()
print(np.round([th - 1.96*m.std(ddof=1), th + 1.96*m.std(ddof=1)], 4))
lth = np.log(th); lse = lm.std(ddof=1)
print(np.round(np.exp([lth - 1.96*lse, lth + 1.96*lse]), 4))
출력:
[0.9639 1.591 ]
[0.9639 1.591 ]
[0.9468 1.5776]
[0.9816 1.6231]
| 방법 | 구간 |
|---|---|
| 백분위수, 원 척도 | \([0.9639, \; 1.5910]\) |
| 백분위수, 로그 척도 → 지수변환 | \([0.9639, \; 1.5910]\) |
| 정규근사, 원 척도 | \([0.9468, \; 1.5776]\) |
| 정규근사, 로그 척도 → 지수변환 | \([0.9816, \; 1.6231]\) |
백분위수 구간이 소수점 이하 전부 일치한다. 우연이 아니라 정의에서 따라 나오는 항등식이다. \(\log\)가 단조증가이므로 \(\log(m)\)의 \(q\)번째 분위수는 \(m\)의 \(q\)번째 분위수의 로그와 정확히 같다.
정규근사 구간은 척도에 따라 다르다. 원 척도에서 \([0.947, 1.578]\), 로그 척도를 거치면 \([0.982, 1.623]\)이다. 하한이 4% 차이 난다.
어느 쪽이 옳은가? 로그 척도를 거친 쪽이 낫다. 로그정규 평균의 표본분포가 오른쪽으로 치우쳐 있어 로그를 취하면 정규에 가까워지기 때문이다. 그러나 이를 알려면 사용자가 올바른 변환을 미리 알아야 한다.
백분위수법의 가치가 여기에 있다. 어떤 변환이 정규화 변환인지 몰라도, 그 변환을 적용한 결과와 같은 답을 준다.
연습문제 2. 백분위수법의 1차 정확도가 실제로 어떤 결과를 낳는가? \(\text{Exp}(1)\) 자료의 표본분산(참값 \(= 1\))에 대해 \(n = 25, 100, 400\)에서 포함확률을 계산하라.
풀이
import numpy as np
rng = np.random.default_rng(3)
for n in (25, 100, 400):
M, B = 1500, 1000
cn = cp = cb = 0
for _ in range(M):
x = rng.exponential(1, n)
th = x.var(ddof=1)
idx = rng.integers(0, n, (B, n))
bs = x[idx].var(axis=1, ddof=1)
se = bs.std(ddof=1)
cn += th - 1.96*se <= 1.0 <= th + 1.96*se
lo, hi = np.percentile(bs, [2.5, 97.5])
cp += lo <= 1.0 <= hi
cb += 2*th - hi <= 1.0 <= 2*th - lo
print(n, round(cn/M, 3), round(cp/M, 3), round(cb/M, 3))
출력:
25 0.743 0.744 0.726
100 0.845 0.851 0.831
400 0.914 0.916 0.907
| \(n\) | 정규 | 백분위수 | 기본 |
|---|---|---|---|
| 25 | 0.743 | 0.744 | 0.726 |
| 100 | 0.845 | 0.851 | 0.831 |
| 400 | 0.914 | 0.916 | 0.907 |
세 방법 모두 명목수준에 크게 못 미친다. \(n = 25\)에서 \(0.74\), \(n = 400\)에서도 \(0.92\)에 그친다.
포함확률 오차가 \(n^{-1/2}\)에 비례하여 줄어드는 것을 확인할 수 있다. \(0.95 - 0.744 = 0.206\), \(0.95 - 0.851 = 0.099\), \(0.95 - 0.916 = 0.034\)이고, \(n\)이 16배가 될 때 오차가 대략 4배 줄었다(\(0.206/0.099 = 2.08 \approx \sqrt{4}\), \(0.099/0.034 = 2.9 \approx \sqrt{4}\)). 이것이 "1차 정확도, \(O(n^{-1/2})\)"의 구체적 의미이다.
왜 분산이 이렇게 어려운가. \(s^2\)의 표본분포는 모집단의 4차 적률에 지배되는데, 지수분포의 초과첨도는 \(6\)이다. 붓스트랩 재표집이 원표본의 4차 적률을 그대로 물려받으므로, \(n\)이 작으면 그 추정 자체가 매우 불안정하다.
어떻게 개선하는가. BCa나 붓스트랩-\(t\)를 쓰면 2차 정확도 \(O(n^{-1})\)를 얻는다. 또는 로그변환처럼 분산을 안정화하는 변환 위에서 구간을 만든 뒤 되돌리는 방법도 있다.
연습문제 3. \(B\)가 백분위수 구간의 안정성에 미치는 영향을 정량화하라. 같은 자료에 붓스트랩을 여러 번 반복하면 구간의 끝점이 얼마나 흔들리는가?
풀이
자료를 고정하고 붓스트랩 절차만 반복한다. 이때 관측되는 변동은 순전히 몬테카를로 오차이다.
import numpy as np
rng = np.random.default_rng(5)
n = 50
x = rng.exponential(1, n) # 자료 고정
for B in (500, 2000, 10000, 50000):
los, his = [], []
for _ in range(200):
idx = rng.integers(0, n, (B, n))
bs = x[idx].mean(axis=1)
lo, hi = np.percentile(bs, [2.5, 97.5])
los.append(lo); his.append(hi)
print(B, round(np.std(los), 5), round(np.std(his), 5),
round(np.mean(his) - np.mean(los), 5))
출력:
500 0.01 0.01093 0.35653
2000 0.00514 0.00597 0.35877
10000 0.00197 0.00235 0.35929
50000 0.0011 0.00112 0.35964
| \(B\) | 하한의 표준편차 | 상한의 표준편차 | 평균 구간 폭 |
|---|---|---|---|
| 500 | 0.01000 | 0.01093 | 0.35653 |
| 2000 | 0.00514 | 0.00597 | 0.35877 |
| 10000 | 0.00197 | 0.00235 | 0.35929 |
| 50000 | 0.00110 | 0.00112 | 0.35964 |
끝점의 몬테카를로 표준편차가 \(\sqrt{B}\)에 반비례하여 줄어든다. \(B\)가 100배가 되면 변동이 약 10배 줄어든다(\(0.0100 \to 0.0011\)).
실무적 판단 기준. 구간 폭이 \(0.359\)인데 \(B = 500\)에서 끝점의 변동이 \(0.010\)이다. 폭의 2.8%로, 무시할 만하다고 보기에는 애매하다. \(B = 10{,}000\)이면 \(0.0020\)으로 폭의 0.55%가 되어 안전하다.
경험칙: 끝점의 몬테카를로 표준오차가 구간 폭의 1% 아래가 되도록 \(B\)를 정한다. 대체로 \(B = 5{,}000\)--\(10{,}000\)이면 충분하다.
한 가지 함정. \(B\)를 늘려도 자료 자체의 변동은 전혀 줄지 않는다. 위 표의 평균 구간 폭이 \(B\)에 따라 거의 변하지 않는 것에 주목하라. \(B\)는 붓스트랩 근사의 잡음만 줄일 뿐, 표본이 하나뿐이라는 근본적 한계는 그대로이다.
연습문제 4. 편향된 추정량에서 백분위수 구간과 기본 구간이 어떻게 달라지는가? \(X_i \sim \mathcal{N}(\mu, 1)\)에서 \(\theta = \mu^2\)을 \(\hat{\theta} = \bar{X}^2\)으로 추정하는 경우를 보라.
풀이
\(\hat{\theta} = \bar{X}^2\)은
이므로 \(1/n\)만큼 위로 편향되어 있다.
import numpy as np
rng = np.random.default_rng(8)
n, B, M = 20, 2000, 3000
mu, true = 0.5, 0.25
cov_p = cov_b = 0
for _ in range(M):
x = rng.normal(mu, 1, n)
th = x.mean() ** 2
idx = rng.integers(0, n, (B, n))
bs = x[idx].mean(axis=1) ** 2
lo, hi = np.percentile(bs, [2.5, 97.5])
cov_p += lo <= true <= hi
cov_b += 2*th - hi <= true <= 2*th - lo
print(round(cov_p/M, 3), round(cov_b/M, 3))
출력:
0.932 0.732
\(\mu = 0.5\), \(n = 20\), 참값 \(\theta = 0.25\):
| 방법 | 포함확률 |
|---|---|
| 백분위수 | 0.932 |
| 기본 (추축) | 0.732 |
기본 구간이 훨씬 나쁘다. 편향을 보정하도록 설계된 방법이 오히려 무너진다.
왜 그런가. 두 힘이 반대로 작용한다.
-
편향. 붓스트랩 복제값 \(\bar{X}^{*2}\)의 평균이 \(\hat{\theta}\)보다 크다. 실제로 확인하면
x = rng.normal(0.5, 1, 20) idx = rng.integers(0, 20, (20000, 20)) bs = x[idx].mean(axis=1) ** 2 print(round(x.mean()**2, 4), round(bs.mean(), 4)) # 0.7267 0.8094출력:
0.7267 0.8094차이 \(0.083\)은 정확히 \(\hat\sigma^2/n\)이다(\(\bar{X}^{*2}\)의 기댓값이 \(\hat\theta + \text{Var}^*(\bar{X}^*)\)이므로). 이 편향만 보면 기본 구간의 반사가 옳은 방향이다.
-
치우침. \(\bar{X}^2\)은 제곱이므로 \(0\)이라는 바닥이 있고 붓스트랩 분포가 오른쪽으로 심하게 치우친다. 참 표본분포도 같은 방향으로 치우쳐 있다. 기본 구간의 반사가 이 치우침을 왼쪽으로 뒤집어 버린다.
이 자료에서는 두 번째 효과가 압도적이라 기본 구간이 크게 실패한다. 붓스트랩 방법 연습문제 1에서 지수분포 중앙값에 대해 본 것과 정확히 같은 현상이다.
그렇다면 편향은 어떻게 다루는가. 반사가 아니라 명시적인 편향보정을 쓴다.
- 복제값에서 \(\widehat{\text{Bias}} = \bar{\hat\theta}^* - \hat\theta\)를 빼고 백분위수 구간을 만든다.
- 또는 BCa를 쓴다. \(\hat z_0\)이 편향을, \(\hat a\)가 치우침을 각각 따로 조정하므로 두 효과가 서로 상쇄되지 않는다.
경계 모수의 함정. \(\mu = 0\)이면 상황이 더 나빠진다. \(\theta = 0\)이 모수공간의 경계에 있어 \(\hat\theta \ge 0\)이 언제나 성립하고, 어떤 붓스트랩 구간도 \(0\)을 잘 덮지 못한다. 경계 모수는 붓스트랩의 알려진 실패 지점이며 BCa로도 고쳐지지 않는다.
정리하며¶
백분위수법은 붓스트랩 분포에서 분위수를 직접 읽어 신뢰구간을 만든다. 단순함, 변환 불변성, 모수 경계를 존중하는 성질 덕에 자연스러운 출발점이 된다. 그러나 1차 정확도에 그치므로 붓스트랩 분포에 편향이 있거나 정규화 변환이 존재하지 않을 때 포함확률이 나빠질 수 있다. 포함확률을 개선하려면 이어지는 절의 BCa와 붓스트랩-\(t\) 방법이 2차 보정을 제공한다.