栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Python机器学习——机器学习模型超参数优化HPO(上)——用网格搜索,随机搜索优化SVM

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Python机器学习——机器学习模型超参数优化HPO(上)——用网格搜索,随机搜索优化SVM

| 图源

机器学习模型的参数,分为可学习参数(以下直接称为参数,Parameter,P)和超参数(Hyper Parameter, HP)。参数是输入空间到输出空间映射的微观实现者,而超参数是模型结构,模型复杂度和正则化程度等的宏观调控者。研究表明,与使用默认超参数相比,根据数据进行超参数优化(Hyper Parameter Optimize,HPO)之后,模型表现往往会有提升。在参数空间的目标函数往往是可微甚至是凸的,如参数空间的MSE,交叉熵,KL散度等,所以可以直接通过传统的优化方法,如坐标下降法,梯度法或牛顿法等,搜索到使目标函数取得局部最优或者全局最优值时的参数值组合。而在超参数空间,超参数常常是离散的,跳变的,它对应的目标函数往往就不可微,非凸,如超参数空间的准确率,MSE,MAE等,这时传统的优化方法往往起不了作用,就需要新的空间搜索方法或者新的优化方法,以搜索到使目标函数取得局部最优或者全局最优值时的超参数值组合。

超参数分为连续超参数(如岭回归的惩罚系数alpha),离散超参数(如随机森林的决策树颗数)和分类超参数(如SVM的kernel)等。最简单,暴力的超参数优化方法当属网格搜索(Grid Search,GS),其次是随机搜索(Random Search,RS),它们都不考虑之前搜索到的超参数组合的好坏,搜索之间相互独立,这会浪费大量时间来搜索超参数空间中表现不佳的区域,不过也正是因为独立,使得这两种方法都可以并行处理。贝叶斯优化(Bayesian optimization,BO)搜索,则是根据先前获得的搜索结果,来确定未来的超参数取值组合,同时考虑最可能出现最佳超参数的区域,和未曾搜索的区域,使得搜索可能更加精确和有效,不过也是因为前后的关联性,使得基于BO的方法难以并行化。元启发式搜索算法中遗传算法(GA),和粒子群算法(PSO)经常被用来做HPO,这种基于种群的搜索算法,可以在考虑之前搜索结果的同时可以进行并行化处理。

每种HPO方法都有其优缺点和适用情形,这次的博客主要是根据2020年Neurocomputing(神经计算)上的一篇综述性文章:On hyperparameter optimization of machine learning algorithms:Theory and practice(关于机器学习算法的超参数优化:理论与实践)来系统的梳理和学习常用的机器学习超参数优化方法,共分为上中下三篇:

Python机器学习——机器学习模型超参数优化HPO(上)——用网格搜索,随机搜索调整SVM超参数
Python机器学习——机器学习模型超参数优化HPO(中)——贝叶斯优化搜索
Python机器学习——机器学习模型超参数优化HPO(下)——元启发式搜索

copyright © 意疏:https://blog.csdn.net/sinat_35907936/article/details/120917366


模型、数据与评估方式
1、模型

关于机器学习算法的超参数优化:理论与实践论文中比较了KNN,随机森林和SVM等常用分类回归模型,由于本博客目的是学习,而不是验证,故只选用了支持向量机(SVM)。SVM在误判松弛约束下最大化分类间隔来实现分类或者在平滑约束下最小化预测误差来实现回归,在麦瑟定理下,通过核方法,它可以把特征映射到高维甚至无穷维空间,以求获得其线性模型的假设下更好的性能。它的超参数包括连续超参数:惩罚系数C和某些核函数参数——如RBF核的gamma,离散超参数——如ploy核的degree,和类别超参数:核类型,如linear和rbf等。具体参数类型与取值区间如下表所示。

modelHyper ParameterTypeSpace
SVCCcontinuous>0
gammacontinuous>0
coef0continuousR
kernelcategorical{‘linear’, ‘poly’, ‘rbf’, ‘sigmoid’}
degreeDiscrete>1

注:关于核方法的参数如下,图源。degree是多项式核的次数,如果小于等于1,就和线性核没有什么区别了,所以表中写的大于1.

2、数据

关于机器学习算法的超参数优化:理论与实践论文中采用了手写数字(Mnist)数据集来作为分类评估数据集,用波士顿房价数据集来作为回归的评估数据集,它们都可以通过scikit-learn的datasets接口获取。同样,本博客只使用手写数字数据集来做分类,scikit-learn提供的接口中包含1797张8x8的图像。

# -*- coding: utf-8 -*-

from sklearn import datasets

digits = datasets.load_digits()
data, target = digits['data'], digits['target']
print(data.shape, target.shape)
(1797, 64) (1797,)
3、评估

超参数组合好坏的评估采用与文章相同的方式,即准确率,并且以三次交叉验证的平均结果作为评估结果,并记录超参数搜索时间。代码参考。生成超参数组合并不耗时,费时的是在该超参数组合下训练模型,并得到评估结果,并且越复杂的模型评估的时间越长。


网格搜索(Grid Search,GS)
1、简介

网格搜索(Grid Search,GS)应该是最简单,最直接,也是最常用的超参数优化(HPO)方法。通过在每种超参数的取值范围上,分别进行简单采样来获得数量较少的离散超参数取值,然后对采样后的每种超参数取值进行组合,即笛卡尔积,其中每一种组合都是笛卡尔坐标系网格中的一个点,因此它被称作网格搜索。最后对所有组合进行独立进行评估,以找出最好的超参数取值组合,此步骤可并行处理。

优点:①实现简单,遍历所有超参数组合就够了。②理解容易。③可以高度并行,如果核足够多,一次就得到全部搜索结果。
缺点:①时间复杂度为O(n^k),其中n为超参数取值个数,k为超参数种类,当超参数取样间隔很小,且超参数种类很多时,会出现 维度灾难。②采样间隔和采样区间都需要手动设置,这需要先验经验或者反复实验,容易错过最优组合。③它对每个超参数取值组合都一视同仁,独立评估,这可能会使得大量时间被花费在不太好的参数组合评估上。

2、实现

离散超参数可以取值采样,以减少取值数量,类别型超参数,也可以根据需要只取其中几个。网格搜索(Grid Search,GS)基本策略是,先大间隔进行大范围的搜索,然后再对表现好的区域,用小间隔进行小范围搜索。

from sklearn.svm import SVC
from sklearn import datasets
from sklearn.model_selection import GridSearchCV, KFold, cross_val_score
import numpy as np

digits = datasets.load_digits()
data, target = digits['data'], digits['target']


# 求默认gamma
n_features = data.shape[1]
var_data = data.var()
gamma = 1/(n_features*var_data)

kf = KFold(n_splits=3, shuffle=False)

svm_model = SVC()
scores = cross_val_score(svm_model, data, target,cv=kf, scoring='accuracy')
print('default accuracy', scores.mean())

# 粗调

svm_params = [
  {'C': [0.01, 0.1, 1, 10, 100], 'kernel': ['linear']},
  {'C': [0.01, 0.1, 1, 10, 100], 'gamma': [0.1*gamma, 0.5*gamma, gamma, 5*gamma, 10*gamma], 'kernel': ['rbf']},
  {'C': [0.01, 0.1, 1, 10, 100], 'degree': [2, 3, 4, 5, 6], 'kernel': ['poly']},
  {'C': [0.01, 0.1, 1, 10, 100], 'coef0': [-10, -5, 0, 5, 10], 'kernel': ['sigmoid']}
 ]


gs = GridSearchCV(estimator=svm_model, param_grid=svm_params, cv=kf)
gs.fit(data, target)

search_num = {}
for svm_param in svm_params:
    n = 1
    for key in svm_param.keys():
        n *= len(svm_param[key])
    search_num[svm_param['kernel'][0]]=n
print(search_num)

print(gs.cv_results_)
print(gs.best_params_)
未完待续

为了在1024程序猿节结束之前发出来,剩下的就接下来的几天再补全吧。请继续关注。


随机搜索(Random Search,RS)
1、简介

图源

2、实现
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/348200.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号