使用sklearn的cross_val_score进行交叉验证实例
在构建模型时,调参是极为重要的一个步骤,因为只有选择最佳的参数才能构建一个最优的模型。但是应该如何确定参数的值呢?所以这里记录一下选择参数的方法,以便后期复习以及分享。
(除了贝叶斯优化等方法)其它简单的验证有两种方法:
1、通过经常使用某个模型的经验和高超的数学知识。
2、通过交叉验证的方法,逐个来验证。
很显然我是属于后者所以我需要在这里记录一下
sklearn的cross_val_score:
我使用是cross_val_score方法,在sklearn中可以使用这个方法。交叉验证的原理不好表述下面随手画了一个图:
(我都没见过这么丑的图)简单说下,比如上面,我们将数据集分为10折,做一次交叉验证,实际上它是计算了十次,将每一折都当做一次测试集,其余九折当做训练集,这样循环十次。通过传入的模型,训练十次,最后将十次结果求平均值。将每个数据集都算一次
交叉验证优点:
1:交叉验证用于评估模型的预测性能,尤其是训练好的模型在新数据上的表现,可以在一定程度上减小过拟合。
2:还可以从有限的数据中获取尽可能多的有效信息。
我们如何利用它来选择参数呢?
我们可以给它加上循环,通过循环不断的改变参数,再利用交叉验证来评估不同参数模型的能力。最终选择能力最优的模型。
下面通过一个简单的实例来说明:(iris鸢尾花)
fromsklearnimportdatasets#自带数据集 fromsklearn.model_selectionimporttrain_test_split,cross_val_score#划分数据交叉验证 fromsklearn.neighborsimportKNeighborsClassifier#一个简单的模型,只有K一个参数,类似K-means importmatplotlib.pyplotasplt iris=datasets.load_iris()#加载sklearn自带的数据集 X=iris.data#这是数据 y=iris.target#这是每个数据所对应的标签 train_X,test_X,train_y,test_y=train_test_split(X,y,test_size=1/3,random_state=3)#这里划分数据以1/3的来划分训练集训练结果测试集测试结果 k_range=range(1,31) cv_scores=[]#用来放每个模型的结果值 fornink_range: knn=KNeighborsClassifier(n)#knn模型,这里一个超参数可以做预测,当多个超参数时需要使用另一种方法GridSearchCV scores=cross_val_score(knn,train_X,train_y,cv=10,scoring='accuracy')#cv:选择每次测试折数accuracy:评价指标是准确度,可以省略使用默认值,具体使用参考下面。 cv_scores.append(scores.mean()) plt.plot(k_range,cv_scores) plt.xlabel('K') plt.ylabel('Accuracy')#通过图像选择最好的参数 plt.show() best_knn=KNeighborsClassifier(n_neighbors=3)#选择最优的K=3传入模型 best_knn.fit(train_X,train_y)#训练模型 print(best_knn.score(test_X,test_y))#看看评分
最后得分0.94
关于cross_val_score的scoring参数的选择,通过查看官方文档后可以发现相关指标的选择可以在这里找到:文档。
这应该是比较简单的一个例子了,上面的注释也比较清楚,如果我表达不清楚可以问我。
补充拓展:sklearn分类算法汇总
废话不多说,上代码吧!
importos importnumpyasnp importpandasaspd fromsklearnimportdatasets fromsklearnimportpreprocessing fromsklearnimportneighbors fromsklearn.discriminant_analysisimportLinearDiscriminantAnalysis fromsklearnimportsvm fromsklearn.ensembleimportRandomForestClassifier fromsklearn.model_selectionimporttrain_test_split fromsklearn.model_selectionimportStratifiedKFold fromsklearn.linear_modelimportLogisticRegression fromsklearn.model_selectionimportGridSearchCV fromtimeimporttime fromsklearn.naive_bayesimportMultinomialNB fromsklearnimporttree fromsklearn.ensembleimportGradientBoostingClassifier #读取sklearn自带的数据集(鸢尾花) defgetData_1(): iris=datasets.load_iris() X=iris.data#样本特征矩阵,150*4矩阵,每行一个样本,每个样本维度是4 y=iris.target#样本类别矩阵,150维行向量,每个元素代表一个样本的类别 #读取本地excel表格内的数据集(抽取每类60%样本组成训练集,剩余样本组成测试集) #返回一个元祖,其内有4个元素(类型均为numpy.ndarray): #(1)归一化后的训练集矩阵,每行为一个训练样本,矩阵行数=训练样本总数,矩阵列数=每个训练样本的特征数 #(2)每个训练样本的类标 #(3)归一化后的测试集矩阵,每行为一个测试样本,矩阵行数=测试样本总数,矩阵列数=每个测试样本的特征数 #(4)每个测试样本的类标 #【注】归一化采用“最大最小值”方法。 defgetData_2(): fPath='D:\分类算法\binary_classify_data.txt' ifos.path.exists(fPath): data=pd.read_csv(fPath,header=None,skiprows=1,names=['class0','pixel0','pixel1','pixel2','pixel3']) X_train1,X_test1,y_train1,y_test1=train_test_split(data,data['class0'],test_size=0.4,random_state=0) min_max_scaler=preprocessing.MinMaxScaler()#归一化 X_train_minmax=min_max_scaler.fit_transform(np.array(X_train1)) X_test_minmax=min_max_scaler.fit_transform(np.array(X_test1)) return(X_train_minmax,np.array(y_train1),X_test_minmax,np.array(y_test1)) else: print('Nosuchfileordirectory!') #读取本地excel表格内的数据集(每类随机生成K个训练集和测试集的组合) #【K的含义】假设一共有1000个样本,K取10,那么就将这1000个样本切分10份(一份100个),那么就产生了10个测试集 #对于每一份的测试集,剩余900个样本即作为训练集 #结果返回一个字典:键为集合编号(1train,1trainclass,1test,1testclass,2train,2trainclass,2test,2testclass...),值为数据 #其中1train和1test为随机生成的第一组训练集和测试集(1trainclass和1testclass为训练样本类别和测试样本类别),其他以此类推 defgetData_3(): fPath='D:\\分类算法\\binary_classify_data.txt' ifos.path.exists(fPath): #读取csv文件内的数据, dataMatrix=np.array(pd.read_csv(fPath,header=None,skiprows=1,names=['class0','pixel0','pixel1','pixel2','pixel3'])) #获取每个样本的特征以及类标 rowNum,colNum=dataMatrix.shape[0],dataMatrix.shape[1] sampleData=[] sampleClass=[] foriinrange(0,rowNum): tempList=list(dataMatrix[i,:]) sampleClass.append(tempList[0]) sampleData.append(tempList[1:]) sampleM=np.array(sampleData)#二维矩阵,一行是一个样本,行数=样本总数,列数=样本特征数 classM=np.array(sampleClass)#一维列向量,每个元素对应每个样本所属类别 #调用StratifiedKFold方法生成训练集和测试集 skf=StratifiedKFold(n_splits=10) setDict={}#创建字典,用于存储生成的训练集和测试集 count=1 fortrainI,testIinskf.split(sampleM,classM): trainSTemp=[]#用于存储当前循环抽取出的训练样本数据 trainCTemp=[]#用于存储当前循环抽取出的训练样本类标 testSTemp=[]#用于存储当前循环抽取出的测试样本数据 testCTemp=[]#用于存储当前循环抽取出的测试样本类标 #生成训练集 trainIndex=list(trainI) fort1inrange(0,len(trainIndex)): trainNum=trainIndex[t1] trainSTemp.append(list(sampleM[trainNum,:])) trainCTemp.append(list(classM)[trainNum]) setDict[str(count)+'train']=np.array(trainSTemp) setDict[str(count)+'trainclass']=np.array(trainCTemp) #生成测试集 testIndex=list(testI) fort2inrange(0,len(testIndex)): testNum=testIndex[t2] testSTemp.append(list(sampleM[testNum,:])) testCTemp.append(list(classM)[testNum]) setDict[str(count)+'test']=np.array(testSTemp) setDict[str(count)+'testclass']=np.array(testCTemp) count+=1 returnsetDict else: print('Nosuchfileordirectory!') #K近邻(KNearestNeighbor) defKNN(): clf=neighbors.KNeighborsClassifier() returnclf #线性鉴别分析(LinearDiscriminantAnalysis) defLDA(): clf=LinearDiscriminantAnalysis() returnclf #支持向量机(SupportVectorMachine) defSVM(): clf=svm.SVC() returnclf #逻辑回归(LogisticRegression) defLR(): clf=LogisticRegression() returnclf #随机森林决策树(RandomForest) defRF(): clf=RandomForestClassifier() returnclf #多项式朴素贝叶斯分类器 defnative_bayes_classifier(): clf=MultinomialNB(alpha=0.01) returnclf #决策树 defdecision_tree_classifier(): clf=tree.DecisionTreeClassifier() returnclf #GBDT defgradient_boosting_classifier(): clf=GradientBoostingClassifier(n_estimators=200) returnclf #计算识别率 defgetRecognitionRate(testPre,testClass): testNum=len(testPre) rightNum=0 foriinrange(0,testNum): iftestClass[i]==testPre[i]: rightNum+=1 returnfloat(rightNum)/float(testNum) #report函数,将调参的详细结果存储到本地F盘(路径可自行修改,其中n_top是指定输出前多少个最优参数组合以及该组合的模型得分) defreport(results,n_top=5488): f=open('F:/grid_search_rf.txt','w') foriinrange(1,n_top+1): candidates=np.flatnonzero(results['rank_test_score']==i) forcandidateincandidates: f.write("Modelwithrank:{0}".format(i)+'\n') f.write("Meanvalidationscore:{0:.3f}(std:{1:.3f})".format( results['mean_test_score'][candidate], results['std_test_score'][candidate])+'\n') f.write("Parameters:{0}".format(results['params'][candidate])+'\n') f.write("\n") f.close() #自动调参(以随机森林为例) defselectRFParam(): clf_RF=RF() param_grid={"max_depth":[3,15], "min_samples_split":[3,5,10], "min_samples_leaf":[3,5,10], "bootstrap":[True,False], "criterion":["gini","entropy"], "n_estimators":range(10,50,10)} #"class_weight":[{0:1,1:13.24503311,2:1.315789474,3:12.42236025,4:8.163265306,5:31.25,6:4.77326969,7:19.41747573}], #"max_features":range(3,10), #"warm_start":[True,False], #"oob_score":[True,False], #"verbose":[True,False]} grid_search=GridSearchCV(clf_RF,param_grid=param_grid,n_jobs=4) start=time() T=getData_2()#获取数据集 grid_search.fit(T[0],T[1])#传入训练集矩阵和训练样本类标 print("GridSearchCVtook%.2fsecondsfor%dcandidateparametersettings." %(time()-start,len(grid_search.cv_results_['params']))) report(grid_search.cv_results_) #“主”函数1(KFold方法生成K个训练集和测试集,即数据集采用getData_3()函数获取,计算这K个组合的平均识别率) deftotalAlgorithm_1(): #获取各个分类器 clf_KNN=KNN() clf_LDA=LDA() clf_SVM=SVM() clf_LR=LR() clf_RF=RF() clf_NBC=native_bayes_classifier() clf_DTC=decision_tree_classifier() clf_GBDT=gradient_boosting_classifier() #获取训练集和测试集 setDict=getData_3() setNums=len(setDict.keys())/4#一共生成了setNums个训练集和setNums个测试集,它们之间是一一对应关系 #定义变量,用于将每个分类器的所有识别率累加 KNN_rate=0.0 LDA_rate=0.0 SVM_rate=0.0 LR_rate=0.0 RF_rate=0.0 NBC_rate=0.0 DTC_rate=0.0 GBDT_rate=0.0 foriinrange(1,int(setNums+1)): trainMatrix=setDict[str(i)+'train'] trainClass=setDict[str(i)+'trainclass'] testMatrix=setDict[str(i)+'test'] testClass=setDict[str(i)+'testclass'] #输入训练样本 clf_KNN.fit(trainMatrix,trainClass) clf_LDA.fit(trainMatrix,trainClass) clf_SVM.fit(trainMatrix,trainClass) clf_LR.fit(trainMatrix,trainClass) clf_RF.fit(trainMatrix,trainClass) clf_NBC.fit(trainMatrix,trainClass) clf_DTC.fit(trainMatrix,trainClass) clf_GBDT.fit(trainMatrix,trainClass) #计算识别率 KNN_rate+=getRecognitionRate(clf_KNN.predict(testMatrix),testClass) LDA_rate+=getRecognitionRate(clf_LDA.predict(testMatrix),testClass) SVM_rate+=getRecognitionRate(clf_SVM.predict(testMatrix),testClass) LR_rate+=getRecognitionRate(clf_LR.predict(testMatrix),testClass) RF_rate+=getRecognitionRate(clf_RF.predict(testMatrix),testClass) NBC_rate+=getRecognitionRate(clf_NBC.predict(testMatrix),testClass) DTC_rate+=getRecognitionRate(clf_DTC.predict(testMatrix),testClass) GBDT_rate+=getRecognitionRate(clf_GBDT.predict(testMatrix),testClass) #输出各个分类器的平均识别率(K个训练集测试集,计算平均) print print print print('KNearestNeighbormeanrecognitionrate:',KNN_rate/float(setNums)) print('LinearDiscriminantAnalysismeanrecognitionrate:',LDA_rate/float(setNums)) print('SupportVectorMachinemeanrecognitionrate:',SVM_rate/float(setNums)) print('LogisticRegressionmeanrecognitionrate:',LR_rate/float(setNums)) print('RandomForestmeanrecognitionrate:',RF_rate/float(setNums)) print('NativeBayesClassifiermeanrecognitionrate:',NBC_rate/float(setNums)) print('DecisionTreeClassifiermeanrecognitionrate:',DTC_rate/float(setNums)) print('GradientBoostingDecisionTreemeanrecognitionrate:',GBDT_rate/float(setNums)) #“主”函数2(每类前x%作为训练集,剩余作为测试集,即数据集用getData_2()方法获取,计算识别率) deftotalAlgorithm_2(): #获取各个分类器 clf_KNN=KNN() clf_LDA=LDA() clf_SVM=SVM() clf_LR=LR() clf_RF=RF() clf_NBC=native_bayes_classifier() clf_DTC=decision_tree_classifier() clf_GBDT=gradient_boosting_classifier() #获取训练集和测试集 T=getData_2() trainMatrix,trainClass,testMatrix,testClass=T[0],T[1],T[2],T[3] #输入训练样本 clf_KNN.fit(trainMatrix,trainClass) clf_LDA.fit(trainMatrix,trainClass) clf_SVM.fit(trainMatrix,trainClass) clf_LR.fit(trainMatrix,trainClass) clf_RF.fit(trainMatrix,trainClass) clf_NBC.fit(trainMatrix,trainClass) clf_DTC.fit(trainMatrix,trainClass) clf_GBDT.fit(trainMatrix,trainClass) #输出各个分类器的识别率 print('KNearestNeighborrecognitionrate:',getRecognitionRate(clf_KNN.predict(testMatrix),testClass)) print('LinearDiscriminantAnalysisrecognitionrate:',getRecognitionRate(clf_LDA.predict(testMatrix),testClass)) print('SupportVectorMachinerecognitionrate:',getRecognitionRate(clf_SVM.predict(testMatrix),testClass)) print('LogisticRegressionrecognitionrate:',getRecognitionRate(clf_LR.predict(testMatrix),testClass)) print('RandomForestrecognitionrate:',getRecognitionRate(clf_RF.predict(testMatrix),testClass)) print('NativeBayesClassifierrecognitionrate:',getRecognitionRate(clf_NBC.predict(testMatrix),testClass)) print('DecisionTreeClassifierrecognitionrate:',getRecognitionRate(clf_DTC.predict(testMatrix),testClass)) print('GradientBoostingDecisionTreerecognitionrate:',getRecognitionRate(clf_GBDT.predict(testMatrix),testClass)) if__name__=='__main__': print('K个训练集和测试集的平均识别率') totalAlgorithm_1() print('每类前x%训练,剩余测试,各个模型的识别率') totalAlgorithm_2() selectRFParam() print('随机森林参数调优完成!')
以上都是个人理解,如果有问题还望指出。希望大家多多支持毛票票!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。