使用Scikit-learn训练AdaBoostRegressor
引言
在机器学习中,集成学习方法通过组合多个弱学习器来构建强大的预测模型。AdaBoost(Adaptive Boosting)作为Boosting家族的代表算法,因其简单高效而广受欢迎。本文将深入介绍Scikit-learn中的AdaBoostRegressor,从算法原理到代码实战,帮助读者全面掌握这一强大的回归工具。
一、AdaBoost回归算法原理
AdaBoost最初是为二分类问题设计的,但其思想具有很强的一般性。Scikit-learn中的AdaBoostRegressor实现了AdaBoost.R2算法,这是由Harris Drucker在1997年提出的回归版本。
核心思想
AdaBoostRegressor是一个元估计器(meta-estimator),它的工作流程如下:
- 初始化:首先在原始数据集上训练一个基础回归器,所有样本的初始权重相同。
- 迭代提升:在每一轮迭代中,根据当前模型的预测误差调整样本权重——预测误差大的样本获得更高的权重,使得后续的回归器更加关注这些“困难”样本。
- 加权集成:最终将所有弱回归器的预测结果按权重组合,形成强回归器。
这种“纠错”机制使得AdaBoost能够逐步提升模型性能,后续的回归器会聚焦于前一轮表现不佳的样本。
AdaBoost.R2的损失函数
AdaBoostRegressor支持三种损失函数,用于在每一轮迭代后更新样本权重:
| 损失函数 | 说明 |
|---|---|
linear(默认) |
线性损失,对误差的惩罚适中 |
square |
平方损失,对大误差惩罚更重 |
exponential |
指数损失,对误差极为敏感 |
二、AdaBoostRegressor核心参数详解
在Scikit-learn中,AdaBoostRegressor的核心参数如下:
1. estimator(基础估计器)
用于构建提升集成的基础回归器。如果为None,则默认使用max_depth=3的DecisionTreeRegressor。从版本1.2开始,base_estimator已重命名为estimator。
注意:基础估计器需要支持样本权重(sample weighting)。
2. n_estimators(估计器数量)
提升终止时的最大估计器数量,默认值为50。如果模型达到完美拟合,学习过程会提前停止。取值范围为[1, inf)。
3. learning_rate(学习率)
每个回归器在每次提升迭代中的贡献权重,默认值为1.0。较高的学习率会增加每个回归器的贡献,但可能导致过拟合;较低的学习率需要更多的估计器来达到相似性能,但通常能获得更好的泛化能力。
learning_rate和n_estimators之间存在权衡关系——降低学习率通常需要增加估计器数量来补偿。
4. loss(损失函数)
更新权重时使用的损失函数,可选'linear'、'square'、'exponential',默认为'linear'。
5. random_state(随机种子)
控制随机数生成,传入整数可确保结果可复现。
三、完整实战案例
下面通过一个完整的示例来演示AdaBoostRegressor的使用。我们将使用Scikit-learn官方示例中的正弦波数据集。
3.1 导入库与生成数据
import numpy as np
import matplotlib.pyplot as plt
from sklearn.tree import DecisionTreeRegressor
from sklearn.ensemble import AdaBoostRegressor
from sklearn.metrics import mean_squared_error, r2_score
# 设置随机种子确保可复现
rng = np.random.RandomState(1)
# 生成1D正弦波数据集(含高斯噪声)
X = np.linspace(0, 6, 100)[:, np.newaxis]
y = np.sin(X).ravel() + np.sin(6 * X).ravel() + rng.normal(0, 0.1, X.shape[0])
这里生成了一个包含正弦波关系并添加了少量高斯噪声的100个样本的数据集。
3.2 训练模型
# 单个决策树回归器(作为对比基准)
regr_1 = DecisionTreeRegressor(max_depth=4)
# AdaBoost回归器:以max_depth=4的决策树为基础估计器,使用300个估计器
regr_2 = AdaBoostRegressor(
estimator=DecisionTreeRegressor(max_depth=4),
n_estimators=300,
random_state=42
)
# 拟合模型
regr_1.fit(X, y)
regr_2.fit(X, y)
# 预测
y_1 = regr_1.predict(X)
y_2 = regr_2.predict(X)
这里我们对比了单个决策树和AdaBoost集成的效果。AdaBoost使用了300棵max_depth=4的决策树作为弱学习器。
3.3 评估与可视化
# 计算评估指标
print("决策树回归 - R²:", r2_score(y, y_1))
print("决策树回归 - MSE:", mean_squared_error(y, y_1))
print("AdaBoost回归 - R²:", r2_score(y, y_2))
print("AdaBoost回归 - MSE:", mean_squared_error(y, y_2))
# 可视化对比
plt.figure(figsize=(12, 5))
plt.scatter(X, y, c="k", s=20, label="训练样本", alpha=0.6)
plt.plot(X, y_1, c="g", label="决策树 (max_depth=4)", linewidth=2)
plt.plot(X, y_2, c="r", label="AdaBoost (n_estimators=300)", linewidth=2)
plt.xlabel("X")
plt.ylabel("y")
plt.title("决策树 vs AdaBoost回归对比")
plt.legend()
plt.show()
3.4 运行结果分析
随着Boosting轮数的增加,AdaBoost回归器能够拟合出更多的细节。相比单棵决策树,AdaBoost集成模型通常能够:
- 显著降低预测误差
- 更好地捕捉数据中的非线性模式
- 在相同基础学习器上实现性能的“提升”
四、超参数调优:网格搜索实战
为了获得最佳性能,我们需要对AdaBoostRegressor的关键超参数进行调优。以下是使用GridSearchCV进行系统调优的示例:
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.ensemble import AdaBoostRegressor
# 生成回归数据集
X, y = make_regression(n_samples=1000, n_features=10, noise=0.1, random_state=42)
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
# 定义参数网格
param_grid = {
'n_estimators': [50, 100, 200],
'learning_rate': [0.01, 0.1, 1.0],
'loss': ['linear', 'square', 'exponential']
}
# 执行网格搜索(5折交叉验证)
grid_search = GridSearchCV(
estimator=AdaBoostRegressor(random_state=42),
param_grid=param_grid,
cv=5,
scoring='neg_mean_squared_error'
)
grid_search.fit(X_train, y_train)
# 输出最佳结果
print(f"最佳交叉验证分数: {grid_search.best_score_:.3f}")
print(f"最佳参数组合: {grid_search.best_params_}")
# 在测试集上评估
best_model = grid_search.best_estimator_
test_score = best_model.score(X_test, y_test)
print(f"测试集 R² 分数: {test_score:.3f}")
运行上述代码可能得到类似如下的输出:
最佳交叉验证分数: -3006.159
最佳参数组合: {'learning_rate': 1, 'loss': 'square', 'n_estimators': 200}
测试集 R² 分数: 0.845
调参要点
对AdaBoostRegressor调参时,主要关注两部分:
- 框架参数:
n_estimators、learning_rate、loss - 弱学习器参数:如果使用决策树作为基础估计器,还需要调整
max_depth、min_samples_split等树参数
learning_rate和n_estimators的权衡是调参的关键——较小的学习率通常需要更多的估计器。
五、模型属性与特征重要性
训练完成后,AdaBoostRegressor提供了多个有用的属性:
| 属性 | 说明 |
|---|---|
estimators_ |
所有已拟合的子估计器列表 |
estimator_weights_ |
每个估计器在集成中的权重 |
estimator_errors_ |
每个估计器的回归误差 |
feature_importances_ |
基于不纯度的特征重要性 |
获取特征重要性的方法如下:
# 获取特征重要性
importances = regr_2.feature_importances_
# 可视化特征重要性
for i, imp in enumerate(importances):
print(f"特征 {i}: {imp:.4f}")
feature_importances_基于不纯度减少来计算,值越高表示该特征越重要。需要注意的是,对于高基数(许多唯一值)的特征,基于不纯度的特征重要性可能会有误导。
六、注意事项与最佳实践
6.1 过拟合风险
AdaBoost对噪声和异常值较为敏感。如果弱学习器过于复杂(如深度很大的决策树),AdaBoost可能会过拟合。建议:
- 使用较浅的决策树(如
max_depth=3~6)作为基础估计器 - 通过交叉验证选择合适的
n_estimators
6.2 计算成本
n_estimators越大,训练时间越长。300个估计器已经能提供很好的性能,实际使用中可根据数据规模和计算资源权衡。
6.3 数据规模
AdaBoost适合中小规模数据集。对于大规模数据,可考虑使用HistGradientBoostingRegressor等更高效的模型。
- 点赞
- 收藏
- 关注作者
评论(0)