使用Scikit-learn训练GradientBoostingRegressor

举报
yd_37369233 发表于 2026/08/07 10:12:15 2026/08/07
【摘要】 引言在机器学习领域,梯度提升(Gradient Boosting)是一种强大且广泛使用的集成学习算法。它通过串行方式构建一系列弱学习器(通常是决策树),每一棵树都在修正前一棵树的预测误差,从而形成一个强预测模型。Scikit-learn提供了GradientBoostingRegressor类,让我们可以方便地在Python中应用这一算法进行回归任务。本文将带你从零开始,系统学习如何使用S...

引言

在机器学习领域,梯度提升(Gradient Boosting)是一种强大且广泛使用的集成学习算法。它通过串行方式构建一系列弱学习器(通常是决策树),每一棵树都在修正前一棵树的预测误差,从而形成一个强预测模型。Scikit-learn提供了GradientBoostingRegressor类,让我们可以方便地在Python中应用这一算法进行回归任务。

本文将带你从零开始,系统学习如何使用Scikit-learn训练GradientBoostingRegressor模型,涵盖原理、关键参数、完整代码实战以及模型调优等内容。

一、GradientBoostingRegressor的核心原理

梯度提升回归的核心思想是加法模型前向分步算法。简单来说:

  1. 首先用一个初始模型(通常是目标值的均值)进行预测
  2. 计算残差(真实值与预测值的差)
  3. 训练一棵决策树来拟合这个残差(即负梯度方向)
  4. 将新树的预测结果乘以学习率后加到模型中
  5. 重复步骤2-4,直到达到指定的树的数量

这种“错误驱动学习”机制使得模型能够逐步逼近真实目标函数。

💡 小提示:如果你的数据集较大(n_samples >= 10000),可以考虑使用HistGradientBoostingRegressor,它是GradientBoostingRegressor的更快变体。

二、关键参数详解

在使用GradientBoostingRegressor之前,理解其核心参数至关重要。

参数 默认值 说明
loss 'squared_error' 损失函数。可选'squared_error'(平方误差)、'absolute_error'(绝对误差)、'huber'(二者的结合)、'quantile'(分位数回归)
learning_rate 0.1 学习率,控制每棵树的贡献缩水程度。learning_raten_estimators之间存在权衡
n_estimators 100 boosting的迭代次数(树的数量)。梯度提升对过拟合较为鲁棒,较大的值通常效果更好
max_depth 3 每棵决策树的最大深度,限制树的复杂度
subsample 1.0 用于拟合每棵树的样本比例。小于1.0时即为随机梯度提升,可降低方差但增加偏差
criterion 'friedman_mse' 衡量分裂质量的标准,'friedman_mse'通常效果最佳
min_samples_split 2 内部节点再划分所需的最小样本数
min_samples_leaf 1 叶节点所需的最小样本数
random_state None 随机种子,保证结果可复现

三、完整实战案例

下面我们以Scikit-learn自带的糖尿病数据集为例,完整演示训练过程。

3.1 导入所需库

import matplotlib.pyplot as plt
import numpy as np
from sklearn import datasets, ensemble
from sklearn.inspection import permutation_importance
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import train_test_split

3.2 加载并准备数据

# 加载糖尿病数据集
diabetes = datasets.load_diabetes()
X, y = diabetes.data, diabetes.target

# 划分训练集和测试集(90%训练,10%测试)
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.1, random_state=13
)

3.3 配置并训练模型

# 设置模型参数
params = {
    'n_estimators': 500,      # 500棵树
    'max_depth': 4,            # 每棵树最大深度为4
    'min_samples_split': 2,    # 内部节点最小样本数
    'learning_rate': 0.01,     # 学习率
    'loss': 'squared_error'    # 平方误差损失
}

# 创建并训练模型
reg = ensemble.GradientBoostingRegressor(**params)
reg.fit(X_train, y_train)

训练完成后,模型就学习到了数据中的模式。

3.4 模型预测与评估

# 在测试集上进行预测
y_pred = reg.predict(X_test)

# 计算均方误差(MSE)
mse = mean_squared_error(y_test, y_pred)
print(f"测试集MSE: {mse:.4f}")

3.5 绘制训练过程中的偏差变化

GradientBoostingRegressor提供了staged_predict()方法,可以获取每一轮boosting迭代后的预测结果,帮助我们观察模型的收敛情况。

# 计算每一轮迭代后在测试集上的偏差
test_score = np.zeros((params['n_estimators'],), dtype=np.float64)
for i, y_pred_iter in enumerate(reg.staged_predict(X_test)):
    test_score[i] = reg.loss_(y_test, y_pred_iter)

# 绘制训练集和测试集的偏差曲线
plt.figure(figsize=(10, 5))
plt.plot(np.arange(params['n_estimators']) + 1, reg.train_score_, 'b-', 
         label='训练集偏差')
plt.plot(np.arange(params['n_estimators']) + 1, test_score, 'r-', 
         label='测试集偏差')
plt.legend(loc='upper right')
plt.xlabel('Boosting迭代次数')
plt.ylabel('偏差')
plt.title('训练过程中的偏差变化')
plt.show()

通过这张图,我们可以判断模型是否在某个迭代次数后开始过拟合。

四、特征重要性分析

GradientBoostingRegressor训练完成后,可以通过feature_importances_属性获取每个特征的重要性分数。重要性分数越高,表示该特征对预测结果的影响越大。

# 获取特征重要性
feature_importance = reg.feature_importances_

# 归一化到百分比
feature_importance = 100.0 * (feature_importance / feature_importance.max())

# 按重要性排序并绘图
sorted_idx = np.argsort(feature_importance)
pos = np.arange(sorted_idx.shape[0]) + 0.5

plt.figure(figsize=(10, 6))
plt.barh(pos, feature_importance[sorted_idx], align='center')
plt.yticks(pos, np.array(diabetes.feature_names)[sorted_idx])
plt.xlabel('相对重要性 (%)')
plt.title('特征重要性排序')
plt.tight_layout()
plt.show()

五、超参数调优

为了获得更好的模型性能,通常需要进行超参数调优。以下是一个使用GridSearchCV进行网格搜索的示例:

from sklearn.model_selection import GridSearchCV

# 定义参数网格
param_grid = {
    'n_estimators': [100, 200, 300],
    'max_depth': [3, 4, 5],
    'learning_rate': [0.01, 0.05, 0.1],
    'subsample': [0.8, 1.0]
}

# 创建GridSearchCV对象
gb = ensemble.GradientBoostingRegressor(random_state=42)
grid_search = GridSearchCV(
    estimator=gb,
    param_grid=param_grid,
    cv=5,  # 5折交叉验证
    scoring='neg_mean_squared_error',
    n_jobs=-1
)

# 执行网格搜索
grid_search.fit(X_train, y_train)

# 输出最优参数
print(f"最优参数: {grid_search.best_params_}")
print(f"最优交叉验证得分: {-grid_search.best_score_:.4f}")

六、高级特性

6.1 早停法(Early Stopping)

Scikit-learn的GradientBoostingRegressor支持通过n_iter_no_changevalidation_fractiontol参数实现早停,当验证集上的得分在若干轮迭代中没有改善时自动停止训练。

reg_early_stop = ensemble.GradientBoostingRegressor(
    n_estimators=1000,           # 设置较大的初始值
    validation_fraction=0.1,     # 10%的数据作为验证集
    n_iter_no_change=10,         # 连续10轮无改善则停止
    tol=0.001,                   # 改善阈值
    random_state=42
)
reg_early_stop.fit(X_train, y_train)
print(f"实际使用的树的数量: {reg_early_stop.n_estimators_}")

6.2 增量训练(warm_start)

warm_start=True允许在已有模型的基础上继续添加更多的树:

# 先训练100棵树
reg = ensemble.GradientBoostingRegressor(n_estimators=100, warm_start=True)
reg.fit(X_train, y_train)

# 再增加100棵树(在已有模型基础上继续训练)
reg.set_params(n_estimators=200)
reg.fit(X_train, y_train)  # 不会重新开始,而是在现有模型上继续
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。