在日常模型训练过程中,模型有多种选择,模型的参数同样也有多种选择,如何根据同一批数据选出最适合的模型和参数呢?
一般情况下,模型还比较好选择,是选用机器学习中分类模型例如 LR、SVM或XGBoost等,还是使用深度学习模型CNN、LSTM等。但是参数的选择就让人很头疼,每个模型都有一堆参数,参数值又有许多,如何不费人力而费机器的选择模型参数呢,我今天看到了一种方法叫做:GridSearch,叫做网格搜索,准备记录一下。
什么是Grid Search 网格搜索?
Grid Search:一种调参手段,看起来很高大上,其实原理并不是很高大上(汗)。
穷举搜索:在所有候选的参数选择中,通过循环遍历,尝试每一种可能性,表现最好的参数就是最终的结果。其原理就像是在数组里找最大值。(为什么叫网格搜索?以有两个参数的模型为例,参数a有3种可能,参数b有4种可能,把所有可能性列出来,可以表示成一个3*4的表格,其中每个cell就是一个网格,循环过程就像是在每个网格里遍历、搜索,所以叫grid search)
例如支持向量机中的SVC模型,一般调参的参数有 C 和 gamma。
其中 C是惩罚系数,即对误差的宽容度。c越高,说明越不能容忍出现误差,容易过拟合。C越小,容易欠拟合。C过大或过小,泛化能力变差
gamma是选择RBF函数作为kernel后,该函数自带的一个参数。隐含地决定了数据映射到新的特征空间后的分布,gamma越大,支持向量越少,gamma值越小,支持向量越多。支持向量的个数影响训练与预测的速度。
而网格搜索就像是在下面这个由多个参数构成的网格里搜索一样:
Simple Grid Search 简单的网格搜索
其实在了解了网格搜索的原理后,我们实现网格搜索可以通过两层for循环,遍历每一个参数组合并返回模型在测试集上的分数,选择最高分数训练出来的模型参数即可。例如我们仅将SVC模型中的C和gamma作为待调参数:
from sklearn.datasets import load_iris from sklearn.svm import SVC from sklearn.model_selection import train_test_split iris = load_iris() X_train,X_test,y_train,y_test = train_test_split(iris.data,iris.target,random_state=0) print("Size of training set:{} size of testing set:{}".format(X_train.shape[0],X_test.shape[0])) #### grid search start best_score = 0 for gamma in [0.001,0.01,0.1,1,10,100]: for C in [0.001,0.01,0.1,1,10,100]: svm = SVC(gamma=gamma,C=C)#对于每种参数可能的组合,进行一次训练; svm.fit(X_train,y_train) score =