强大而精致的机器学习调参方法:贝叶斯优化

一、简介

贝叶斯优化用于机器学习调参由J. Snoek(2012)提出,主要思想是,给定优化的目标函数(广义的函数,只需指定输入和输出即可,无需知道内部结构以及数学性质),通过不断地添加样本点来更新目标函数的后验分布(高斯过程,直到后验分布基本贴合于真实分布。简单的说,就是考虑了上一次参数的信息**,从而更好的调整当前的参数。

他与常规的网格搜索或者随机搜索的区别是:

  • 贝叶斯调参采用高斯过程,考虑之前的参数信息,不断地更新先验;网格搜索未考虑之前的参数信息
  • 贝叶斯调参迭代次数少,速度快;网格搜索速度慢,参数多时易导致维度爆炸
  • 贝叶斯调参针对非凸问题依然稳健;网格搜索针对非凸问题易得到局部优最

二、理论

介绍贝叶斯优化调参,必须要从两个部分讲起:

  • 高斯过程,用以拟合优化目标函数
  • 贝叶斯优化,包括了“开采”和“勘探”,用以花最少的代价找到最优值

2.1 高斯过程

高斯过程可以用于非线性回归、非线性分类、参数寻优等等。以往的建模需要对 p(y|X)p(y|X)

2.3 缺点和不足

  • 高斯过程核矩阵不好选

三、例子

目前可以做贝叶斯优化的包非常多,光是python就有:

本文使用BayesianOptimization为例,利用sklearn的随机森林模型进行分类

安装

pip install bayesian-optimization

前期准备

from sklearn.datasets import make_classification
from sklearn.ensemble import RandomForestClassifier
from sklearn.cross_validation import cross_val_score
from bayes_opt import BayesianOptimization

# 产生随机分类数据集,10个特征, 2个类别
x, y = make_classification(n_samples=1000,n_features=10,n_classes=2)

我们先看看不调参的结果:

rf = RandomForestClassifier()
print(np.mean(cross_val_score(rf, x, y, cv=20, scoring='roc_auc')))

>>> 0.965162

可以看到,不调参的话模型20此交叉验证AUC均值是0.965162,算是一个不错的模型,那么如果用bayes调参结果会怎么样呢

bayes调参初探

我们先定义一个目标函数,里面放入我们希望优化的函数。比如此时,函数输入为随机森林的所有参数,输出为模型交叉验证5次的AUC均值,作为我们的目标函数。因为bayes_opt库只支持最大值,所以最后的输出如果是越小越好,那么需要在前面加上负号,以转为最大值。由于bayes优化只能优化连续超参数,因此要加上int()转为离散超参数。

def rf_cv(n_estimators, min_samples_split, max_features, max_depth):
    val = cross_val_score(
        RandomForestClassifier(n_estimators=int(n_estimators),
            min_samples_split=int(min_samples_split),
            max_features=min(max_features, 0.999), # float
            max_depth=int(max_depth),
            random_state=2
        ),
        x, y, 'roc_auc', cv=5
    ).mean()
    return val

然后我们就可以实例化一个bayes优化对象了:

 rf_bo = BayesianOptimization(
        rf_cv,
        {'n_estimators': (10, 250),
        'min_samples_split': (2, 25),
        'max_features': (0.1, 0.999),
        'max_depth': (5, 15)}
    )

里面的第一个参数是我们的优化目标函数,第二个参数是我们所需要输入的超参数名称,以及其范围。超参数名称必须和目标函数的输入名称一一对应。

完成上面两步之后,我们就可以运行bayes优化了!

rf_bo.maximize()

完成的时候会不断地输出结果,如下图所示:

等到程序结束,我们可以查看当前最优的参数和结果:

rf_bo.res['max']

>>> {‘max_params’: {‘max_depth’: 5.819908283575526,
‘max_features’: 0.4951745603509127,
‘min_samples_split’: 2.3110014720414958,
‘n_estimators’: 249.73529231990733},
‘max_val’: 0.9774079407940794}

bayes调参进阶

上面bayes算法得到的参数并不一定最优,当然我们会遇到一种情况,就是我们已经知道有一组或是几组参数是非常好的了,我们想知道其附近有没有更好的。这个操作相当于上文bayes优化中的Explore操作,而bayes_opt库给了我们实现此方法的函数:


rf_bo.explore(
    {'n_estimators': [10, 100, 200],
        'min_samples_split': [2, 10, 20],
        'max_features': [0.1, 0.5, 0.9],
        'max_depth': [5, 10, 15]
    }
)

这里我们添加了三组较优的超参数,让其在该参数基础上进行explore,可能会得到更好的结果。

同时,我们还可以修改高斯过程的参数,高斯过程主要参数是核函数(kernel),还有其他参数可以参考sklearn.gaussianprocess

gp_param={'kernel':None}
rf_bo.maximize(**gp_param)

最终我们的到参数如下:

{'max_params': {'max_depth': 5.819908283575526,
  'max_features': 0.4951745603509127,
  'min_samples_split': 2.3110014720414958,
  'n_estimators': 249.73529231990733},
 'max_val': 0.9774079407940794}

运行交叉验证测试一下:

rf = RandomForestClassifier(max_depth=6, max_features=0.39517, min_samples_split=2, n_estimators=250)
np.mean(cross_val_score(rf, x, y, cv=20, scoring='roc_auc'))
>>> 0.9754953

得到最终结果是0.9755,比之前的0.9652提高了约0.01,做过kaggle的朋友都懂,这在后期已经是非常大的提高了!到后面想提高0.001都极其困难,因此bayes优化真的非常强大!

结束!

Reference

 

转载于:https://www.cnblogs.com/mfryf/p/11411387.html

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 下面是一个使用贝叶斯优化来调整XGBoost超参数的示例代码: ```python import xgboost as xgb from bayes_opt import BayesianOptimization # 定义优化目标函数 def xgb_cv(max_depth, learning_rate, n_estimators, gamma, min_child_weight, subsample, colsample_bytree): params = { 'eval_metric': 'rmse', 'max_depth': int(max_depth), 'learning_rate': learning_rate, 'n_estimators': int(n_estimators), 'gamma': gamma, 'min_child_weight': int(min_child_weight), 'subsample': subsample, 'colsample_bytree': colsample_bytree, 'n_jobs': -1, 'random_state': 42 } # 进行交叉验证 cv_result = xgb.cv(params, dtrain, num_boost_round=100, early_stopping_rounds=10, stratified=False) return -1.0 * cv_result['test-rmse-mean'].iloc[-1] # 定义参数范围 pbounds = {'max_depth': (3, 10), 'learning_rate': (0.01, 0.3), 'n_estimators': (50, 200), 'gamma': (0, 10), 'min_child_weight': (1, 10), 'subsample': (0.5, 1), 'colsample_bytree': (0.1, 1)} # 进行贝叶斯优化,找到最优超参数 optimizer = BayesianOptimization(f=xgb_cv, pbounds=pbounds, random_state=42) optimizer.maximize(init_points=5, n_iter=25) # 输出最优结果 print(optimizer.max) ``` 在上面的代码中,我们使用了XGBoost和贝叶斯优化的库。我们首先定义了一个优化的目标函数xgb_cv,它接受一些参数,构建XGBoost模型,并对模型进行交叉验证来计算目标值。然后我们定义了每个参数的范围,然后使用BayesianOptimization库来进行贝叶斯优化,找到最大化目标函数的最优参数组合。最后,我们输出了最优结果。 ### 回答2: 贝叶斯优化是一种用于超参数调优的统计方法,能够更高效地找到最优参数组合。在使用XGBoost算法时,也可以通过贝叶斯优化来搜索最佳的超参数组合。 首先,我们需要定义一个目标函数,用于评估不同超参数组合的性能。目标函数通常会根据给定超参数组合在训练集上进行交叉验证,并返回一个性能指标,如准确率或均方根误差。 接下来,我们需要定义超参数的搜索空间。对于XGBoost算法,常见的超参数包括学习率、树的深度、子采样比例等。贝叶斯优化通过在搜索空间内随机采样一些点,并利用高斯过程模型来建立超参数与性能指标之间的映射关系,进而根据这个模型预测下一个最有可能的超参数组合。 按照这个过程,我们可以进行多次迭代,每次得到一个新的超参数组合,并利用目标函数评估其性能。然后,我们将其加入贝叶斯优化的历史数据集中,并更新高斯过程模型,以便更准确地预测下一个最佳超参数组合。 最后,当迭代次数达到预设值或满足一定终止条件时,我们就可以得到一个在训练集上表现最好的超参数组合。 总结来说,贝叶斯优化在XGBoost超参数调优中能够更高效地搜索最佳超参数组合。通过定义目标函数和搜索空间,并利用贝叶斯优化方法迭代找到最佳超参数组合,可以显著提高XGBoost算法的性能。 ### 回答3: 贝叶斯优化是一种用于调整XGBoost模型的超参数的方法。XGBoost是一种强大机器学习框架,但正确选择合适的超参数对模型性能至关重要。 首先,我们需要确定要调整的超参数。常见的超参数包括学习率、树的最大深度、叶子节点最小权重等。这些超参数的值将影响模型的准确性和复杂性。 接下来,我们使用贝叶斯优化方法来找到最佳的超参数组合。贝叶斯优化考虑了每次迭代的参数和结果之间的关联性。它建立了一个概率模型,并在每次迭代中根据先前的结果调整超参数来选择下一次迭代的参数。这允许我们在较少的迭代次数内找到最佳的超参数组合,从而节省时间和计算资源。 在选择下一组参数并进行训练之后,我们需要计算所得模型的性能指标,如准确率、精确率、召回率等。根据这些指标,我们可以确定当前超参数组合的性能,并将其与先前的结果进行比较。 接着,我们将优化过程迭代多次,直到找到最佳的超参数组合为止。通过使用贝叶斯优化方法,我们能够在较短时间内找到最优的超参数组合,提高模型的准确性和鲁棒性。 综上所述,贝叶斯优化是一种有效的方法来调整XGBoost模型的超参数。通过建立概率模型并根据先前的结果来选择下一个参数组合,贝叶斯优化能够帮助我们快速找到最佳的超参数组合,从而提高模型的性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值