如何绘制GradientBoostingRegressor每轮迭代的训练与验证精度/分数?
获取GradientBoostingRegressor每轮迭代的训练与验证分数
方法1:用内置验证集快速获取(单折)
如果你只需要从训练集拆分一部分作为验证集,直接用模型内置参数就能拿到每轮对应的验证分数:
- 初始化模型时,设置
validation_fraction(比如0.2,即从训练集划20%作为验证集),同时指定n_estimators和随机种子保证结果可复现。 - 拟合完成后,
model.train_score_是每轮训练的损失值(默认是Friedman MSE,越小越好),model.validation_scores_对应每轮的验证损失,两者长度均等于n_estimators。
代码示例:
from sklearn.ensemble import GradientBoostingRegressor from sklearn.datasets import make_regression import matplotlib.pyplot as plt # 生成示例回归数据 X, y = make_regression(n_samples=1000, n_features=10, random_state=42) # 初始化梯度提升回归模型 gbr = GradientBoostingRegressor( n_estimators=1000, validation_fraction=0.2, random_state=42 ) gbr.fit(X, y) # 获取训练与验证分数数组 train_scores = gbr.train_score_ val_scores = gbr.validation_scores_ # 绘制对比曲线 plt.figure(figsize=(10,6)) plt.plot(range(1, 1001), train_scores, label='训练损失(MSE)') plt.plot(range(1, 1001), val_scores, label='验证损失(MSE)') plt.xlabel('迭代次数(Estimator数量)') plt.ylabel('损失值(MSE)') plt.title('梯度提升回归每轮迭代的训练与验证损失') plt.legend() plt.show()
方法2:交叉验证下的每轮平均分数(多折)
如果需要交叉验证后的每轮平均分数,得手动循环每个折,利用warm_start=True逐步训练并记录分数:
- 用KFold拆分数据集,对每个折单独处理
- 初始化模型时设置
warm_start=True,每次迭代仅增加1个estimator,避免重复训练 - 每轮拟合后,计算当前训练集和验证集的损失,最后取所有折的平均值
代码示例:
from sklearn.model_selection import KFold import numpy as np # 设置交叉验证参数 kf = KFold(n_splits=5, shuffle=True, random_state=42) n_estimators = 1000 # 初始化存储所有折分数的数组 all_train_scores = np.zeros((5, n_estimators)) all_val_scores = np.zeros((5, n_estimators)) fold_idx = 0 for train_idx, val_idx in kf.split(X, y): X_train, X_val = X[train_idx], X[val_idx] y_train, y_val = y[train_idx], y[val_idx] # 初始化模型,warm_start=True允许逐步添加estimator gbr = GradientBoostingRegressor( n_estimators=1, warm_start=True, random_state=42 ) for i in range(n_estimators): # 每轮拟合(warm_start=True,在上一轮基础上新增1个estimator) gbr.n_estimators = i + 1 gbr.fit(X_train, y_train) # 记录当前轮训练损失 all_train_scores[fold_idx, i] = gbr.train_score_[-1] # 计算当前轮验证损失(MSE) y_pred = gbr.predict(X_val) all_val_scores[fold_idx, i] = np.mean((y_pred - y_val)**2) fold_idx += 1 # 计算每轮的平均分数 mean_train_scores = all_train_scores.mean(axis=0) mean_val_scores = all_val_scores.mean(axis=0) # 绘制交叉验证后的对比曲线 plt.figure(figsize=(10,6)) plt.plot(range(1, n_estimators+1), mean_train_scores, label='平均训练损失') plt.plot(range(1, n_estimators+1), mean_val_scores, label='平均验证损失') plt.xlabel('迭代次数(Estimator数量)') plt.ylabel('损失值(MSE)') plt.title('交叉验证下梯度提升回归每轮迭代的训练与验证损失') plt.legend() plt.show()
注意事项
- 默认情况下,
train_score_和validation_scores_存储的是损失值(回归任务为MSE),回归任务一般不使用精度作为评估指标。如果需要R²等其他指标,可以手动计算每轮模型在训练/验证集上的对应值。 - 方法2的计算量较大(尤其是当
n_estimators设置很大时),可以根据需求调整迭代次数或采用并行处理优化。
内容的提问来源于stack exchange,提问作者connor.rawls
相关产品推荐
相关产品推荐

