Datawhale第23期组队学习—集成学习—task4—掌握回归模型的评估及超参数调优

参数与超参数

参考来源:https://github.com/datawhalechina/team-learning-data-mining/tree/master/EnsembleLearning/CH2-%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%E5%9F%BA%E7%A1%80%E6%A8%A1%E5%9E%8B%E5%9B%9E%E9%A1%BE

模型参数

模型参数是模型内部的配置变量,其值可以根据数据进行估计。

  • 它们的值定义了可使用的模型
  • 模型在进行预测时需要它们。
  • 它们是从数据估计或获悉的。
  • 它们通常不由编程者手动设置。
  • 它们通常被保存为学习模型的一部分。
  • 参数是机器学习算法的关键。它们通常由过去的训练数据中总结得出。

超参数

  • 它们通常用于帮助估计模型参数。
  • 它们通常由人工指定。
  • 它们通常可以使用启发式设置。
  • 它们经常被调整为给定的预测建模问题

由于超参数不能根据模型计算得出,找到最佳超参数的问题本质上属于最优化的内容,因为从一个参数集合中找到最佳的值本身就是最优化的任务之一。

寻找最佳超参数有两种常用方法:网格搜索和随即搜索:

网格搜索
网格搜索的思想非常简单,比如你有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]} ,然后针对每组超参数分别建立一个模型,然后选择测试误差最小的那组超参数。换句话说,我们需要从超参数空间中寻找最优的超参数,很像一个网格中找到一个最优的节点,因此叫网格搜索。

随机搜索
网格搜索的思想相当于遍历每一种可能性,计算每一种结果最终得到最优解。这样的方法是相当暴力的,当超参数增加时,遍历的次数成指数型增长,很明显不满足算法对于高效性的要求。
加拿大蒙特利尔大学的两位学者Bergstra和Bengio在他们2012年发表的文章【1】中,表明随机搜索比网格搜索更高效。如下图所示,在搜索次数相同时,随机搜索相对于网格搜索会尝试更多的参数值【2】
在这里插入图片描述
通过sklearn里的测试代码可以得到:
在这里插入图片描述
可以发现,随机搜索在牺牲了一些预测准确性后,搜索时间将近减少了10倍。与网格搜索相比,这有两个主要优点:

  • 可以独立于参数数量和可能的值来选择计算成本。
  • 添加不影响性能的参数不会降低效率。

使用SVR的例子,结合管道来进行调优:

# 对未调参的SVR进行评价: 
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)))

运行结果

CV accuracy: 0.187 +/- 0.649

使用网格搜索调优

# 下面我们使用网格搜索来对SVR调参:
from sklearn.pipeline import Pipeline
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.6081303070817233
网格搜索最优参数组合:
{‘svr__C’: 1000.0, ‘svr__gamma’: 0.001, ‘svr__kernel’: ‘rbf’}

使用随机搜索调优

下面我们使用随机搜索来对SVR调参:
from sklearn.model_selection import RandomizedSearchCV
from scipy.stats import uniform  # 引入均匀分布设置参数
pipe_svr = Pipeline([("StandardScaler",StandardScaler()),
                                                         ("svr",SVR())])
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.30021249798866756
随机搜索最优参数组合:
{‘svr__C’: 1.4195029566223933, ‘svr__gamma’: 1.8683733769303625, ‘svr__kernel’: ‘linear’}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值