在机器学习模型中,需要人工选择的参数称为超参数。比如随机森林中决策树的个数,人工神经网络模型中隐藏层层数和每层的节点个数,正则项中常数大小等等,他们都需要事先指定。超参数选择不恰当,就会出现欠拟合或者过拟合的问题。而在选择超参数的时候,有两个途径,一个是凭经验微调,另一个就是选择不同大小的参数,带入模型中,挑选表现最好的参数。 Scikit-Learn的GridSearchCV就能帮你找到一组很好的超参数组合。

1、介绍

  GridSearchCV的名字其实可以拆分为两部分,GridSearch和CV,即网格搜索和交叉验证。这两个名字都非常好理解。网格搜索,搜索的是参数,即在指定的参数范围内,按步长依次调整参数,利用调整的参数训练学习器,从所有的参数中找到在验证集上精度最高的参数,这其实是一个训练和比较的过程。

  GridSearchCV可以保证在指定的参数范围内找到精度最高的参数,但是这也是网格搜索的缺陷所在,他要求遍历所有可能参数的组合,在面对大数据集和多参数的情况下,非常耗时。

2,什么是Grid Search网格搜索?

  Grid Search:一种调参手段;穷举搜索:在所有候选的参数选择中,通过循环遍历,尝试每一种可能性,表现最好的参数就是最终的结果。其原理就像是在数组里找到最大值。这种方法的主要缺点是比较耗时!   所以网格搜索适用于三四个(或者更少)的超参数(当超参数的数量增长时,网格搜索的计算复杂度会呈现指数增长,这时候则使用随机搜索),用户列出一个较小的超参数值域,这些超参数至于的笛卡尔积(排列组合)为一组组超参数。网格搜索算法使用每组超参数训练模型并挑选验证集误差最小的超参数组合。

class sklearn.model_selection.GridSearchCV(estimator, param_grid, scoring=None, n_jobs=None, iid='deprecated', refit=True, cv=None, verbose=0, pre_dispatch='2*n_jobs', error_score=nan, return_train_score=False)

例子

from sklearn import svm, datasetsfrom sklearn.model_selection import GridSearchCViris = datasets.load_iris()parameters = {'kernel':('linear', 'rbf'), 'C':[1, 10]}svc = svm.SVC()clf = GridSearchCV(svc, parameters)#2x2=4种clf.fit(iris.data, iris.target)#拟合x和yprint(clf.best_score_)print(clf.best_params_)#找出最佳参数

最优组合:

94b2d6c501fc62fe19090e726decdd5d.png

参数

  1. estimator :估计器对象,例如要找随机森林模型的最佳参数,就传随机森林模型。
  2. parameters:要选择的参数集合。
  3. cv: 用来指定交叉验证数据集的生成规则。假设=5表示每次计算都把数据集分成5份,拿其中一份作为交叉验证数据集,其他作为训练集。

例子一:决策树调参

# 导入库from sklearn.tree import DecisionTreeClassifierfrom sklearn import datasetsfrom sklearn.model_selection import train_test_splitimport matplotlib.pyplot as pltfrom sklearn.model_selection import GridSearchCVfrom sklearn.tree import DecisionTreeRegressorfrom sklearn import metrics# 导入数据集X = datasets.load_iris()  # 以全部字典形式返回,有data,target,target_names三个键data = X.datatarget = X.targetname = X.target_namesx,y=datasets.load_iris(return_X_y=True) # 能一次性取前2个print(x.shape,y.shape)# 数据分为训练集和测试集x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.2,random_state=100)# 用GridSearchCV寻找最优参数(字典)param = {'criterion':['gini'],'max_depth':[30,50,60,100],'min_samples_leaf':[2,3,5,10],'min_impurity_decrease':[0.1,0.2,0.5]}grid = GridSearchCV(DecisionTreeClassifier(),param_grid=param,cv=6)grid.fit(x_train,y_train)print('最优分类器:',grid.best_params_,'最优分数:', grid.best_score_)  # 得到最优的参数和分值
97151085b9d5d79508162df98a81b439.png
# 用GridSearchCV寻找最优参数(列表)param = [{'criterion':['gini'],'max_depth':[30,50,60,100],'min_samples_leaf':[2,3,5,10],'min_impurity_decrease':[0.1,0.2,0.5]},         {'criterion':['gini','entropy']},         {'max_depth': [30,60,100], 'min_impurity_decrease':[0.1,0.2,0.5]}]grid = GridSearchCV(DecisionTreeClassifier(),param_grid=param,cv=6)grid.fit(x_train,y_train)print('最优分类器:',grid.best_params_,'最优分数:', grid.best_score_)  # 得到最优的参数和分值
5743bdd4a39093b5ba35a68615c3d8cb.png

测试集分数高于训练集,说明拟合得很好,有较好的泛化能力

d18a73fb5bc5d59ae6e6df5af1e9a236.png

测试集分类得已经相当好了!

GridSearchCV调参过程

clf.fit(x_train,y_train)fig = plt.figure()ax = fig.add_subplot(111)ax.fill_between(min_samples_leaf,clf.cv_results_['mean_train_score']+clf.cv_results_['std_train_score'],                 clf.cv_results_['mean_train_score']-clf.cv_results_['std_train_score'],color='b')ax.fill_between(min_samples_leaf,clf.cv_results_['mean_test_score']+clf.cv_results_['std_test_score'],                 clf.cv_results_['mean_test_score']-clf.cv_results_['std_test_score'],color='r')ax.plot(min_samples_leaf,clf.cv_results_['mean_train_score'],'ko-')ax.plot(min_samples_leaf,clf.cv_results_['mean_test_score'],'g*-')plt.legend()plt.title('GridSearchCV训练过程图')plt.rcParams['font.sans-serif'] = ['SimHei']plt.rcParams['font.serif'] = ['SimHei']  # 设置正常显示中文plt.show()
4f659b26aa419a50d91d30f169a2a514.png

从图上可以看出,min_samples_leaf=3时,测试集的分数达到最高,训练集也还不错,且这时的标准差最小!

参考:https://blog.csdn.net/cindy407/article/details/93304059 https://blog.csdn.net/qq_25987491/article/details/81236504

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐