You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GridSearchCV未采用XGBRegressor指定评分方法的问题及解决需求

问题原因分析

你遇到的问题核心在于:GridSearchCV默认使用的是XGBRegressor自带的score()方法,而这个方法返回的是R²分数,和你在fit()里指定的eval_metric完全无关。

你在reg.fit()中传入的eval_metric只是告诉XGBoost在训练过程中监控哪个指标,但并不会改变GridSearchCV用来评估模型性能的逻辑——当scoring=None时,它只会调用模型的score()方法,而XGBRegressor的score()方法(继承自sklearn的回归器接口)默认返回的是决定系数R²,所以不管你传mae还是rmse,得到的测试分数都是同一个R²值。


解决方案

要让GridSearchCV返回与eval_metric对应的结果,你需要显式指定scoring参数,或者自定义评分函数,让GridSearchCV用你想要的指标来评估模型。下面是两种可行的方法:

方法1:使用sklearn内置的负向评分器

sklearn的评分器默认遵循"分数越高越好"的逻辑,而MAE/RMSE是误差指标(数值越小模型越好),所以需要使用它们的负向版本:

  • MAE对应neg_mean_absolute_error
  • RMSE对应neg_root_mean_squared_error

修改你的GridSearchCV初始化代码,加上scoring参数即可:

import numpy as np
from sklearn.model_selection import GridSearchCV, KFold
from sklearn.datasets import load_boston
import xgboost as xgb

rng = np.random.RandomState(31337)
boston = load_boston()
y = boston['target']
X = boston['data']
kf = KFold(n_splits=2, random_state=42, shuffle=True)  # 加shuffle让划分更合理,可选
folds = list(kf.split(X))

# 针对MAE的GridSearchCV
xgb_model = xgb.XGBRegressor(objective='reg:squarederror', verbose=False)
reg_mae = GridSearchCV(
    estimator=xgb_model,
    param_grid={'max_depth': [2], 'n_estimators': [50]},
    cv=folds,
    verbose=False,
    scoring='neg_mean_absolute_error'  # 指定MAE的负向评分
)
reg_mae.fit(X, y, **{'eval_metric': 'mae', 'verbose': False})
# 取负数得到实际MAE值
print('GridSearchCV mean(mae): ', -reg_mae.cv_results_['mean_test_score'][0])

# 针对RMSE的GridSearchCV
reg_rmse = GridSearchCV(
    estimator=xgb_model,
    param_grid={'max_depth': [2], 'n_estimators': [50]},
    cv=folds,
    verbose=False,
    scoring='neg_root_mean_squared_error'  # 指定RMSE的负向评分
)
reg_rmse.fit(X, y, **{'eval_metric': 'rmse', 'verbose': False})
# 取负数得到实际RMSE值
print('GridSearchCV mean(rmse): ', -reg_rmse.cv_results_['mean_test_score'][0])

方法2:自定义评分函数(更灵活)

如果需要完全匹配XGBoost计算的eval_metric结果,你可以用make_scorer自定义评分函数,适配自己的计算逻辑:

from sklearn.metrics import make_scorer, mean_absolute_error, mean_squared_error

# 自定义MAE评分函数
def xgb_mae(y_true, y_pred):
    return mean_absolute_error(y_true, y_pred)

# 自定义RMSE评分函数
def xgb_rmse(y_true, y_pred):
    return np.sqrt(mean_squared_error(y_true, y_pred))

# 使用自定义评分器
reg_mae_custom = GridSearchCV(
    estimator=xgb_model,
    param_grid={'max_depth': [2], 'n_estimators': [50]},
    cv=folds,
    verbose=False,
    scoring=make_scorer(xgb_mae, greater_is_better=False)  # MAE越小越好,所以设为False
)
reg_mae_custom.fit(X, y, **{'eval_metric': 'mae', 'verbose': False})
print('GridSearchCV mean(mae) (custom): ', -reg_mae_custom.cv_results_['mean_test_score'][0])

reg_rmse_custom = GridSearchCV(
    estimator=xgb_model,
    param_grid={'max_depth': [2], 'n_estimators': [50]},
    cv=folds,
    verbose=False,
    scoring=make_scorer(xgb_rmse, greater_is_better=False)
)
reg_rmse_custom.fit(X, y, **{'eval_metric': 'rmse', 'verbose': False})
print('GridSearchCV mean(rmse) (custom): ', -reg_rmse_custom.cv_results_['mean_test_score'][0])

预期输出

修改后,你会得到和XGBRegressor单独计算的MAE/RMSE平均值一致的结果:

GridSearchCV mean(mae):  1.1392865
GridSearchCV mean(rmse):  1.469283

这和你单独计算的(1.273626 + 1.004947)/2 ≈ 1.139、(1.647694 + 1.290872)/2 ≈ 1.469完全匹配。


内容的提问来源于stack exchange,提问作者Geir Inge

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 18:42:47