首页 > 编程知识 正文

自动超参数优化算法,自动超参数优化算法有哪些

时间:2023-05-04 09:37:19 阅读:266149 作者:4783

文章目录 技术介绍核心技术栈 项目选择数据基础模型Hyperopt 实现数据读取使用lightgbm中的cv方法定义参数空间展示结果 贝叶斯优化原理使用lightgbm中的cv方法创建参数搜索空间并调用获取最佳结果继续训练 总结参考

技术介绍

自动化机器学习就是能够自动建立机器学习模型的方法,其主要包含三个方面:方面一,超参数优化;方面二,自动特征工程与机器学习算法自动选择;方面三,神经网络结构搜索。本文侧重于方面一,如何对超参数进行自动优化。

在机器学习中,模型本身的参数是可以通过训练数据来获取的,这些参数属于算法的普通参数,通过数据训练获得算法合适的参数,构建强大的模型本身就是机器学习的核心目标。但是机器学习算法本身还存在在超参数,超参数就是那些需要科学家手动设置的参数,如SVM的核函数,Lasso的alpha,决策树的最大深度与分支条件,随机森林的子采样率和决策树类型等等等等。如何对这些超参数进行自动优化,而非手动调节正是自动化机器学习的第一步。在这方面一般而言我们是将算法本身视作一个特殊的非凸函数,然后将超参数作为输入,来进行非凸函数优化。而对于非凸函数优化就属于比较成熟的研究领域了。

目前对于超参数优化常用的优化方法有四:(1)随机搜索(2)遗传算法或者粒子群算法等遗传学派方法(3)TPE树搜索(4)贝叶斯优化等元学习方法。

前两类方法,随即搜索和遗传学派的效果都不是特别适用于超参数优化,主要是性能比较差,时间较长。其中遗传学派效果稍好一些,但是依旧表现一般。如果想要在Python中使用遗传学派进行超参数搜索,则需要借助deap库。TPE的主要实现则是hyperopt,贝叶斯优化的则需要借助bayesian-optimization来使用。本文主要讲的就是使用hyperopt与bayesian-optimization来进行自动化机器学习中的超参数优化。

核心技术栈 scikit-learnhyperoptbayesian-optimizationpandas 项目选择 数据

这里我们的数据集使用的是
该数据的下载可以前往http://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-red.csv

该数据为UCI的红酒质量数据集,标签为分数(整数),因此既可可用于回归,也可用于分类。

基础模型

由于我们主要做的是超参数优化,因为我们就需要选择一个比较适合的模型来作为基础模型,线性模型或许比较简单,但是性能太差。因为我们这里直接选择lightgbm作为基础模型,其不仅拥有顶尖的性能和许多适合演示的超参数,同时相对于xgboost的高速度也是我们选择他的一个重要原因。

Hyperopt

Hyperopt:是python中的一个用于"分布式异步算法组态/超参数优化"的类库。使用它我们可以摆脱繁杂的超参数优化过程,自动获取最佳的超参数。广泛意义上,可以将带有超参数的模型看作是一个必然的非凸函数,因此hyperopt几乎可以稳定的获取比手工更加合理的调参结果。尤其对于调参比较复杂的模型而言,其更是能以远快于人工调参的速度同样获得远远超过人工调参的最终性能。

目前中文文档的地址由本人FontTian在2017年翻译,但是hyperopt文档本身确实写的不怎么样。所以才有了这份教程。源代码请前往Github教程地址下载下载。

中文文档地址FontTian的博客Hyperopt官方文档地址 实现 数据读取

这里的数据读取比较特别,由于lightgbm自带一个数据读取器,而以这种数据读取器进行数据读取的话,lightgbm的速度会快一些。具体代码如下:

import numpy as npfrom sklearn.model_selection import train_test_splitdef GetDataByPandas(): import pandas as pd wine = pd.read_csv("/home/fonttian/Data/dataset/wine/wine.csv") y = np.array(wine.quality) X = np.array(wine.drop("quality", axis=1)) columns = np.array(wine.columns) return X, y, columnsX, y, wineNames = GetDataByPandas()# split data to [[0.8,0.2],01]x_train_all, x_predict, y_train_all, y_predict = train_test_split(X, y, test_size=0.10, random_state=100)x_train, x_test, y_train, y_test = train_test_split(x_train_all, y_train_all, test_size=0.2, random_state=100)import lightgbm as lgbtrain_data = lgb.Dataset(data=x_train,label=y_train)test_data = lgb.Dataset(data=x_test,label=y_test) 使用lightgbm中的cv方法

这里主要是使用lightgbm的的CV方法自定义一个函数,其输出结果为cv的最小误差。这里之所以选择最小是因为hyperopt本身的特殊性质,只能够求最小值(最大加负号即可,本身不提供最大化,最小化选择)

import hyperopttrain_all_data = lgb.Dataset(data=x_train_all,label=y_train_all)def hyperopt_objective(params): model = lgb.LGBMRegressor( num_leaves=31, max_depth=int(params['max_depth']) + 5, learning_rate=params['learning_rate'], objective='regression', eval_metric='rmse', nthread=-1, silent=1 ) num_round = 10 res = lgb.cv(model.get_params(),train_all_data, num_round, nfold=5, metrics='rmse',early_stopping_rounds=10) return min(res['rmse-mean']) # as hyperopt minimises 定义参数空间

使用hyperopt自带的函数定义参数空间,但是因为其randint()方法产生的数组范围是从0开始的,所以我额外定义了一些特殊的转换方法,对原始参数空间进行一次转换。上文中的max_depth=int(params['max_depth']) + 5就是这个作用,我们想要的搜索空间是从五开始,但是hyperopt本身不提供,所以我们直接给它加个五就可以了。

关于hyperopt中定义参数区间需要使用的函数请参考:

中文地址,请点击这里英文地址,请点击这里 import warningswarnings.filterwarnings("ignore")from numpy.random import RandomStateparams_space = { 'max_depth': hyperopt.hp.randint('max_depth', 6), 'learning_rate': hyperopt.hp.uniform('learning_rate', 1e-3, 5e-1),}trials = hyperopt.Trials()best = hyperopt.fmin( hyperopt_objective, space=params_space, algo=hyperopt.tpe.suggest, max_evals=50, trials=trials, rstate=RandomState(123)) 100%|██████████| 50/50 [00:14<00:00, 3.35trial/s, best loss: 0.5991675855681323] 展示结果

展示我们获取的最佳参数,但是要注意的是我们对hyperopt最初的取值范围做过一次转换,所这里的最大深度需要+5,也即是等于9

print("n展示hyperopt获取的最佳结果,但是要注意的是我们对hyperopt最初的取值范围做过一次转换")print(best) 展示hyperopt获取的最佳结果,但是要注意的是我们对hyperopt最初的取值范围做过一次转换{'learning_rate': 0.09532567649797613, 'max_depth': 4} 贝叶斯优化

贝叶斯优化则是另外一个非常重要的超参数优化方法,同时作用于自动化机器学习的第二和第三个方面。不过这里我们主要使用它来完成第一部分——超参数优化。

原理

贝叶斯优化通过构造函数的后验分布(高斯过程)来工作,该分布最能描述您要优化的函数。随着观察次数的增加,后验分布改善,并且算法变得更加确定,参数空间中的哪些区域值得探索,哪些区域不值得探索。

随着您一遍又一遍的迭代,该算法会考虑到对目标函数的了解,从而平衡其探索和开发的需求。在每个步骤中,将高斯过程拟合到已知样本(先前探索的点),然后使用后验分布结合探索策略(例如UCB(上限可信度)或EI(预期改进))来确定接下来应该探索的一点。

此过程旨在最大程度地减少找到与最佳组合接近的参数组合所需的步骤。为此,此方法使用了代理优化问题(查找获取函数的最大值),尽管这仍然是一个难题,但更便宜(在计算意义上),可以使用通用工具。因此,贝叶斯优化最适合需要优化函数采样的情况。有关此方法的正确讨论,请参见参考资料。

使用lightgbm中的cv方法

这里和之前一样我们使用cv方法创建一个函数,以供bayesian-optimization使用。具体代码如下:

train_all_data = lgb.Dataset(data=x_train_all, label=y_train_all)def lgb_cv(n_estimators, num_leaves, max_depth, learning_rate): model = lgb.LGBMRegressor(n_estimators=int(n_estimators), num_leaves=int(num_leaves), max_depth=int(max_depth), learning_rate=learning_rate, objective='regression', eval_metric='rmse', nthread=-1, ) num_round = 10 res = lgb.cv(model.get_params(), train_all_data, num_round, nfold=5, metrics='rmse', early_stopping_rounds=10) return -min(res['rmse-mean']) # as hyperopt minimises

这段代码和之前的主要差别就是多加了几个参数,同时输出结果加上了负号,也就是求最大值。另外超参数的传递方式也不同,之前是通过一个dict进行超参数的传递,而现在则需要直接定义超参数为函数lgb_cv的传入参数。

创建参数搜索空间并调用

在这里ayesian-optimization库的搜索空间创建方法要简洁的多,而另外一个不同之处在于训练时需要传入的参数:

n_iter:您要执行贝叶斯优化的步骤。步骤越多,您越有可能找到一个好的最大值。init_points:您要执行多少步随机探索。随机勘探可以通过使勘探空间多样化而有所帮助。 import warningswarnings.filterwarnings("ignore")pbounds = {'n_estimators': (200, 800), 'num_leaves': (30, 70), 'max_depth': (5, 8), 'learning_rate': (0.001, 0.1), }from bayes_opt import BayesianOptimizationlgb_bayes = BayesianOptimization(lgb_cv, pbounds=pbounds, random_state=1)lgb_bayes.maximize( init_points=5, n_iter=20,)

由上面可以看出iter = init_points + n_iter;而输出的类表中12和19颜色不同于其他行,是紫色的。贝叶斯优化在优化到一定程度之后会产生跳变,以避免陷入某个局部最优值,而每次跳变前都会有一个最佳结果,紫色标出。

获取最佳结果

最佳接通使用.max获取:

lgb_bayes.max {'target': -0.6006942523702591, 'params': {'learning_rate': 0.1, 'max_depth': 8.0, 'n_estimators': 458.0804237879571, 'num_leaves': 56.7334370138792}} 继续训练

只要不重新创建并覆盖原有的类,那么我们就可以使用maximize函数,重新进行训练,训练次数会紧随之前的次数,这里中间省略了十次,因此变为了35:

lgb_bayes.maximize( init_points=3, n_iter=10,)

总结

超参数优化是机器学习中绕不过的一件事情,传统的方法以手动为主,对于熟练度高,对算法了解程度高的工程师或科学家,确实可以比较快速的手动获取比较好的结果。但是一旦想要靠人力获取最佳结果,那么在一定程度后进度必然会变的缓慢无比。而相比之下,算法则可以不断地计算,不断的进步,虽然由于缺乏专业工程师的先验知识,超参数优化算法起步往往会慢很多,但是经过一段时间的计算后,其却可以达到人很难达到的高度。从这方面来说,超参数优化又是我们不得不懂,不得不使用的关键性技术。

参考 https://github.com/FontTian/hyperopt-doc-zhhttps://github.com/fmfn/BayesianOptimization

other:

自动化机器学习(二)自动构建机器学习流水线自动化机器学习(三)神经网络架构搜索综述(NAS)简述

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。