模型调参之网格搜索与随机搜索
网格搜索法(GridSearchCV)
- GridSearchCV:GridSearchCV可以拆分成GridSearch和CV两部分,即网格搜素和交叉验证。GridSearch系统地遍历多种参数组合,通过交叉验证确定最佳效果参数。网格搜索是对参数进行搜索,在指定的参数范围内,按步长依次调整参数,利用调整的参
在这里插入代码片
数训练学习器,从所有的参数中找到在验证集上精度最高的参数,这也是一个训练和比较的过程。交叉验证根据cv参数的设置,设置为k折交叉验证,默认为5折。
- Grid Search:网格搜素是一种调参手段,采用的是穷举搜索的方式,即在所有候选的参数选择中,通过循环遍历,尝试每一种可能性,表现最好的参数就是最终的结果。其原理类似于在数组中找最大值。
- 适用情况:网格搜索法适用于三四个(或者更少)的超参数。
- 缺点:对于大数据集和多参数的情况,计算代价非常非常大,面临维度灾难。
- 参数说明:
class sklearn.model_selection.GridSearchCV(estimator, param_grid, *, scoring=None, n_jobs=None, refit=True, cv=None, verbose=0, pre_dispatch='2*n_jobs', error_score=nan, return_train_score=False)
- estimator:选择使用的分类器,并且传入除需要确定最佳的参数之外的其他参数。
- param_grid:需要最优化的参数取值,值为字典或者列表。
- scoring=None:模型评价标准,默认None;根据所选模型不同,评价准则不同。比如scoring=”accuracy”或者scoring='roc_auc’等。如果是None,则使用estimator的误差估计函数。
- n_jobs:进程个数,默认为1。 若值为 -1,则用所有的CPU进行运算。 若值为1,则不进行并行运算,这样的话方便调试。
- refit=True:默认为True,程序将会以交叉验证训练集得到的最佳参数,重新对所有可用的训练集与开发集进行,作为最终用于性能评估的最佳模型参数。即在搜索参数结束后,用最佳参数结果再次fit一遍全部数据集。如果scoring参数有多个值,refit必须指定其中一种评价指标。
- cv=None:交叉验证参数,默认None,使用五折交叉验证。
- verbose=0:verbose:日志冗长度,0:不输出训练过程,1:偶尔输出,>1:对每个子模型都输出。
- pre_dispatch=‘2*n_jobs’:指定总共分发的并行任务数。当n_jobs大于1时,数据将在每个运行点进行复制,这可能导致OOM,而设置pre_dispatch参数,则可以预先划分总共的job数量,使数据最多被复制pre_dispatch次
- return_train_score=False:默认为FALSE,cv_results_属性将不包括训练分数。也可设置为‘warn’
- 示例:
from sklearn.model_selection import GridSearchCV
from sklearn.datasets import load_iris
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split
#把要调整的参数以及其候选值 列出来;
param_grid = {"gamma":[0.001,0.01,0.1,1,10,100],
"C":[0.001,0.01,0.1,1,10,100]}
print("Parameters:{}".format(param_grid))
grid_search = GridSearchCV(SVC(),param_grid,cv=5) #实例化一个GridSearchCV类
X_train,X_test,y_train,y_test = train_test_split(iris.data,iris.target,random_state=10)
grid_search.fit(X_train,y_train) #训练,找到最优的参数,同时使用最优的参数实例化一个新的SVC estimator。
print("Test set score:{:.2f}".format(grid_search.score(X_test,y_test)))
print("Best parameters:{}".format(grid_search.best_params_))
print("Best score on train set:{:.2f}".format(grid_search.best_score_))
随机搜索(RandomizedSearchCV)
- 原理:随机搜索并未尝试所有参数值,而是从指定的分布中采样固定数量的参数设置。它的理论依据是,如果随机样本点集足够大,那么也可以找到全局的最大或最小值,或它们的近似值。通过对搜索范围的随机取样,随机搜索一般会比网格搜索要快一些。但是和网格搜索的快速版(非自动版)相似,结果也是没法保证的。
- RandomizedSearchCV的使用方法其实是和GridSearchCV一致的,但它以随机在参数空间中采样的方式代替了GridSearchCV对于参数的网格搜索,在对于有连续变量的参数时,RandomizedSearchCV会将其当做一个分布进行采样进行这是网格搜索做不到的,它的搜索能力取决于设定的n_iter参数。
- RandomSearchCV的搜索策略如下:
- 对于搜索范围是distribution的超参数,根据给定的distribution随机采样;
- 对于搜索范围是list的超参数,在给定的list中等概率采样;
- 对a、b两步中得到的n_iter组采样结果,进行遍历。
- 如果给定的搜索范围均为list,则不放回抽样n_iter次。
- 适用情况:
- 数据规模大,精确的结果难以在一定时间计算出。
- 结果的些许的不精确能够被接受。
- 求取的结果是最优化(optimization)问题,有一个成本计算模型
- 参数说明:
class sklearn.model_selection.RandomizedSearchCV(estimator, param_distributions, *, n_iter=10, scoring=None, n_jobs=None, refit=True, cv=None, verbose=0, pre_dispatch='2*n_jobs', random_state=None, error_score=nan, return_train_score=False)
参数和GridSearchCV类似。
- 示例:
from sklearn.datasets import load_iris
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import RandomizedSearchCV
from scipy.stats import uniform
iris = load_iris()
logistic = LogisticRegression(solver='saga', tol=1e-2, max_iter=200,
... random_state=0)
distributions = dict(C=uniform(loc=0, scale=4),
... penalty=['l2', 'l1'])
clf = RandomizedSearchCV(logistic, distributions, random_state=0)
search = clf.fit(iris.data, iris.target)
search.best_params_
{'C': 2..., 'penalty': 'l1'}
随机搜索和网格搜索对比
- 相较于网格搜索,随机搜索的速度更快,精度稍微提升或降。
- 当超参数的搜索空间很大时,更推荐使用RandomizedSearchCV。
- 使用随机搜索方法的难点在于确定参数的分布范围,这需要对所使用的模型有足够的了解。
使用多种评估指标
- cross_validate
from sklearn.model_selection import cross_validate
from sklearn.metrics import recall_score
scoring = ['precision_macro', 'recall_macro']
clf = svm.SVC(kernel='linear', C=1, random_state=0)
scores = cross_validate(clf, iris.data, iris.target, scoring=scoring)
sorted(scores.keys())
- 在网格搜索中使用多种评估指标
scoring = {'AUC': 'roc_auc', 'Accuracy': make_scorer(accuracy_score)}
# Setting refit='AUC', refits an estimator on the whole dataset with the
# parameter setting that has the best cross-validated AUC score.
gs = GridSearchCV(DecisionTreeClassifier(random_state=42),
param_grid={'min_samples_split': range(2, 403, 10)},
scoring=scoring, refit='AUC', return_train_score=True)
gs.fit(X, y)
results = gs.cv_results_