贝叶斯优化不能提高XGBoost的预测精度

问题描述 投票:1回答:2

我对XGBoost模型的贝叶斯优化存在一些严重问题。贝叶斯优化产生的最佳超参数导致RMSE高于我自己选择的超参数。

这里是贝叶斯优化的代码:


space = [ 
    Categorical(["gbtree", "gblinear", "dart"], name="booster"),
    Real(0.01, 1.0, prior='log-uniform', name = 'learning_rate'),
    Real(1e-16, 1e5, prior="log-uniform", name="min_child_weight"), 
    Integer(4,20, name="max_depth"), 
    Integer(0,20, name= "max_delta_step"),
    Real(0.01, 1.0, prior="uniform", name="subsample"),
    Real(0.5, 1.0, name="colsample_bytree"), 
    Real(0.5, 1.0, name= "colsample_bylevel"), 
    Real(0.5, 1.0, name= "colsample_bynode"),
    Integer(30, 100, name="reg_lambda"), 
    Real(0.0, 100, name="reg_alpha"),
    Real(30, 100, prior= "log-uniform", name="gamma"),
    Integer(50, 1000, name="estimators"), 
    Integer(1,20, name="scale_pos_weight"), 
    Categorical(["reg:linear"], name="objective"),
    Categorical(["gain", "weight", "cover", "total_gain" "total_cover"],name= "importance_type"),     
]


X = df[features].values
y= df[outcome].values



@skopt.utils.use_named_args(space)
def objective(**params):
    model.set_params(**params)
    kfold = KFold(n_splits=5)
    results = cross_val_score(
        model, X, y, cv=kfold, scoring="neg_mean_squared_error", n_jobs=-1)
    rmse = np.sqrt(-results.mean())
    return(rmse)

gp = gp_minimize(func=objective, dimensions= space,  n_calls=100, random_state=42, n_jobs=1)

然后通过贝叶斯优化的最佳RMSE:1.8467559504498372

但是如果我自己选择超参数(max_depth = 15,estimators = 1000,learning_rate = 0.1),我已经得到了更好的结果:RMSE = 1.66。因此,贝叶斯优化并没有真正优化我的RMSE。

这是我自己选择超参数的代码:

np.random.seed(0)
gradboodf= gradboodf.reindex(np.random.permutation(gradboodf.index))

# Define y and X 
X = gradboodf[features].values
y = gradboodf["Rent per Sqm"].values


# K-fold cross Validation and XGBoost
RMSE = []
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)  
kfold = KFold(n_splits= 10, shuffle=False)

model = xgb.XGBRegressor(max_depth=15, cv=kfold, estimators=1000, learning_rate=0.1) 

model.fit(X_train,y_train)
#Prediction 
y_pred = model.predict(X_test)
pred = pd.DataFrame()
pred["Prediction"] = y_pred
# RMSE 
rmse = np.sqrt(mean_squared_error(y_test,y_pred))
RMSE.append(rmse)
print(np.mean(RMSE))

可能是什么原因???

python machine-learning scikit-learn xgboost hyperparameters
2个回答
0
投票

我想通过一点直觉来扩展一个完美的@desertnaut answer,这可能会出错,以及如何改善贝叶斯优化。贝叶斯优化通常使用某种形式的点(超参数)之间的距离(和相关性)计算。不幸的是-通常在参数空间上施加这样的几何结构几乎是不可能的。与该问题有关的重要问题之一是在优化值和超参数之间施加Lipshitzlinear依赖性。要了解更多细节,让我们看一下:

Integer(50, 1000, name="estimators")

参数。让我们检查一下添加100个估计量如何改变优化问题的行为。如果将100个估算器添加到50个中,则估算器的数量将增加三倍,并可能显着提高表达能力。如何从900更改为1000应该没有那么重要。因此,如果优化过程以-首先假设600个估算器为起点-它会注意到,将估算器变化约50并不会改变太多,因此会跳过优化此超参数(因为它假定为准连续线性依赖性) 。这可能会严重损害勘探过程。

为了克服此问题,最好对此参数使用某种log分布。应用了类似的技巧,例如learning_rate参数。


1
投票

没有任何[保证贝叶斯优化将提供最佳超参数值;引自Goodfellow,Bengio和Courville(Deep Learning)的权威教科书page 430

目前,我们不能明确建议贝叶斯超参数优化是获得更好的深度学习结果的既定工具,或者获得较少结果的结果。贝叶斯超参数优化有时表现与人类专家相当,有时更好,但失败了灾难性地解决其他问题。可能值得尝试看看它是否适用于特定问题,但尚未完全成熟或可靠。

换句话说,它实际上只是一种启发式方法(如网格搜索),并且您报告的内容不是

必要

表示您做错了什么或要纠正的程序有问题。 。
© www.soinside.com 2019 - 2024. All rights reserved.