zoukankan      html  css  js  c++  java
  • 强大而精致的机器学习调参方法:贝叶斯优化

    一、简介

    贝叶斯优化用于机器学习调参由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

     
  • 相关阅读:
    内存泄露的小问题(转载)
    脚本错误:"return 语句不能在函数之外" (转载)
    转载:asp.net网页防刷新重复提交、防后退解决办法集!
    转载:一行代码搞定你的QueryString
    转载 PowerDesigner Name/Code自动调整
    无刷新仿google波形扭曲彩色Asp.net验证码
    转载:认识Web.config文件
    转载:将数据库从SQL2000迁移到SQL2005时,无法查看关系图的解决办法
    [转]WTL的windows mobile环境的配置(vs2008)[最终版,验证通过]
    [转].NET中Cache用法分析
  • 原文地址:https://www.cnblogs.com/mfryf/p/11411387.html
Copyright © 2011-2022 走看看