机器学习—模型超参数调优之网格搜索与随机搜索

引言

  不同的超参数的值对于模型的性能有不同的影响,我们需要找到的就是使得模型性能最佳的超参数。

1.网格搜索GridSearchCV()

  网格搜索的思想非常简单,比如你有2个超参数需要去选择,那你就把所有的超参数选择列出来分别做排列组合。举个例子: 𝜆=0.01,0.1,1.0 和 𝛼=0.01,0.1,1.0 ,你可以做一个排列组合,即:{[0.01,0.01],[0.01,0.1],[0.01,1],[0.1,0.01],[0.1,0.1],[0.1,1.0],[1,0.01],[1,0.1],[1,1]} ,然后针对每组超参数分别建立一个模型,然后选择测试误差最小的那组超参数。换句话说,我们需要从超参数空间中寻找最优的超参数,很像一个网格中找到一个最优的节点,因此叫网格搜索

import numpy as np
from sklearn.svm import SVR  # 引入SVR类
from sklearn.pipeline import make_pipeline  # 引入管道简化学习流程
from sklearn.preprocessing import StandardScaler  # 由于SVR基于距离计算,引入对数据进行标准化的类
from sklearn.model_selection import GridSearchCV  # 引入网格搜索调优
from sklearn.model_selection import cross_val_score  # 引入K折交叉验证
from sklearn import datasets

boston = datasets.load_boston()  # 返回一个类似于字典的类
X = boston.data
y = boston.target
features = boston.feature_names
pipe_SVR = make_pipeline(StandardScaler(),
                         SVR())
score1 = cross_val_score(estimator=pipe_SVR,
                         X=X,
                         y=y,
                         scoring='r2',
                         cv=10)  # 10折交叉验证
print("CV accuracy: %.3f +/- %.3f" % ((np.mean(score1)), np.std(score1)))
from sklearn.svm import SVR  # 引入SVR类
from sklearn.pipeline import make_pipeline, Pipeline  # 引入管道简化学习流程
from sklearn.preprocessing import StandardScaler  # 由于SVR基于距离计算,引入对数据进行标准化的类
from sklearn.model_selection import GridSearchCV  # 引入网格搜索调优
from sklearn.model_selection import cross_val_score  # 引入K折交叉验证
from sklearn import datasets

boston = datasets.load_boston()  # 返回一个类似于字典的类
X = boston.data
y = boston.target
features = boston.feature_names
pipe_svr = Pipeline([("StandardScaler", StandardScaler()),
                     ("svr", SVR())])
param_range = [0.0001, 0.001, 0.01, 0.1, 1.0, 10.0, 100.0, 1000.0]
# 管道与网格搜索结合
param_grid = [{"svr__C": param_range, "svr__kernel": ["linear"]},  # 注意__是指两个下划线,一个下划线会报错的
              {"svr__C": param_range, "svr__gamma": param_range, "svr__kernel": ["rbf"]}]
gs = GridSearchCV(estimator=pipe_svr,
                  param_grid=param_grid,
                  scoring='r2',
                  cv=10)  # 10折交叉验证
gs = gs.fit(X, y)
print("网格搜索最优得分:", gs.best_score_)
print("网格搜索最优参数组合:\n", gs.best_params_)
网格搜索最优得分: 0.6081303070817127
网格搜索最优参数组合:
 {'svr__C': 1000.0, 'svr__gamma': 0.001, 'svr__kernel': 'rbf'}

2.随机搜索GridSearchCV()

  网格搜索相当于暴力地从参数空间中每个都尝试一遍,然后选择最优的那组参数,这样的方法显然是不够高效的,因为随着参数类别个数的增加,需要尝试的次数呈指数级增长。有没有一种更加高效的调优方式呢?那就是使用随机搜索的方式,这种方式不仅仅高校,而且实验证明,随机搜索法结果比稀疏化网格法稍好(有时候也会极差,需要权衡)。参数的随机搜索中的每个参数都是从可能的参数值的分布中采样的。与网格搜索相比,这有两个主要优点:

  • 可以独立于参数数量和可能的值来选择计算成本。

  • 添加不影响性能的参数不会降低效率。

from sklearn.svm import SVR  # 引入SVR类
from sklearn.pipeline import make_pipeline, Pipeline  # 引入管道简化学习流程
from sklearn.preprocessing import StandardScaler  # 由于SVR基于距离计算,引入对数据进行标准化的类
from sklearn import datasets
from sklearn.model_selection import RandomizedSearchCV
from scipy.stats import uniform  # 引入均匀分布设置参数

boston = datasets.load_boston()  # 返回一个类似于字典的类
X = boston.data
y = boston.target
features = boston.feature_names

pipe_svr = Pipeline([("StandardScaler", StandardScaler()),
                     ("svr", SVR())])
# 利用参数loc和scale,可以得到[loc, loc + scale]上的均匀分布,在uniform中loc是最小值,scale是最大值。
distributions = dict(svr__C=uniform(loc=1.0, scale=4),  # 构建连续参数的分布
                     svr__kernel=["linear", "rbf"],  # 离散参数的集合
                     svr__gamma=uniform(loc=0, scale=4))

rs = RandomizedSearchCV(estimator=pipe_svr,
                        param_distributions=distributions,
                        scoring='r2',
                        cv=10)  # 10折交叉验证
rs = rs.fit(X, y)
print("随机搜索最优得分:", rs.best_score_)
print("随机搜索最优参数组合:\n", rs.best_params_)
随机搜索最优得分: 0.2988221516140073
随机搜索最优参数组合:
 {'svr__C': 4.503224088282858, 'svr__gamma': 3.1457760882766905, 'svr__kernel': 'linear'}

3.总结

  数据量小使用网格搜索,当时间代价比较大时,可以多次使用随机搜索。
参考:
机器学习基础


如果对您有帮助,麻烦点赞关注,这真的对我很重要!!!如果需要互关,请评论留言!
在这里插入图片描述


  • 15
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值