§5.2 Bootstrap 自助抽樣法

📖 ISLP §5.2 📄 pp. 204–210 ⭐⭐ ⏱️ 約 25 分鐘
Bootstrap Resampling 標準誤差 信賴區間 Portfolio

📚 理論核心

📖 課本文獻引用:
James, G., Witten, D., Hastie, T., & Tibshirani, R. (2023). An Introduction to Statistical Learning with Applications in Python. Springer. §5.2 The Bootstrap.
💡 核心概念(生活化比喻): Bootstrap 就像「用一面鏡子照出另一個自己,重複一千次來研究自己的身高變化」。我們手上只有一組樣本(n 個觀測值),無法重複抽樣,所以 Bootstrap 把這組樣本當作母體,從中進行有放回的重複抽樣(每次抽 n 個),計算感興趣的統計量(如平均數、迴歸係數),然後用這 B 個統計量的標準差來估計該統計量的標準誤差。不需要數學公式、不需要假設母體分布,就能量化任何估計量的不確定性。
\[ \hat{\alpha} = \frac{\hat{\sigma}_Y^2 - \hat{\sigma}_{XY}}{\hat{\sigma}_X^2 + \hat{\sigma}_Y^2 - 2\hat{\sigma}_{XY}} \]
Portfolio 範例:最小風險資產配置權重 α,使 Var(αX + (1−α)Y) 最小
\[ \text{SE}_B(\hat{\alpha}) = \sqrt{\frac{1}{B-1} \sum_{r=1}^{B} \left( \hat{\alpha}^{*r} - \bar{\alpha}^{*} \right)^2} \]
Bootstrap 標準誤差:B 個 bootstrap 樣本的 α 估計值的標準差

💻 程式碼實作

實作 1:手刻 Bootstrap — Portfolio 資料集的 α 標準誤差

說明:不依賴 sklearn,從頭實作 Bootstrap。從原始 n=100 個 (X,Y) 配對中,有放回地抽取 B=1000 個 bootstrap 樣本,每次計算 α 估計值,最後取標準差即為 Bootstrap SE。
import numpy as np

# 模擬 Portfolio 資料:X 和 Y 為兩種資產的報酬率
np.random.seed(42)
n = 100
X = np.random.normal(0.05, 0.20, n)   # 資產 X
Y = np.random.normal(0.07, 0.25, n)   # 資產 Y

# 計算 α 的函數:最小化 Var(αX + (1-α)Y)
def estimate_alpha(X_sample, Y_sample):
    var_X = np.var(X_sample, ddof=1)
    var_Y = np.var(Y_sample, ddof=1)
    cov_XY = np.cov(X_sample, Y_sample, ddof=1)[0, 1]
    alpha = (var_Y - cov_XY) / (var_X + var_Y - 2 * cov_XY)
    return alpha

# 原始樣本的 α
alpha_hat = estimate_alpha(X, Y)
print(f"原始樣本 α̂ = {alpha_hat:.4f}")

# Bootstrap(B = 1000)
B = 1000
alpha_boot = np.zeros(B)
for b in range(B):
    idx = np.random.choice(n, size=n, replace=True)  # 有放回抽樣
    alpha_boot[b] = estimate_alpha(X[idx], Y[idx])

# Bootstrap 標準誤差
se_boot = np.std(alpha_boot, ddof=1)
print(f"Bootstrap SE(α̂) = {se_boot:.4f}")
print(f"95% CI: [{alpha_hat - 1.96*se_boot:.4f}, {alpha_hat + 1.96*se_boot:.4f}]")

預期輸出:

原始樣本 α̂ = 0.6173
Bootstrap SE(α̂) = 0.0911
95% CI: [0.4388, 0.7958]

🔍 α̂ ≈ 0.62 表示建議將約 62% 資金配置到資產 X。SE ≈ 0.09 代表此估計有大約 ±9% 的不確定性。95% CI 顯示真實最優比例可能在 44%~80% 之間。

實作 2:用 Bootstrap 評估線性回歸係數的不確定性

說明:對簡單線性回歸的斜率係數做 Bootstrap,比較 Bootstrap SE 與最小平方法公式 SE。當誤差不是常態分布時,Bootstrap SE 更可靠。
from sklearn.linear_model import LinearRegression

# 模擬:y = 2 + 3x + ε,ε 來自偏態分布
np.random.seed(123)
n = 80
x = np.random.uniform(0, 10, n).reshape(-1, 1)
eps = np.random.exponential(scale=2, size=n)  # 偏態誤差
y = 2 + 3 * x[:, 0] + eps

# 原始 OLS
ols = LinearRegression().fit(x, y)
beta1_hat = ols.coef_[0]
print(f"OLS β̂₁ = {beta1_hat:.4f}")

# Bootstrap
B = 1000
beta1_boot = np.zeros(B)
for b in range(B):
    idx = np.random.choice(n, size=n, replace=True)
    boot_lr = LinearRegression().fit(x[idx], y[idx])
    beta1_boot[b] = boot_lr.coef_[0]

se_boot_beta = np.std(beta1_boot, ddof=1)
print(f"Bootstrap SE(β̂₁) = {se_boot_beta:.4f}")
print(f"95% Bootstrap CI: [{np.percentile(beta1_boot, 2.5):.4f}, "
      f"{np.percentile(beta1_boot, 97.5):.4f}]")

# 比較:理論 SE(假設誤差常態)
residuals = y - ols.predict(x)
sigma2_hat = np.sum(residuals**2) / (n - 2)
se_theory = np.sqrt(sigma2_hat / np.sum((x - x.mean())**2))
print(f"理論 SE(β̂₁)     = {se_theory:.4f}(假設誤差常態)")

預期輸出:

OLS β̂₁ = 2.9124
Bootstrap SE(β̂₁) = 0.0981
95% Bootstrap CI: [2.7223, 3.1058]
理論 SE(β̂₁)     = 0.0950(假設誤差常態)

🔍 Bootstrap SE (0.0981) 略大於理論 SE (0.0950),因為誤差來自偏態分布(指數分布),理論公式低估了真實不確定性。Bootstrap 不需假設誤差分布,在此例中更接近真實。

🎯 應用場景

場景描述
💰 投資組合估計最優資產配置權重的信賴區間,量化配置建議的不確定性
📊 模型評估當誤差非常態或統計量沒有簡單公式時,用 Bootstrap 估計任何指標的 SE
🧪 A/B 測試估計處理效應的信賴區間,不需假設抽樣分布
🤖 機器學習Bootstrap aggregating (Bagging) — 隨機森林的基礎,建立多個 bootstrap 模型後平均

⚖️ 優缺點

✅ 優點:

❌ 缺點:

📊 方法比較

方法原理計算成本適用場景
理論公式 SE數學推導(需假設分布)極低簡單統計量 + 常態假設成立
Bootstrap SE重複抽樣求標準差中(B×模型擬合)任何統計量、無需分布假設
Jackknife逐一剔除一筆重算低(n×模型擬合)偏差修正、較小資料集
Bayesian後驗分布的標準差高(MCMC)已有先驗資訊時

「Bootstrap 解放了統計學家:不需要解析公式,不需要假設母體分布——你只需要一台電腦和一點耐心。」

— Bradley Efron (1979), Bootstrap 發明者

🪞 自我內化

Bootstrap 的核心精神——「從既有經驗中重複抽樣來量化不確定性」——對 AI agent 的自我評估機制有深刻的啟發。Hermes 在每次任務後記錄自己的表現,但如何量化「我的能力在這個任務上有多穩定」?答案可能就是 Agent Bootstrap:從過去的任務記錄庫中重複抽樣類似場景,觀察自己的成功率波動,建立不確定性區間。當不確定性過大時,主動請求人類介入,而不是盲目自信地給出可能錯誤的結果。Bootstrap 不只是統計方法,它是一種在不完美資訊下誠實面對自己的哲學。