大家好,我是爱酱。前几篇我们讲了聚类、回归等基础任务,这一期我们来聊聊机器学习中提升模型效果的“法宝”——集成方法(Ensemble Methods)。本篇将用Iris鸢尾花分类为例,详细讲解Bagging和Boosting的原理、流程和代码,让你像看层次聚类那篇一样,能一步步跟着学会。
注:本文章含大量数学算式、详细例子说明及代码演示,大量干货,建议先收藏再慢慢观看理解。新频道发展不易,你们的每个赞、收藏跟转发都是我继续分享的动力!
注:本文章颇长近7000字,非常耗时制作,建议先收藏再慢慢观看。新频道发展不易,你们的每个赞、收藏跟转发都是我继续分享的动力!
一、Bagging(以随机森林为例)
1. 原理简介
Bagging(Bootstrap Aggregating)通过对原始数据集有放回地抽样,生成多个训练子集,每个子集训练一个基学习器(通常是决策树),最后对所有模型的预测结果进行投票(分类)或平均(回归),从而提升整体模型的稳定性和准确率。
数学表达:
-
分类:
-
回归:
其中 为第
个基学习器,
为模型数。
2. 详细案例流程(以Iris数据集为例)
数据集
我们用经典的鸢尾花(Iris)数据集,共150条数据,4个特征,3个类别。
Step 1:数据准备
-
加载Iris数据集
-
划分训练集和测试集(如70%训练,30%测试)
Step 2:Bootstrap采样
-
从训练集有放回地随机抽样,生成10个与原训练集等大的子集(假设n_estimators=10)
-
每个子集可能有重复数据,也可能遗漏部分原始样本
Step 3:训练基学习器
-
对每个子集,训练一棵决策树(弱学习器)
Step 4:集成预测
-
对每个测试样本,让10棵树分别预测类别
-
统计10个预测结果,采用多数投票,得出最终预测类别
Step 5:评估结果
-
计算整体准确率,对比单棵树的效果
3. Python代码实现
注:记得要先 pip install scikit-learn Library喔~
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.ensemble import BaggingClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.inspection import DecisionBoundaryDisplay
# 加载数据,只用前两个特征
X, y = load_iris(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X[:, :2], y, test_size=0.3, random_state=42)
# Bagging集成决策树
bagging_model = BaggingClassifier(
estimator=DecisionTreeClassifier(max_depth=2),
n_estimators=10,
random_state=42
)
bagging_model.fit(X_train, y_train)
# 绘制决策边界
plt.figure(figsize=(8, 6))
ax = plt.gca()
DecisionBoundaryDisplay.from_estimator(bagging_model, X_train, response_method='predict', cmap='Pastel1', alpha=0.6, ax=ax)
# 绘制训练点
scatter = ax.scatter(X_train[:, 0], X_train[:, 1], c=y_train, cmap='Set1', edgecolor='k', s=50)
plt.title('Bagging Classifier Decision Boundary and Training Data')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.grid(True)
plt.show()
二、Boosting(以AdaBoost为例)
1. 原理简介
Boosting通过串行方式训练多个弱学习器,每一轮关注前一轮分错的样本,逐步提升整体模型能力。最终模型是所有弱学习器的加权组合。
AdaBoost 核心公式:
-
样本权重初始化
-
第
轮分类器误差:
-
分类器权重:
-
样本权重更新:
-
最终模型预测:
2. 详细案例流程(以Iris数据集为例)
数据集
同样用Iris数据集。(Iris数据集有150条样本,每条有4个特征(花萼长宽、花瓣长宽),分3个类别(Setosa、Versicolor、Virginica)。)
Step 1:数据准备
-
加载Iris数据集,划分训练集和测试集
Step 2:初始化样本权重
-
所有训练样本权重均等,
Step 3:迭代训练弱学习器
-
第一轮:
-
用当前权重训练一个决策树桩(只分一层)
-
计算分错的样本,加大其权重
-
-
第二轮及以后:
-
用更新后的权重再次训练新树桩
-
继续加大分错样本的权重
-
-
每一轮,都记录当前弱学习器的权重
Step 4:组合弱学习器
-
所有弱学习器按权重
加权投票,形成最终强模型
Step 5:预测与评估
-
用加权投票预测新样本类别
-
计算整体准确率
3. Python代码实现
注:记得要先 pip install scikit-learn Library喔~
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.ensemble import AdaBoostClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.inspection import DecisionBoundaryDisplay
# 加载数据,只用前两个特征
X, y = load_iris(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X[:, :2], y, test_size=0.3, random_state=42)
# AdaBoost集成决策树桩
ada_model = AdaBoostClassifier(
estimator=DecisionTreeClassifier(max_depth=1),
n_estimators=50,
learning_rate=1,
random_state=42
)
ada_model.fit(X_train, y_train)
# 绘制决策边界
plt.figure(figsize=(8, 6))
ax = plt.gca()
DecisionBoundaryDisplay.from_estimator(ada_model, X_train, response_method='predict', cmap='Pastel2', alpha=0.6, ax=ax)
# 绘制训练点
scatter = ax.scatter(X_train[:, 0], X_train[:, 1], c=y_train, cmap='Set1', edgecolor='k', s=50)
plt.title('AdaBoost Classifier Decision Boundary and Training Data')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.grid(True)
plt.show()
三、Boosting进阶:XGBoost案例
1. 原理简介
XGBoost(eXtreme Gradient Boosting)是一种基于梯度提升(Gradient Boosting)的集成算法。它通过串行地训练多个弱学习器(通常是决策树),每一步关注前一步做错的样本,最终加权组合所有弱学习器,提升整体预测能力
XGBoost 核心公式:
-
梯度提升框架
XGBoost的本质是加法模型,每一轮都在已有模型的基础上,拟合损失函数的负梯度(即残差):
其中 是第
棵新树,
是步长(learning rate)。
-
二阶泰勒展开近似损失
XGBoost用泰勒展开近似损失函数,利用一阶和二阶导数(梯度和Hessian)高效优化:
:损失函数对预测的梯度
:损失函数对预测的二阶导数
:正则化项,防止过拟合
- 正则化与Shrinkage
XGBoost在每轮加法时引入Shrinkage(学习率)和正则化,进一步提升泛化能力。
2. 详细案例流程(以Iris数据集为例)
数据集简介
同样用Iris数据集。(Iris数据集有150条样本,每条有4个特征(花萼长宽、花瓣长宽),分3个类别(Setosa、Versicolor、Virginica)。)
Step 1:数据准备
-
只用前两个特征,便于二维可视化
-
划分训练集和测试集
Step 2:初始化和训练XGBoost模型
-
设定弱学习器为树,步长learning_rate=0.1,树的数量n_estimators=50
Step 3:迭代训练过程(原理说明)
-
第1轮:先用一棵小树拟合标签分布
-
第2轮及以后:每轮计算上轮模型的残差(负梯度),新树专门拟合残差,逐步修正模型
-
每一轮的树输出都乘以学习率(shrinkage),防止过拟合
-
所有树的加权输出相加,得到最终预测
Step 4:预测与评估
Step 5:可视化决策边界与训练样本
3. Python代码实现
注:记得要先 pip install scikit-learn Library喔~
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from xgboost import XGBClassifier
from sklearn.model_selection import train_test_split
from matplotlib.colors import ListedColormap
# 加载数据,只用前两个特征
X, y = load_iris(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X[:, :2], y, test_size=0.3, random_state=42)
# 训练XGBoost模型
xgb_model = XGBClassifier(n_estimators=50, learning_rate=0.1, max_depth=2, use_label_encoder=False, eval_metric='mlogloss')
xgb_model.fit(X_train, y_train)
# 绘制决策边界
x_min, x_max = X_train[:, 0].min() - 1, X_train[:, 0].max() + 1
y_min, y_max = X_train[:, 1].min() - 1, X_train[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.02), np.arange(y_min, y_max, 0.02))
Z = xgb_model.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.figure(figsize=(8, 6))
cmap_light = ListedColormap(['#FFAAAA', '#AAFFAA', '#AAAAFF'])
cmap_bold = ListedColormap(['#FF0000', '#00FF00', '#0000FF'])
plt.contourf(xx, yy, Z, alpha=0.3, cmap=cmap_light)
plt.scatter(X_train[:, 0], X_train[:, 1], c=y_train, cmap=cmap_bold, edgecolor='k', s=50)
plt.title('XGBoost Decision Boundary and Training Data')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.grid(True)
plt.show()
四、Bagging(随机森林)和Boosting(AdaBoost/XGBoost)的优缺点与工程建议
1. Bagging(以随机森林为代表)
优点:
-
减少过拟合,提升泛化能力:通过并行训练多个模型并平均结果,有效降低模型的方差,减少单一模型对噪声的敏感性。
-
适合大数据和高维特征:能高效处理大量特征和样本,适用于分类和回归任务。
-
对异常值和缺失值鲁棒:随机森林对异常点和缺失值不敏感,适合真实业务环境。
-
可输出特征重要性:有助于特征选择和模型解释。
-
训练可并行,速度快:各树独立训练,易于并行化。
缺点:
-
模型不易解释:集成多棵树后,单次预测难以追溯具体决策路径,属于“黑盒”模型。
-
计算资源消耗大:需要训练和存储多棵树,内存和计算量较大,尤其在大数据场景下。
-
参数调优复杂:如树的数量、最大深度等超参数需调优,否则可能欠拟合或过拟合。
工程建议:
-
当你的数据集较大、特征较多、模型易过拟合时,优先考虑Bagging/随机森林。
-
需要模型解释性时,可以结合特征重要性分析辅助业务解读。
-
适合并行计算资源充足的场景。
2. Boosting(以AdaBoost/XGBoost为代表)
优点:
-
提升准确率,降低偏差:Boosting通过序列训练,每一步关注前一步分错的样本,能有效降低模型偏差,提升整体准确率。
-
适合小数据集和复杂数据:尤其在样本量不大、模型单独表现欠佳时,Boosting能大幅提升效果。
-
内置正则化,抗过拟合能力强(XGBoost):XGBoost等算法内置正则化项,能有效防止过拟合。
-
可处理缺失值、异常值:XGBoost等对缺失值、异常值有较好容忍度。
-
特征选择能力强:可输出特征重要性,辅助业务决策。
缺点:
-
对噪声敏感,易过拟合异常点:Boosting对分错样本赋予更高权重,若数据中噪声多,易导致过拟合。
-
训练速度慢,难以并行:Boosting串行训练,无法像Bagging一样并行,训练时间较长。
-
模型解释性较弱:复杂的加权组合使得模型难以直观解释。
-
参数多,调优复杂:如学习率、树数、最大深度等超参数需仔细调优,否则效果不佳。
工程建议:
-
追求极致精度、数据质量较高时优先考虑Boosting(如XGBoost)。
-
数据有较多异常点或噪声时,需注意调参和正则化,避免过拟合。
-
适合对性能要求高、资源允许的场景,尤其是结构化数据建模。
3. 总结对比与选择建议
维度 | Bagging(随机森林) | Boosting(AdaBoost/XGBoost) |
---|---|---|
训练方式 | 并行,模型独立 | 串行,模型依赖前一轮结果 |
主要作用 | 降低方差,提升稳定性 | 降低偏差和方差,提升准确率 |
对噪声敏感性 | 鲁棒,抗噪声 | 易过拟合噪声,需要正则化 |
解释性 | 一般,特征重要性可解释 | 弱,模型为加权组合 |
训练速度 | 快,可并行 | 慢,难并行 |
超参数调优 | 中等 | 复杂 |
典型场景 | 大数据、高维、易过拟合任务 | 精度要求高、结构化数据、特征选择 |
代表算法 | 随机森林 | AdaBoost、XGBoost、LightGBM |
实际工程建议:
-
Bagging/随机森林适合大数据、高维、模型易过拟合且对解释性有一定需求的场景。
-
Boosting(XGBoost等)适合追求极致精度、数据质量高、特征复杂的场景,尤其在Kaggle等竞赛中表现突出。
-
两者都可输出特征重要性,辅助业务分析。
-
推荐结合交叉验证、特征工程和正则化,获得最佳泛化性能。
五、总结
集成方法通过组合多个弱学习器,大幅提升模型的泛化能力和鲁棒性。Bagging适合并行、降方差,Boosting适合串行、降偏差。实际工程中,建议根据数据特性和业务需求灵活选择,并结合交叉验证、模型集成等策略获得最佳效果。
谢谢你看到这里,你们的每个赞、收藏跟转发都是我继续分享的动力。
如需进一步案例、代码实现或与其他聚类算法对比,欢迎留言交流!我是爱酱,我们下次再见,谢谢收看!