关键词:机器学习、Bagging算法、Bootstrap聚合、集成学习、随机森林基础、偏差方差分解、Python Bagging、Java Bagging、OOB误差、决策树集成
一句话答案:Bagging 通过对训练集有放回随机采样构建多个基模型,并平均(回归)或投票(分类) 其预测结果——它不降低偏差,但显著降低方差,是随机森林的理论基础!
如果你在搜索:
那么,这篇文章就是为你写的——从自助法到方差分解,一步不跳。
Bagging(Bootstrap Aggregating)由 Leo Breiman 于 1996 年提出,是一种并行式集成学习方法。
💡 关键洞察:Bagging 通过引入随机性 + 模型平均,降低单模型对训练数据的敏感度。
任何模型的泛化误差可分解为:

组件 | 单模型 | Bagging 集成 | 原因 |
|---|---|---|---|
偏差(Bias) | 固定 | 基本不变 | 所有基模型同质,期望预测不变 |
方差(Variance) | 高 | ✅ 显著降低 | 模型间不相关 → 平均后方差下降 |
过拟合风险 | 高(如深树) | ✅ 大幅降低 | 随机采样打破噪声模式 |
✅ 结论:Bagging 特别适合高方差、低偏差的模型(如未剪枝决策树)。
房屋ID | 面积(x) | 价格(y, 万元) |
|---|---|---|
A | 50 | 100 |
B | 70 | 140 |
C | 90 | 180 |
D | 110 | 220 |
E | 130 | 260 |
目标:用 Bagging(3棵树)预测面积=100 的房价。
💡 注意:B 在样本1出现两次,C 在样本2出现两次,A 在样本3出现两次。

💡 真实关系 y=2x → 真实值=200。 单棵树可能严重偏离(如树3预测246.7),但Bagging 平滑了极端预测。
特性 | Bagging | Boosting(如AdaBoost) |
|---|---|---|
训练方式 | ⚡ 并行(独立训练) | 🔄 串行(依赖前一轮) |
样本权重 | 所有样本等权(但采样随机) | ❗ 动态调整(关注错分样本) |
目标 | ✅ 降低方差 | ✅ 降低偏差 |
基模型要求 | 高方差模型(如深树) | 弱模型(如决策桩) |
过拟合风险 | 低 | 高(尤其噪声数据) |
代表算法 | 随机森林 | AdaBoost, GBDT, XGBoost |
🎯 简单记:
import numpy as np
from sklearn.tree import DecisionTreeRegressor, DecisionTreeClassifier
class Bagging:
def __init__(self, base_estimator=None, n_estimators=10, task='regression'):
self.base_estimator = base_estimator or (
DecisionTreeRegressor(max_depth=5) if task == 'regression'
else DecisionTreeClassifier(max_depth=5)
)
self.n_estimators = n_estimators
self.task = task
self.estimators = []
def fit(self, X, y):
n_samples = X.shape[0]
self.estimators = []
for _ in range(self.n_estimators):
# Bootstrap 采样(有放回)
indices = np.random.choice(n_samples, size=n_samples, replace=True)
X_boot, y_boot = X[indices], y[indices]
# 训练基模型
estimator = self.base_estimator
if hasattr(estimator, 'fit'):
estimator = self.base_estimator.__class__(**self.base_estimator.get_params())
estimator.fit(X_boot, y_boot)
self.estimators.append(estimator)
def predict(self, X):
if self.task == 'regression':
predictions = np.array([est.predict(X) for est in self.estimators])
return np.mean(predictions, axis=0)
else: # classification
predictions = np.array([est.predict(X) for est in self.estimators])
# 多数投票
return np.array([np.bincount(preds).argmax() for preds in predictions.T])
# === 测试回归 ===
X = np.array([[50], [70], [90], [110], [130]])
y = np.array([100, 140, 180, 220, 260])
bag_reg = Bagging(task='regression', n_estimators=3)
bag_reg.fit(X, y)
print("Bagging预测(100):", bag_reg.predict()) # ≈215
# === 测试分类 ===
X_cls = np.array([[1], [2], [3], [4], [5]])
y_cls = np.array([0, 0, 1, 1, 1])
bag_cls = Bagging(task='classification', n_estimators=3)
bag_cls.fit(X_cls, y_cls)
print("Bagging分类(3.5):", bag_cls.predict()) # 应为1import weka.classifiers.trees.J48;
import weka.core.Instances;
import weka.core.Instance;
import java.util.Random;
public class Bagging {
private weka.classifiers.Classifier[] models;
private int numModels;
private Random rand = new Random();
public void buildClassifier(Instances data, int numModels) throws Exception {
this.numModels = numModels;
models = new weka.classifiers.Classifier[numModels];
for (int i = 0; i < numModels; i++) {
// Bootstrap 采样
Instances bootstrap = new Instances(data, data.numInstances());
for (int j = 0; j < data.numInstances(); j++) {
int idx = rand.nextInt(data.numInstances());
bootstrap.add(data.instance(idx));
}
// 训练基模型(以J48为例)
J48 tree = new J48();
tree.buildClassifier(bootstrap);
models[i] = tree;
}
}
public double[] distributionForInstance(Instance inst) throws Exception {
double[] avgDist = new double[inst.numClasses()];
for (weka.classifiers.Classifier model : models) {
double[] dist = model.distributionForInstance(inst);
for (int i = 0; i < avgDist.length; i++) {
avgDist[i] += dist[i];
}
}
// 平均概率分布
for (int i = 0; i < avgDist.length; i++) {
avgDist[i] /= numModels;
}
return avgDist;
}
// 分类预测:取概率最大类
public double classifyInstance(Instance inst) throws Exception {
double[] dist = distributionForInstance(inst);
int bestClass = 0;
for (int i = 1; i < dist.length; i++) {
if (dist[i] > dist[bestClass]) bestClass = i;
}
return bestClass;
}
}💡 回归任务需替换为
M5P或自定义回归树。
问题 | 说明 |
|---|---|
❌ 不降低偏差 | 若基模型本身有偏(如线性模型拟合非线性),Bagging 无法改善 |
❌ 计算成本高 | 需训练 (N) 个模型(但可并行) |
❌ 对稳定模型无效 | 如线性回归、KNN(本身方差低) |
⚠️ OOB 估计有偏 | 尤其在小数据集上 |
💡 经验法则:当你的单模型在不同训练集上预测波动大时,用 Bagging!
Bagging 是集成学习的“稳压器”——它不追求单个模型的强大,而是通过群体智慧实现稳健预测。理解 Bagging,是掌握随机森林、理解模型稳定性的关键一步。
记住:在机器学习中,多样性 + 平均 = 稳定性。
现在,你已经能:
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。