Python 轻型GBM模型的贝叶斯优化
我能够通过贝叶斯优化成功地提高XGBoost模型的性能,但在使用Light GBM(我的首选)时,通过贝叶斯优化所能达到的最佳效果要比使用默认超参数和遵循标准提前停止方法所能达到的效果差 当通过贝叶斯优化进行优化时,我已经确定在搜索图面中包含算法的默认超参数,以供参考 下面的代码显示了Light GBM模型中的RMSE,使用seaborn的diamonds数据框作为我的工作示例,具有默认的超参数:Python 轻型GBM模型的贝叶斯优化,python,pandas,bayesian,hyperparameters,lightgbm,Python,Pandas,Bayesian,Hyperparameters,Lightgbm,我能够通过贝叶斯优化成功地提高XGBoost模型的性能,但在使用Light GBM(我的首选)时,通过贝叶斯优化所能达到的最佳效果要比使用默认超参数和遵循标准提前停止方法所能达到的效果差 当通过贝叶斯优化进行优化时,我已经确定在搜索图面中包含算法的默认超参数,以供参考 下面的代码显示了Light GBM模型中的RMSE,使用seaborn的diamonds数据框作为我的工作示例,具有默认的超参数: #pip install bayesian-optimization import seabor
#pip install bayesian-optimization
import seaborn as sns
from sklearn.model_selection import train_test_split
import lightgbm as lgb
from bayes_opt import BayesianOptimization
df = sns.load_dataset('diamonds')
df["color"] = df["color"].astype('category')
df["color_cat"] = df["color"].cat.codes
df = df.drop(["color"],axis = 1)
df["cut"] = df["cut"].astype('category')
df["cut_cat"] = df["cut"].cat.codes
df = df.drop(["cut"],axis = 1)
df["clarity"] = df["clarity"].astype('category')
df["clarity_cat"] = df["clarity"].cat.codes
df = df.drop(["clarity"],axis = 1)
y = df['price']
X = df.drop(['price'], axis=1)
seed = 7
test_size = 0.3
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=test_size,random_state=seed)
train_lgb = lgb.Dataset(X_train, y_train)
eval_lgb = lgb.Dataset(X_test, y_test, reference = train_lgb)
params = { 'objective': 'regression',
'metric': 'RMSE',
'learning_rate': 0.02}
lgb_reg = lgb.train(params, train_lgb, num_boost_round = 10000, early_stopping_rounds=50, verbose_eval = 100, valid_sets=eval_lgb)
结果
OUT:
Training until validation scores don't improve for 50 rounds.
Early stopping, best iteration is:
[1330 (n_estimators)] valid_0's rmse: 538.728
这里,我尝试实施贝叶斯优化并得到RMSE值:
def modelFitter(colsampleByTree, subsample,maxDepth, num_leaves):
model = lgb.LGBMRegressor(learning_rate=0.02, n_estimators=10000, max_depth=maxDepth.astype("int32"), subsample=subsample, colsample_bytree=colsampleByTree,num_leaves=num_leaves.astype("int32"))
evalSet = [(X_test, y_test)]
model.fit(X_train, y_train, eval_metric="rmse", eval_set=evalSet, early_stopping_rounds=50, verbose=False)
bestScore = model.best_score_[list(model.best_score_.keys())[0]]['rmse']
return -bestScore
# Bounded region of parameter space
pbounds = {'colsampleByTree': (0.8,1.0), 'subsample': (0.8,1.0), 'maxDepth': (2,5), 'num_leaves': (24, 45)}
optimizer = BayesianOptimization(
f=modelFitter,
pbounds=pbounds,
random_state=1)
optimizer.maximize(init_points=5,n_iter=5) #n_iter=bayesian, init_points=random
结果
iter | target | colsam... | maxDepth | num_le... | subsample |
-------------------------------------------------------------------------
| 1 | -548.7 | 0.8834 | 4.161 | 24.0 | 0.8605 |
| 2 | -642.4 | 0.8294 | 2.277 | 27.91 | 0.8691 |
| 3 | -583.5 | 0.8794 | 3.616 | 32.8 | 0.937 |
| 4 | -548.7 | 0.8409 | 4.634 | 24.58 | 0.9341 |
| 5 | -583.5 | 0.8835 | 3.676 | 26.95 | 0.8396 |
| 6 | -548.7 | 0.8625 | 4.395 | 24.29 | 0.8968 |
| 7 | -548.7 | 0.8435 | 4.603 | 24.42 | 0.9298 |
| 8 | -551.5 | 0.9271 | 4.266 | 24.11 | 0.8035 |
| 9 | -548.7 | 0.8 | 4.11 | 24.08 | 1.0 |
| 10 | -548.7 | 0.8 | 4.44 | 24.45 | 0.9924 |
在贝叶斯优化过程中生成的RMSE(-1 x“目标”)应优于LightGBM默认值生成的RMSE,但我无法获得更好的RMSE(通过上述“正常”提前停止过程,寻找更好/更高的-538.728)
maxDepth和num_leaves应该是整数;似乎有一个公开的票证来强制执行此操作(即引入“ptypes”):
贝叶斯优化在LightGBM上似乎找不到更好的解决方案,但在XGBoost上却找到了更好的解决方案,这有什么原因吗?这个问题属于stats.SE;我鼓励你在那边的Meta上问为什么它不相关。这可能有点过于宽泛,因为可能有一些可能的原因造成差异 1) 仔细检查两个模型中优化的超参数空间是否一致。(pbounds参数目前似乎仅在LGBM模型中定义) 2) 如果搜索空间的范围太小,那么在默认值处可能存在一个局部最大值,这通常是一个启发式的、经验法则“相当好”的默认值集 3) 这两种模型都是梯度推进模型,但它们有不同的方法来确定最佳分割值。这意味着您的解决方案空间可能会从算法的角度开发不同的最优值,这只能从其给定的体系结构中进行最佳猜测,如果优化功能发生变化,您可能会在默认LGBM超参数值下开发最佳解
4) 如果你在寻找一个极度次优的搜索空间,类似于寻找一个小的子空间,你最终会在max得到平庸的结果,这大大低于默认设置。(这就像在寻找海洋中的山峰,而默认情况下可能是某个局部山丘。)对于回归,我使用lightgbm软件包中的cv函数实现了更好的结果 my
BayesianOptimization()
中的“黑盒”函数返回l1平均值的最小值
def black_box_lgbm():
params = {...} #Your params here
cv_results = lgb.cv(params, train_data, nfold=5, metrics='mae', verbose_eval = 200, stratified=False)
return min(cv_results['l1-mean'])
在调用
BayesianOptimization()
上的maximize()
并以最低的l1错误获取结果后,我重新训练了一个模型,并与默认值进行了比较。与默认值相比,这始终会导致较低的MSE。与编码相关的问题是什么?这看起来像是属于stats exchangeHi@Yuca的-我上面提到的代码中是否有导致贝叶斯优化不起作用的东西?请回答我的问题。然后我可以回答你的:)是的,我真诚地认为你在那里可能有更好的机会。我没有答案给你,因为它需要高度的专业化和大量的空闲时间来回答,这是一种罕见的商品。因此,您可能需要等待很长时间,或者在CodeReviewId中发布您是否尝试使用默认参数拟合LGBMRegressionor
,并查看结果指标?原因是本机API(lgb.train
)和scikit学习API(LGBMRegressor
)的默认值可能不同(它们不应该是,但我不确定作者是否提供了任何保证)。此外,您在本机API中使用的默认值是max_depth=-1
,而您的优化边界与此不同。限制深度可能导致不同的树结构