对模型超参数进行调优:
No | 参数 | 超参数 |
---|---|---|
1 | 模型本身的一部分,参与定义了模型 | 用来帮助估计,调试参数 |
2 | 通过样本数据推算估计得出 | 通常在人工选定,在训练模型之前就已经分配好 |
-
网格搜索GridSearchCV():
- scikit-learn-api:网格搜索
- 方法:将备选的参数全都排列组合,然后遍历全部参数,找出模型误差最小的那个组合
- 缺点:因为遍历全部排列组合,耗时会很长,备选参数越多耗时越长,在选定参数钱最好先确定一个范围
- scikit-learn-api:网格搜索结合管道
- 大多数机器学习应用不仅需要应用单个算法,而且还需要将许多不同的处理步骤和机器学习模型链接在一起,例如对数据进行缩放,然后手动合并特征,再利用无监督学习来学习特征。为了简化构建变换和模型链的过程,Scikit-Learn提供了pipeline类,可以将多个处理步骤合并为单个Scikit-Learn估计器。
- pipeline类本身具有fit、predict和score方法,其行为与Scikit-Learn中的其他模型相同。
- scikit-learn-api:网格搜索
-
随机搜索 RandomizedSearchCV() :
- scikit-learn-api:随机搜索
- 方法:每个参数都是从可能的参数值的分布中采样的
- 优点:
- 效果有时比稀疏网格法好,有时比稀疏网格法差(权衡使用)
- 可以独立于参数数量和可能的值来选择计算成本。
- 添加不影响性能的参数不会降低效率。
- scikit-learn-api:随机搜索
代码实现:糖尿病数据集数据介绍
- 我们先来对未调参的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
import pandas as pd
import numpy as np
diabetes = datasets.load_boston() # 返回一个类似于字典的类
X = diabetes.data
y = diabetes.target
features = diabetes.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.151 +/- 0.040
- 下面我们使用网格搜索来对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.4639171327773603
随机搜索最优参数组合:
{'svr__C': 1.270166536102996, 'svr__gamma': 1.4682590674492535, 'svr__kernel': 'linear'}
param_range = [0.0001,0.01,1.0,10.0,20,30]
-
修改备选参数后,选择合适的备选参数也很重要
网格搜索最优得分: 0.4669447951823411 网格搜索最优参数组合: {'svr__C': 30, 'svr__gamma': 0.01, '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.4645801684017908
随机搜索最优参数组合:
{'svr__C': 1.018317247447654, 'svr__gamma': 3.421387159903711, 'svr__kernel': 'linear'}