为什么在 XGBRegressor 中使用优化参数(MSE 是最小化 objective)给我的 RMSE 与优化 RMSE 不同?

Why the using optimized parameters (MSE is the minimize objective) in the XGBRegressor gives me different RMSE than the optimized RMSE?

我正在处理回归量问题。我正在调整 XGBRegressor 模型的参数,因此我使用库 GPyOpt 来获取优化参数。函数 returns 一个包含 5 个元素的数组和最小化 MSE,即 1813。然后我尝试在模型中输入优化参数,然后输入模型的 MSE returns 2810。我想知道为什么会这样?

我对 GPyOpt 库非常熟悉。关于我面临的这个问题没有很多信息所以我想知道这是因为我的粗心错误还是我不明白?

import GPyOpt
from GPyOpt.methods import BayesianOptimization
def cv_score(parameters):
    parameters = parameters[0]
    score = cross_val_score(
                XGBRegressor(learning_rate=parameters[0],
                              gamma=int(parameters[1]),
                              max_depth=int(parameters[2]),
                              n_estimators=int(parameters[3]),
                              min_child_weight = parameters[4]), 
                x_train, y_train, scoring='neg_mean_squared_error').mean()
    score = np.array(score)
    return score

bds = [{'name': 'learning_rate', 'type': 'continuous', 'domain': (0, 1)},
        {'name': 'gamma', 'type': 'continuous', 'domain': (0, 5)},
        {'name': 'max_depth', 'type': 'discrete', 'domain': (1, 50)},
        {'name': 'n_estimators', 'type': 'discrete', 'domain': (1, 300)},
        {'name': 'min_child_weight', 'type': 'discrete', 'domain': (1, 10)}]


optimizer = BayesianOptimization(f=cv_score, domain=bds,
                                 model_type='GP',
                                 acquisition_type ='EI',
                                 acquisition_jitter = 0.05,
                                 exact_feval=True, 
                                 maximize=True)
optimizer.run_optimization(max_iter=20)
optimizer.x_opt

array([ 0.56133897, 2.697656 , 50. , 300. , 10. ])

xgb_final_param = {'learning_rate': 0.56133897, 'gamma': 2.697656, 'max_depth': 50, 'n_estimators': 300, 'min_child_weight': 10}
xgb_final = SklearnExtra(clf = XGBRegressor(), seed = Seed, params = xgb_final_param)
xgb_final.fit(x_train, y_train)
evaluate(xgb_final, x_test, y_test) #evaluate returns MSE

我预计 MSE 大约在 1813 左右,但我得到了 2810。所以我想知道为什么

gpyopt 中的离散变量不是由它们的 min/max 指定的,而是由它们的整个值列表指定的。为什么?因为你可能有不连续性,也就是说你的变量可能只取值 (1, 3, 8)。看一个例子 here.

因此在您的示例中,正确指定这些域的方法是生成所有可能值的列表:

{'name': 'max_depth', 'type': 'discrete', 'domain': list(range(1, 51))}

其他离散变量也是如此。请注意,对于连续代码,您的代码很好 - 它们由它们的范围指定。