文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

算法模型自动超参数优化方法

2024-12-03 14:56

关注

超参数:

定义关于模型的更高层次的概念,如复杂性或学习能力 不能直接从标准模型培训过程中的数据中学习,需要预先定义 可以通过设置不同的值,训练不同的模型和选择更好的测试值来决定 参数空间的搜索一般由以下几个部分构成:

Scikit-Learn中的超参数优化方法

在机器学习模型中,比如随机森林中决策树的个数,人工神经网络模型中的隐藏层层数和每层的节点个数,正则项中常数大小等等,它们都需要事先指定。超参数选择不恰当,就会出现欠拟合或者过拟合的问题。在Scikit-Learn中,超参数是在学习过程开始之前设置其值的参数。典型的例子包括支持向量机里的C、kernel、gamma等。

  1. class sklearn.svm.SVC(*, C=1.0, kernel='rbf', degree=3, gamma='scale', coef0=0.0, shrinking=True, probability=False, tol=0.001, cache_size=200, class_weight=None, verbose=False, max_iter=-1, decision_function_shape='ovr', break_ties=False, random_state=None) 

使用过程中可以使用estimator.get_params() 获得学习器模型的超参数列表和当前取值。

Sklearn提供了两种通用的超参数优化方法:网格搜索与随机搜索。

交叉验证 (Cross-Validation)- CV 简介

在机器学习里,通常来说我们不能将全部用于数据训练模型,否则我们将没有数据集对该模型进行验证,从而评估我们的模型的预测效果。为了解决这一问题,有如下常用的方法:

The Validation Set Approach(验证集方案)

这种是方法最简单的,也是很容易就想到的。我们可以把整个数据集分成两部分,一部分用于训练,一部分用于验证,这也就是我们经常提到的训练集(training set)和测试集(test set)。

不过,这个简单的方法存在两个弊端:

基于这样的背景,有人就提出了Cross-Validation方法,也就是交叉验证。

Cross-Validation

LOOCV(留一法)

LOOCV即(Leave-one-out cross-validation)。像Test set approach一样,LOOCV方法也包含将数据集分为训练集和测试集这一步骤。但是不同的是,我们只用一个数据作为测试集,其他的数据都作为训练集,并将此步骤重复N次(N为数据集的数据数量)。

假设我们现在有n个数据组成的数据集,那么LOOCV的方法就是每次取出一个数据作为测试集的唯一元素,而其他n-1个数据都作为训练集用于训练模型和调参。结果就是我们最终训练了n个模型,每次都能得到一个MSE。而计算最终test MSE则就是将这n个MSE取平均。

比起test set approach,LOOCV有很多优点。首先它不受测试集合训练集划分方法的影响,因为每一个数据都单独的做过测试集。同时,其用了n-1个数据训练模型,也几乎用到了所有的数据,保证了模型的bias更小。不过LOOCV的缺点也很明显,那就是计算量过于大,是test set approach耗时的n-1倍。

K-fold Cross Validation(k 折交叉验证)

K折交叉验证,和LOOCV的不同在于,我们每次的测试集将不再只包含一个数据,而是多个,具体数目将根据K的选取决定。比如,如果K=5,那么我们利用五折交叉验证的步骤就是:

不难理解,其实LOOCV是一种特殊的K-fold Cross Validation(K=N)。最后K的选取是一个Bias和Variance的trade-off。K越大,每次投入的训练集的数据越多,模型的Bias越小。但是K越大,又意味着每一次选取的训练集之前的相关性越大(考虑最极端的例子,当k=N,也就是在LOOCV里,每次都训练数据几乎是一样的)。而这种大相关性会导致最终的test error具有更大的Variance。一般K值选择5或10。

网格搜索 GridSearchCV

我们在选择超参数有两个途径:1)凭经验;2)选择不同大小的参数,带入到模型中,挑选表现最好的参数。通过途径2选择超参数时,人力手动调节注意力成本太高,非常不值得。For循环或类似于for循环的方法受限于太过分明的层次,不够简洁与灵活,注意力成本高,易出错。GridSearchCV 称为网格搜索交叉验证调参,它通过遍历传入的参数的所有排列组合,通过交叉验证的方式,返回所有参数组合下的评价指标得分。

GridSearchCV听起来很高大上,其实就是暴力搜索。注意的是,该方法在小数据集上很有用,数据集大了就不太适用了。数据量比较大的时候可以使用一个快速调优的方法——坐标下降。它其实是一种贪心算法:拿当前对模型影响最大的参数调优,直到最优化;再拿下一个影响最大的参数调优,如此下去,直到所有的参数调整完毕。这个方法的缺点就是可能会调到局部最优而不是全局最优,但是省时间省力。

GridSearchCV使用说明

  1. class sklearn.model_selection.GridSearchCV(estimator, param_grid, scoring=None, n_jobs=None, refit=True, cv='warn', verbose=0, pre_dispatch='2*n_jobs', error_score='raise-deprecating', return_train_score='warn'

参数详解:

GridSearchCV对象

GridSearchCV方法

使用示例:

  1. from sklearn.model_selection import GridSearchCV 
  2. from sklearn.svm import SVR 
  3. from sklearn import datasets 
  4. dataset = datasets.load_iris() 
  5. X = dataset.data 
  6. y = dataset.target 
  7. grid = GridSearchCV( 
  8.     estimator=SVR(kernel='rbf'), 
  9.     param_grid={ 
  10.         'C': [0.1110100], 
  11.         'epsilon': [0.00010.0010.010.1110], 
  12.         'gamma': [0.0010.010.11
  13.     }, 
  14.     cv=5, scoring='neg_mean_squared_error', verbose=0, n_jobs=-1
  15. grid.fit(X, y) 
  16. print(grid.best_score_) 
  17. print(grid.best_params_) 

随机搜索 RandomizedSearchCV

我们在搜索超参数的时候,如果超参数个数较少(三四个或者更少),那么我们可以采用网格搜索,一种穷尽式的搜索方法。但是当超参数个数比较多的时候,我们仍然采用网格搜索,那么搜索所需时间将会指数级上升。所以有人就提出了随机搜索的方法,随机在超参数空间中搜索几十几百个点,其中就有可能有比较小的值。这种做法比上面稀疏化网格的做法快,而且实验证明,随机搜索法结果比稀疏网格法稍好。

RandomizedSearchCV使用方法和类GridSearchCV 很相似,但他不是尝试所有可能的组合,而是通过选择每一个超参数的一个随机值的特定数量的随机组合,这个方法有两个优点:

相比于整体参数空间,可以选择相对较少的参数组合数量。如果让随机搜索运行,它会探索每个超参数的不同的值 可以方便的通过设定搜索次数,控制超参数搜索的计算量。添加参数节点不会影响性能,不会降低效率。RandomizedSearchCV的使用方法其实是和GridSearchCV一致的,但它以随机在参数空间中采样的方式代替了GridSearchCV对于参数的网格搜索,在对于有连续变量的参数时,RandomizedSearchCV会将其当做一个分布进行采样进行这是网格搜索做不到的,它的搜索能力取决于设定的n_iter参数。

RandomizedSearchCV使用说明

  1. class sklearn.model_selection.RandomizedSearchCV(estimator, param_distributions, *, n_iter=10, scoring=None, n_jobs=None , refit=True, cv=None, verbose=0, pre_dispatch='2*n_jobs', random_state=None, error_score=nan, return_train_score=False) 

与GridSearchCV不同的主要有以下两参数:

自动超参数优化方法

贝叶斯优化方法(Bayesian Optimization)

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

贝叶斯优化与常规的网格搜索或者随机搜索的区别是:

让我们构造一个函数c(x)或者一个接收输入x的模型,如下图所示为c(x)的形状。当然,优化器并不知道该函数,称之为“目标函数”。

贝叶斯优化通过代理优化的方式来完成任务。代理函数通过采样点模拟构造(见下图)。

根据代理函数,我们大致可以确定哪些点是可能的最小值。然后再这些点附近做更多的采样,并随之更新代理函数。

每一次迭代,我们都会继续观察当前的代用函数,通过采样了解更多感兴趣的区域,并更新函数。需要注意的是,代用函数在数学上的表达方式将大大降低评估成本。经过一定的迭代次数后,我们注定要到达一个全局最小值,除非函数的形状非常诡异。

让我们仔细看看代用函数,通常用高斯过程来表示,它可以被认为是掷骰子,返回与给定数据点(如sin、log)拟合的函数,而不是1到6的数字。这个过程会返回几个函数,这些函数都附有概率。为什么用高斯过程,而不是其他的曲线拟合方法来模拟代用函数,有一个很好的理由:它是贝叶斯性质的。代用函数–表示为概率分布,即先验–被更新为 “获取函数”。这个函数负责在勘探和开发的权衡中提出新的测试点。

一个鼓励过多的开发和过少探索的获取函数将导致模型只停留在它首先发现的最小值(通常是局部的–“只去有光的地方”)。一个鼓励相反的获取函数将不会首先停留在一个最小值,本地或全球。在微妙的平衡中产生良好的结果。acquisition 函数,我们将其表示为a(x),必须同时考虑开发和探索。常见的获取函数包括预期改进和最大改进概率,所有这些函数都是在给定先验信息(高斯过程)的情况下,衡量特定投入在未来可能得到回报的概率。

让我们把这些东西整合起来。贝叶斯优化可以这样进行。

  1. 初始化一个高斯过程 “代用函数 “的先验分布。

  2. 选择几个数据点x,使在当前先验分布上运行的获取函数a(x)最大化。

  3. 评估目标成本函数c(x)中的数据点x,得到结果,y。

  4. 用新的数据更新高斯过程先验分布,以产生一个后验(它将成为下一步的先验)。

  5. 重复步骤2-5进行多次迭代。

  6. 解释当前的高斯过程分布(这是非常便宜的),以找到全局最小值。

贝叶斯优化就是把概率论的思想放在代入优化的思想后面。综上所述:

Hyperopt

Hyperopt是一个强大的Python库,用于超参数优化,由jamesbergstra开发。Hyperopt使用贝叶斯优化的形式进行参数调整,允许你为给定模型获得最佳参数。它可以在大范围内优化具有数百个参数的模型。

Hyperopt包含4个重要的特性

1、搜索空间

hyperopt有不同的函数来指定输入参数的范围,这些是随机搜索空间。选择最常用的搜索选项:

你可以使用的其他选项包括:

2、目标函数

这是一个最小化函数,它从搜索空间接收超参数值作为输入并返回损失。这意味着在优化过程中,我们使用选定的超参数值训练模型并预测目标特征,然后评估预测误差并将其返回给优化器。优化器将决定要检查哪些值并再次迭代。你将在一个实际例子中学习如何创建一个目标函数。

3、fmin

4、试验对象

Trials对象用于保存所有超参数、损失和其他信息,这意味着你可以在运行优化后访问它们。此外,trials 可以帮助你保存和加载重要信息,然后继续优化过程。

Hyperopt的使用

在理解了Hyperopt的重要特性之后,下面将介绍Hyperopt的使用方法。

  1. from sklearn import datasets 
  2. from hyperopt import fmin, tpe, hp, STATUS_OK, Trials 
  3. from sklearn.neighbors import KNeighborsClassifier 
  4. from sklearn.model_selection import cross_val_score 
  5. iris = datasets.load_iris() 
  6. X = iris.data 
  7. y = iris.target 
  8. def hyperopt_train_test(params): 
  9.     clf = KNeighborsClassifier(**params) 
  10.     return cross_val_score(clf, X, y).mean() 
  11. # 定义参数空间 
  12. space_knn = { 
  13.     'n_neighbors': hp.choice('n_neighbors', range(1100)) 
  14. # 定义最小化函数(目标函数) 
  15. def fn_knn(params): 
  16.     acc = hyperopt_train_test(params) 
  17.     return {'loss': -acc, 'status': STATUS_OK}  # hyperopt最小化函数,所以在acc中添加了负号 
  18. # 实例化Trial 对象,对模型进行微调,然后用其超参数值打印出最佳损失 
  19. trials = Trials() 
  20. best = fmin(fn_knn, space_knn, algo=tpe.suggest, max_evals=100, trials=trials) 
  21. print("Best: {}".format(best)) 
  22. print(trials.results)  # 搜索期间“objective”返回的词典列表。 

algo指定搜索算法,目前支持以下算法:

除了Hyperopt外,贝叶斯优化方法的Python包还有:

遗传算法(Genetic Algorithms)

遗传算法试图将自然选择机制应用于机器学习环境。它受到达尔文自然选择过程的启发,因此通常也称为进化算法。假设我们创建了具有一些预定义超参数的N个机器学习模型。然后,我们可以计算每个模型的准确性,并决定只保留一半模型(性能最好的模型)。现在,我们可以生成具有与最佳模型相似的超参数的后代,以便再次获得N个模型的种群。在这一点上,我们可以再次计算每个模型的准确性,并在定义的世代中重复该循环。这样,只有最佳模型才能在流程结束时生存下来。

TPOT是一种基于遗传算法优化机器学习管道(pipeline)的Python自动机器学习工具。简单来说,就是TPOT可以智能地探索数千个可能的pipeline,为数据集找到最好的pipeline,从而实现机器学习中最乏味的部分。

 

更重要地是,一旦TPOT完成搜索,TPOT同时也提供了Python代码。通过这个代码,我们可以具体地知道TPOT获得最优性能时的具体pipeline的内容,这对于后续修改是十分方便的!

TPOT是在sklearn的基础之上做的封装库。其主要封装了sklearn的模型相关模块、processesing模块和feature_selection模块,所以TPOT的主要功能是集中在使用pipeline的方式完成模型的数据预处理、特征选择和模型选择方面。此外,我们还发现了TPOT已经对xgboost进行了支持。

虽然TPOT使用遗传算法代替了传统的网格搜索进行超参数选择,但由于默认初始值的随机性,在少量的进化(迭代)次数下,TPOT最终选择的模型往往并不相同。

计算效率问题。作者在代码中写道:进化(迭代)次数和每一代保留的个体数量值越多,最终得模型得分会越高。但这同样也会导致耗时很长。如果使用相当复杂的数据集或运行TPOT短时间,不同的TPOT运行可能会导致不同的流水线推荐。TPOT的优化算法本质上是随机的,这意味着它使用随机性(部分地)来搜索可能的流水线空间。当两个TPOT运行推荐不同的管道时,这意味着TPOT运行由于时间不够而不收敛,或者多个管道在数据集上执行的次数大致相同。这实际上是一个优于固定网格搜索技术的优点:TPOT是一个助手,它通过探索您可能从未考虑过的流水线配置来提供解决如何解决特定机器学习问题的想法,然后将微调留给更受约束的参数调整技术,例如网格搜索。

使用TPOT(版本0.9.5)开发模型需要把握以下几点:

示例代码:

  1. from tpot import TPOTClassifier 
  2. from sklearn.datasets import load_iris 
  3. from sklearn.model_selection import train_test_split 
  4. iris = load_iris() 
  5. X = iris.data 
  6. y = iris.target 
  7. X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2
  8. tpot = TPOTClassifier(generations=5, population_size=50, verbosity=2, n_jobs=-1
  9. tpot.fit(X_train, y_train) 
  10. print(tpot.score(X_test, y_test)) 

TPOT的主要参数:

使用这个迭代过程,我们选出最佳配置。准备遗传算法的结果一般取决于初始状态。因此,它随机产生的初始种群影响输出,重新运行相同的设置可能会输出不同的结果。

 

来源:Coggle数据科学内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯