什么是 Bootstrap 采样?
Bootstrap 是一种强大的重采样统计方法,由 Bradley Efron 在 1979 年提出,它的核心思想是:

从原始数据集中有放回地重复抽样,生成多个新的“自助样本”,然后利用这些新样本来估计统计量的分布和性质。
为什么需要它? 在很多实际应用中,我们无法获得总体数据,只有一个样本,我们想了解这个样本统计量(比如均值、中位数、标准差,甚至更复杂的模型参数)的“不确定性”或“可靠性”,Bootstrap 提供了一种在只有一个样本的情况下,模拟抽样分布的方法。
核心概念:
- 原始数据集: 我们手头的一组观测数据,大小为
n。 - 自助样本: 通过从原始数据集中有放回地随机抽取
n个数据点生成的新数据集,因为是有放回,所以原始数据集中的某些点可能会在自助样本中出现多次,而另一些点可能一次都没出现。 - 自助统计量: 对每一个自助样本计算我们感兴趣的统计量(均值)。
- Bootstrap 分布: 将所有自助统计量汇集在一起形成的分布,这个分布可以用来近似真实统计量的抽样分布。
Bootstrap 采样的步骤
假设我们有一个原始数据集 X,包含 n 个观测值。

- 设定迭代次数
B: 决定要生成多少个自助样本。B通常是一个较大的数,1000, 5000, 或 10000。 - 循环
B次: a. 生成一个自助样本: 从X中有放回地随机抽取n个数据点,组成一个新的数据集X_star。 b. 计算统计量: 在X_star上计算你感兴趣的统计量(均值mean(X_star)),并将这个值存储起来。 - 构建 Bootstrap 分布: 循环结束后,你将拥有
B个统计量值,这B个值就构成了该统计量的 Bootstrap 分布。 - 进行分析: 利用这个 Bootstrap 分布,你可以进行各种分析,
- 计算置信区间: 估计统计量的不确定性范围。
- 计算标准误: 估计统计量的波动程度。
- 偏差修正: 评估原始样本统计量与真实总体参数之间的偏差。
Python 实现方法
在 Python 中,实现 Bootstrap 采样有几种方式,从手动编写到使用专业库。
使用 NumPy 手动实现(推荐理解原理)
这是最基础也是最直观的方法,能帮助你彻底理解 Bootstrap 的过程。
假设我们有一个样本,并想计算其均值的 95% 置信区间。
import numpy as np
# 1. 准备原始数据
# 假设我们有一个样本,来自某个未知总体的 100 个观测值
# 这里我们用正态分布生成一个示例数据
np.random.seed(42) # 保证结果可复现
original_data = np.random.normal(loc=100, scale=15, size=100)
print(f"原始数据均值: {np.mean(original_data):.2f}")
print(f"原始数据标准差: {np.std(original_data, ddof=1):.2f}")
# 2. 设置 Bootstrap 参数
n_iterations = 10000 # Bootstrap 次数
sample_size = len(original_data) # 原始样本大小
# 3. 存储 Bootstrap 统计量
bootstrap_means = []
# 4. 执行 Bootstrap 采样
for _ in range(n_iterations):
# a. 有放回地抽样,生成一个自助样本
# replace=True 是关键,表示有放回
bootstrap_sample = np.random.choice(original_data, size=sample_size, replace=True)
# b. 计算统计量(这里是均值)并存储
bootstrap_means.append(np.mean(bootstrap_sample))
# 5. 分析 Bootstrap 分布
bootstrap_means = np.array(bootstrap_means)
# 计算标准误
standard_error = np.std(bootstrap_means, ddof=1)
print(f"\nBootstrap 均值的标准误: {standard_error:.2f}")
# 计算 95% 置信区间 (使用百分位数法)
# np.percentile 可以直接计算任意百分位
ci_low = np.percentile(bootstrap_means, 2.5)
ci_high = np.percentile(bootstrap_means, 97.5)
print(f"均值的 95% 置信区间: [{ci_low:.2f}, {ci_high:.2f}]")
# 可视化 Bootstrap 分布
import matplotlib.pyplot as plt
import seaborn as sns
sns.histplot(bootstrap_means, kde=True)'Bootstrap Distribution of the Mean')
plt.axvline(np.mean(original_data), color='red', linestyle='--', label='Original Mean')
plt.axvline(ci_low, color='green', linestyle=':', label='95% CI')
plt.axvline(ci_high, color='green', linestyle=':')
plt.legend()
plt.show()
代码解释:

np.random.choice(data, size=n, replace=True)是核心函数,它实现了从data中有放回地抽取n个样本。- 我们循环
n_iterations次,每次都生成一个新的自助样本并计算其均值。 - 我们计算所有 Bootstrap 均值的标准差,这就是标准误的估计。
- 使用
np.percentile计算第 2.5 和第 97.5 百分位数,构成了 95% 的置信区间。
使用 scikit-learn 的 resample 函数
scikit-learn 库提供了一个更便捷的 resample 函数,可以简化抽样过程。
from sklearn.utils import resample
import numpy as np
# 1. 准备原始数据
np.random.seed(42)
original_data = np.random.normal(loc=100, scale=15, size=100)
# 2. 设置参数
n_iterations = 10000
bootstrap_means = []
# 3. 执行 Bootstrap
for _ in range(n_iterations):
# resample 默认就是有放回的
# n_samples=len(original_data) 表示样本大小与原始数据相同
bootstrap_sample = resample(original_data, n_samples=len(original_data), replace=True)
bootstrap_means.append(np.mean(bootstrap_sample))
# 4. 分析结果 (与 NumPy 方法完全相同)
bootstrap_means = np.array(bootstrap_means)
ci_low = np.percentile(bootstrap_means, 2.5)
ci_high = np.percentile(bootstrap_means, 97.5)
print(f"使用 scikit-learn 计算的 95% 置信区间: [{ci_low:.2f}, {ci_high:.2f}]")
resample 函数非常直观,replace=True 明确指定了有放回抽样。
使用 bootstrapped 库(最简单)
如果你不想自己写循环,可以使用专门的 bootstrapped 库,它能一站式完成计算并返回置信区间。
首先需要安装:
pip install bootstrapped
import bootstrapped.bootstrap as bs
import bootstrapped.stats_functions as bs_stats
import numpy as np
# 1. 准备原始数据
np.random.seed(42)
original_data = np.random.normal(loc=100, scale=15, size=100)
# 2. 调用 bootstrap 函数
# 第一个参数是数据
# stat_func 是你想要计算的统计量,这里用均值
# 返回的是一个 BootstrapResult 对象
result = bs.bootstrap(original_data, stat_func=bs_stats.mean)
# 3. 提取结果
# 0.95 表示 95% 置信水平
ci_low = result.lower_bound
ci_high = result.upper_bound
std_err = result.error_bound
print(f"使用 bootstrapped 库计算的均值: {result.value:.2f}")
print(f"标准误: {std_err:.2f}")
print(f"95% 置信区间: [{ci_low:.2f}, {ci_high:.2f}]")
这个方法代码最简洁,特别适合快速原型验证。
Bootstrap 的应用场景
Bootstrap 非常灵活,远不止计算均值和置信区间。
-
计算任意统计量的置信区间和标准误:
- 中位数、方差、分位数等。
- 相关系数、回归系数等。
-
模型评估(如交叉验证的替代):
可以用来评估一个模型(如线性回归、随机森林)性能指标(如准确率、R²分数)的稳定性。
-
偏差修正:
原始样本的统计量可能是总体参数的有偏估计,Bootstrap 可以用来估计这个偏差,并进行修正。
-
假设检验:
可以通过构造 Bootstrap 分布来执行一些非参数的假设检验。
优点与缺点
优点:
- 通用性强: 不依赖于数据分布的假设(非参数方法),适用于各种复杂的统计量。
- 实现简单: 核心思想就是“有放回抽样”,逻辑清晰。
- 直观: 通过可视化 Bootstrap 分布,可以非常直观地理解统计量的不确定性。
缺点:
- 计算密集: 当样本量
n或迭代次数B很大时,计算成本较高。 - 不适用于小样本: 如果原始样本量
n非常小,Bootstrap 可能无法很好地近似总体分布。 - 不能凭空创造信息: Bootstrap 只能在原始数据的信息范围内进行推断,它不能解决样本有系统性偏差(如选择偏差)的问题。
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| NumPy 手动 | 理解原理,灵活可控 | 代码稍长,需要自己写循环 | 学习、研究、自定义复杂统计量 |
Scikit-learn resample |
代码简洁,是标准库的一部分 | 仍需自己写循环 | 日常数据分析,已在使用 scikit-learn 的项目中 |
bootstrapped 库 |
极其简洁,一站式解决 | 需要额外安装,定制性稍差 | 快速原型验证,生产环境中需要高效、简洁的代码 |
对于初学者和大多数应用场景,强烈建议先掌握使用 NumPy 手动实现,这能帮助你深刻理解 Bootstrap 的精髓,在实际项目中,可以根据需求选择 scikit-learn 或 bootstrapped 库来提高效率。
