调参系列1
1 什么叫调参?2 为什么要调参3 调参方法有哪些?3.1 网格搜索3.1.1 原理3.1.2 Python实现
3.2 随机搜索3.2.1 原理3.2.2 Python实现
3.3 贝叶斯调参3.3.1 区别于前两种方法的点3.3.2 原理3.3.3 Python实现
4 参考
1 什么叫调参?
调参即对模型的参数进行相应的调整,以期获得更好的预测效果!
其中参数又分为:模型参数和模型超参数。
模型参数:模型内部的配置变量,可以用数据估计模型参数的值。比如线性回归或逻辑回归中的系数。模型超参数:模型外部的配置,必须手动设置参数的值,其值不能从数据估计得到。比如K近邻分析的K,学习率learning_rate
即:
模型参数是从数据中自动估计的,而模型超参数是手动设置的,并用于估计模型参数的过程。模型调参 调整的是模型超参数
2 为什么要调参
调参调参,无非就是将模型的超参数调整到最佳的参数,使得模型预测的效果最好。
3 调参方法有哪些?
总的来说,调参方式有下面三种:
网格搜索。对应sklearn中的GridSearchCV随机搜索。对应sklearn中的RandomizedSearchCV贝叶斯调参。见上面两个链接。
3.1 网格搜索
3.1.1 原理
GridSearchCV的名字其实可以拆分为两部分,GridSearch和CV,即网格搜索和交叉验证。网格搜索,搜索的是参数,即在指定的参数范围内,从所有的参数中找到在测试集上精度最高的参数,这其实是一个循环和比较的过程。每一个参数组合下均使用交叉验证来评估模型预测的效果
优点:
简单,保证在指定的参数范围内找到精度最高的参数
缺点:
耗时。要求遍历所有可能参数的组合,在面对大数据集和多参数的情况下,非常耗时。同时每种参数组合下均使用交叉验证也要求大量的计算资源,加重了网格搜索的搜索时间。
3.1.2 Python实现
展示之前博客内容 机器学习 | 集成学习 中的调参内容
步骤:
设置参数。设置要调参的参数搭建模型。搭建框架。网格调参框架搭建拟合模型查看结果。比如最佳学习器,最佳参数等等。
# 导入相应的库
from sklearn.model_selection import GridSearchCV
# 设置要调参的参数
param_test1 = {'n_estimators':range(80,300,20),
'learning_rate': [0.1, 0.2, 0.3]} # 即[10, 20, 30, 40, 50, 60, 70]
# 搭建模型
estimator = GradientBoostingClassifier(
min_samples_split=300,
min_samples_leaf=20,
max_depth=8,
max_features='sqrt',
subsample=0.8, # 子采样
random_state=23
)
# 网格调参框架搭建
gsearch1 = GridSearchCV(estimator = estimator, # 预测器
param_grid = param_test1, # 参数
scoring='roc_auc', # 评价准则
cv=5 ) # 交叉验证次数
# 拟合模型 开始漫漫调参路 针对训练集
gsearch1.fit(X_train, y_train)
# 查看调参结果
gsearch1.best_params_, gsearch1.best_score_, gsearch1.best_estimator_
3.2 随机搜索
3.2.1 原理
使用方法和网格调参一样不同点:随机在参数空间中以采样的方式代替了GridSearchCV对于参数的网格搜索,在对于有连续变量的参数时,随机搜索(RandomizedSearchCV)会将其当作一个分布进行采样,这是网格搜索做不到的
步骤:
对于搜索范围是distribution的超参数,根据给定的distribution随机采样;对于搜索范围是list的超参数,在给定的list中等概率采样;对a、b两步中得到的n_iter组采样结果,进行遍历。并从中找到最优的一组参数。
为什么随机搜索能够起到作用?有一个形象的例子: 比如上面两个图:
目标函数:f(x,y)=g(x)+h(y),其中绿色为g(x),黄色为h(y),目的是求f的最大值。由于g(x)数值上要明显大于h(y),因此有f(x,y)=g(x)+h(y)≈g(x),也就是说在整体求解f(x,y)最大值的过程中,g(x)的影响明显大于h(y)。所以可以只看绿色的g(x)可以看到左边的9个搜索中真正起到作用的只有3个,而右边有9个!即对于f最大值的寻找有帮助的点!可以看出右图更可能找到目标函数的最大值。
因此引入随机因素在某些情况下可以提高寻优效率。
3.2.2 Python实现
# 导入相应的库
from sklearn.grid_search import RandomizedSearchCV
# 设置要调参的参数
param_test1 = {'n_estimators':range(80,300,20),
"max_features": sp_randint(1, 11), #给定distribution 区别于网格搜索的
"min_samples_split": sp_randint(2, 11), #给定distribution
'learning_rate': [0.1, 0.2, 0.3]} # 即[10, 20, 30, 40, 50, 60, 70]
# 搭建模型
estimator = GradientBoostingClassifier(
min_samples_leaf=20,
max_depth=8,
subsample=0.8, # 子采样
random_state=23
)
# 网格调参框架搭建
gsearch1 = RandomizedSearchCV(estimator, # 预测器
param_test1, # 参数
scoring='roc_auc', # 评价准则
cv=5, # 交叉验证次数
n_iter=300) # 训练300次,数值越大,获得的参数精度越大,但是搜索时间越长
# 拟合模型 开始漫漫调参路 针对训练集
gsearch1.fit(X_train, y_train)
# 查看调参结果 最优训练器的精度(best_score_)
gsearch1.best_params_, gsearch1.best_score_, gsearch1.best_estimator_
3.3 贝叶斯调参
3.3.1 区别于前两种方法的点
网格搜索和随机搜索在测试一个新的点时,会忽略前一个点的信息。贝叶斯优化会考虑前一个点的信息。贝叶斯优化的工作方式:通过对目标函数形状的学习,找到使结果向全局最大值提升的参数。学习目标函数形状的方法:根据先验分布,假设一个搜集函数。在每一次使用新的采样点来测试目标函数时,它使用这个信息来更新目标函数的先验分布。然后,算法测试由后验分布给出的,全局最值最可能出现的位置的点。
存在的问题:
一旦找到了一个局部最大值或最小值,它会在这个区域不断采样,所以很容易陷入局部最值
解决方案:
勘探:在还未取样的区域获取采样点
开采:根据后验分布,在最可能出现全局最值的区域进行采样。
3.3.2 原理
利用用户假设的目标函数的先验概率与目前已知数据构建目标函数的概率模型,并由推断下一步最优参数组合, 进而更新概率模型.
3.3.3 Python实现
以上两部分比较复杂,内容较多,单独开一篇博客!借鉴ZR的相关内容!code和原理已经准备好了,加油!
4 参考
https://blog.csdn.net/csdn_elsa/article/details/82494153https://blog.csdn.net/juezhanangle/article/details/80051256https://blog.csdn.net/qq_27782503/article/details/89323456https://blog.csdn.net/qq_36810398/article/details/86699842https://blog.csdn.net/gzj533/article/details/77734310网格调参官方文档:https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.GridSearchCV.html随机调参官方文档:https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.RandomizedSearchCV.html