使用sklearn的cross_val_score進(jìn)行交叉驗(yàn)證實(shí)例
在構(gòu)建模型時,調(diào)參是極為重要的一個步驟,因?yàn)橹挥羞x擇最佳的參數(shù)才能構(gòu)建一個最優(yōu)的模型。但是應(yīng)該如何確定參數(shù)的值呢?所以這里記錄一下選擇參數(shù)的方法,以便后期復(fù)習(xí)以及分享。
(除了貝葉斯優(yōu)化等方法)其它簡單的驗(yàn)證有兩種方法:
1、通過經(jīng)常使用某個模型的經(jīng)驗(yàn)和高超的數(shù)學(xué)知識。
2、通過交叉驗(yàn)證的方法,逐個來驗(yàn)證。
很顯然我是屬于后者所以我需要在這里記錄一下
sklearn 的 cross_val_score:
我使用是cross_val_score方法,在sklearn中可以使用這個方法。交叉驗(yàn)證的原理不好表述下面隨手畫了一個圖:
(我都沒見過這么丑的圖)簡單說下,比如上面,我們將數(shù)據(jù)集分為10折,做一次交叉驗(yàn)證,實(shí)際上它是計算了十次,將每一折都當(dāng)做一次測試集,其余九折當(dāng)做訓(xùn)練集,這樣循環(huán)十次。通過傳入的模型,訓(xùn)練十次,最后將十次結(jié)果求平均值。將每個數(shù)據(jù)集都算一次
交叉驗(yàn)證優(yōu)點(diǎn):
1:交叉驗(yàn)證用于評估模型的預(yù)測性能,尤其是訓(xùn)練好的模型在新數(shù)據(jù)上的表現(xiàn),可以在一定程度上減小過擬合。
2:還可以從有限的數(shù)據(jù)中獲取盡可能多的有效信息。
我們?nèi)绾卫盟鼇磉x擇參數(shù)呢?
我們可以給它加上循環(huán),通過循環(huán)不斷的改變參數(shù),再利用交叉驗(yàn)證來評估不同參數(shù)模型的能力。最終選擇能力最優(yōu)的模型。
下面通過一個簡單的實(shí)例來說明:(iris鳶尾花)
from sklearn import datasets #自帶數(shù)據(jù)集 from sklearn.model_selection import train_test_split,cross_val_score #劃分?jǐn)?shù)據(jù) 交叉驗(yàn)證 from sklearn.neighbors import KNeighborsClassifier #一個簡單的模型,只有K一個參數(shù),類似K-means import matplotlib.pyplot as plt iris = datasets.load_iris() #加載sklearn自帶的數(shù)據(jù)集 X = iris.data #這是數(shù)據(jù) y = iris.target #這是每個數(shù)據(jù)所對應(yīng)的標(biāo)簽 train_X,test_X,train_y,test_y = train_test_split(X,y,test_size=1/3,random_state=3) #這里劃分?jǐn)?shù)據(jù)以1/3的來劃分 訓(xùn)練集訓(xùn)練結(jié)果 測試集測試結(jié)果 k_range = range(1,31) cv_scores = [] #用來放每個模型的結(jié)果值 for n in k_range: knn = KNeighborsClassifier(n) #knn模型,這里一個超參數(shù)可以做預(yù)測,當(dāng)多個超參數(shù)時需要使用另一種方法GridSearchCV scores = cross_val_score(knn,train_X,train_y,cv=10,scoring='accuracy') #cv:選擇每次測試折數(shù) accuracy:評價指標(biāo)是準(zhǔn)確度,可以省略使用默認(rèn)值,具體使用參考下面。 cv_scores.append(scores.mean()) plt.plot(k_range,cv_scores) plt.xlabel('K') plt.ylabel('Accuracy') #通過圖像選擇最好的參數(shù) plt.show() best_knn = KNeighborsClassifier(n_neighbors=3) # 選擇最優(yōu)的K=3傳入模型 best_knn.fit(train_X,train_y) #訓(xùn)練模型 print(best_knn.score(test_X,test_y)) #看看評分
最后得分0.94
關(guān)于 cross_val_score 的 scoring 參數(shù)的選擇,通過查看官方文檔后可以發(fā)現(xiàn)相關(guān)指標(biāo)的選擇可以在這里找到:文檔。
這應(yīng)該是比較簡單的一個例子了,上面的注釋也比較清楚,如果我表達(dá)不清楚可以問我。
補(bǔ)充拓展:sklearn分類算法匯總
廢話不多說,上代碼吧!
import os import numpy as np import pandas as pd from sklearn import datasets from sklearn import preprocessing from sklearn import neighbors from sklearn.discriminant_analysis import LinearDiscriminantAnalysis from sklearn import svm from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import train_test_split from sklearn.model_selection import StratifiedKFold from sklearn.linear_model import LogisticRegression from sklearn.model_selection import GridSearchCV from time import time from sklearn.naive_bayes import MultinomialNB from sklearn import tree from sklearn.ensemble import GradientBoostingClassifier #讀取sklearn自帶的數(shù)據(jù)集(鳶尾花) def getData_1(): iris = datasets.load_iris() X = iris.data #樣本特征矩陣,150*4矩陣,每行一個樣本,每個樣本維度是4 y = iris.target #樣本類別矩陣,150維行向量,每個元素代表一個樣本的類別 #讀取本地excel表格內(nèi)的數(shù)據(jù)集(抽取每類60%樣本組成訓(xùn)練集,剩余樣本組成測試集) #返回一個元祖,其內(nèi)有4個元素(類型均為numpy.ndarray): #(1)歸一化后的訓(xùn)練集矩陣,每行為一個訓(xùn)練樣本,矩陣行數(shù)=訓(xùn)練樣本總數(shù),矩陣列數(shù)=每個訓(xùn)練樣本的特征數(shù) #(2)每個訓(xùn)練樣本的類標(biāo) #(3)歸一化后的測試集矩陣,每行為一個測試樣本,矩陣行數(shù)=測試樣本總數(shù),矩陣列數(shù)=每個測試樣本的特征數(shù) #(4)每個測試樣本的類標(biāo) #【注】歸一化采用“最大最小值”方法。 def getData_2(): fPath = 'D:\分類算法\binary_classify_data.txt' if os.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 ('No such file or directory!') #讀取本地excel表格內(nèi)的數(shù)據(jù)集(每類隨機(jī)生成K個訓(xùn)練集和測試集的組合) #【K的含義】假設(shè)一共有1000個樣本,K取10,那么就將這1000個樣本切分10份(一份100個),那么就產(chǎn)生了10個測試集 #對于每一份的測試集,剩余900個樣本即作為訓(xùn)練集 #結(jié)果返回一個字典:鍵為集合編號(1train, 1trainclass, 1test, 1testclass, 2train, 2trainclass, 2test, 2testclass...),值為數(shù)據(jù) #其中1train和1test為隨機(jī)生成的第一組訓(xùn)練集和測試集(1trainclass和1testclass為訓(xùn)練樣本類別和測試樣本類別),其他以此類推 def getData_3(): fPath = 'D:\\分類算法\\binary_classify_data.txt' if os.path.exists(fPath): #讀取csv文件內(nèi)的數(shù)據(jù), dataMatrix = np.array(pd.read_csv(fPath,header=None,skiprows=1,names=['class0','pixel0','pixel1','pixel2','pixel3'])) #獲取每個樣本的特征以及類標(biāo) rowNum, colNum = dataMatrix.shape[0], dataMatrix.shape[1] sampleData = [] sampleClass = [] for i in range(0, rowNum): tempList = list(dataMatrix[i,:]) sampleClass.append(tempList[0]) sampleData.append(tempList[1:]) sampleM = np.array(sampleData) #二維矩陣,一行是一個樣本,行數(shù)=樣本總數(shù),列數(shù)=樣本特征數(shù) classM = np.array(sampleClass) #一維列向量,每個元素對應(yīng)每個樣本所屬類別 #調(diào)用StratifiedKFold方法生成訓(xùn)練集和測試集 skf = StratifiedKFold(n_splits = 10) setDict = {} #創(chuàng)建字典,用于存儲生成的訓(xùn)練集和測試集 count = 1 for trainI, testI in skf.split(sampleM, classM): trainSTemp = [] #用于存儲當(dāng)前循環(huán)抽取出的訓(xùn)練樣本數(shù)據(jù) trainCTemp = [] #用于存儲當(dāng)前循環(huán)抽取出的訓(xùn)練樣本類標(biāo) testSTemp = [] #用于存儲當(dāng)前循環(huán)抽取出的測試樣本數(shù)據(jù) testCTemp = [] #用于存儲當(dāng)前循環(huán)抽取出的測試樣本類標(biāo) #生成訓(xùn)練集 trainIndex = list(trainI) for t1 in range(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) for t2 in range(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 return setDict else: print ('No such file or directory!') #K近鄰(K Nearest Neighbor) def KNN(): clf = neighbors.KNeighborsClassifier() return clf #線性鑒別分析(Linear Discriminant Analysis) def LDA(): clf = LinearDiscriminantAnalysis() return clf #支持向量機(jī)(Support Vector Machine) def SVM(): clf = svm.SVC() return clf #邏輯回歸(Logistic Regression) def LR(): clf = LogisticRegression() return clf #隨機(jī)森林決策樹(Random Forest) def RF(): clf = RandomForestClassifier() return clf #多項(xiàng)式樸素貝葉斯分類器 def native_bayes_classifier(): clf = MultinomialNB(alpha = 0.01) return clf #決策樹 def decision_tree_classifier(): clf = tree.DecisionTreeClassifier() return clf #GBDT def gradient_boosting_classifier(): clf = GradientBoostingClassifier(n_estimators = 200) return clf #計算識別率 def getRecognitionRate(testPre, testClass): testNum = len(testPre) rightNum = 0 for i in range(0, testNum): if testClass[i] == testPre[i]: rightNum += 1 return float(rightNum) / float(testNum) #report函數(shù),將調(diào)參的詳細(xì)結(jié)果存儲到本地F盤(路徑可自行修改,其中n_top是指定輸出前多少個最優(yōu)參數(shù)組合以及該組合的模型得分) def report(results, n_top=5488): f = open('F:/grid_search_rf.txt', 'w') for i in range(1, n_top + 1): candidates = np.flatnonzero(results['rank_test_score'] == i) for candidate in candidates: f.write("Model with rank: {0}".format(i) + '\n') f.write("Mean validation score: {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() #自動調(diào)參(以隨機(jī)森林為例) def selectRFParam(): 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() #獲取數(shù)據(jù)集 grid_search.fit(T[0], T[1]) #傳入訓(xùn)練集矩陣和訓(xùn)練樣本類標(biāo) print("GridSearchCV took %.2f seconds for %d candidate parameter settings." % (time() - start, len(grid_search.cv_results_['params']))) report(grid_search.cv_results_) #“主”函數(shù)1(KFold方法生成K個訓(xùn)練集和測試集,即數(shù)據(jù)集采用getData_3()函數(shù)獲取,計算這K個組合的平均識別率) def totalAlgorithm_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() #獲取訓(xùn)練集和測試集 setDict = getData_3() setNums = len(setDict.keys()) / 4 #一共生成了setNums個訓(xùn)練集和setNums個測試集,它們之間是一一對應(yīng)關(guān)系 #定義變量,用于將每個分類器的所有識別率累加 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 for i in range(1, int(setNums + 1)): trainMatrix = setDict[str(i) + 'train'] trainClass = setDict[str(i) + 'trainclass'] testMatrix = setDict[str(i) + 'test'] testClass = setDict[str(i) + 'testclass'] #輸入訓(xùn)練樣本 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個訓(xùn)練集測試集,計算平均) print print print print('K Nearest Neighbor mean recognition rate: ', KNN_rate / float(setNums)) print('Linear Discriminant Analysis mean recognition rate: ', LDA_rate / float(setNums)) print('Support Vector Machine mean recognition rate: ', SVM_rate / float(setNums)) print('Logistic Regression mean recognition rate: ', LR_rate / float(setNums)) print('Random Forest mean recognition rate: ', RF_rate / float(setNums)) print('Native Bayes Classifier mean recognition rate: ', NBC_rate / float(setNums)) print('Decision Tree Classifier mean recognition rate: ', DTC_rate / float(setNums)) print('Gradient Boosting Decision Tree mean recognition rate: ', GBDT_rate / float(setNums)) #“主”函數(shù)2(每類前x%作為訓(xùn)練集,剩余作為測試集,即數(shù)據(jù)集用getData_2()方法獲取,計算識別率) def totalAlgorithm_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() #獲取訓(xùn)練集和測試集 T = getData_2() trainMatrix, trainClass, testMatrix, testClass = T[0], T[1], T[2], T[3] #輸入訓(xùn)練樣本 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('K Nearest Neighbor recognition rate: ', getRecognitionRate(clf_KNN.predict(testMatrix), testClass)) print('Linear Discriminant Analysis recognition rate: ', getRecognitionRate(clf_LDA.predict(testMatrix), testClass)) print('Support Vector Machine recognition rate: ', getRecognitionRate(clf_SVM.predict(testMatrix), testClass)) print('Logistic Regression recognition rate: ', getRecognitionRate(clf_LR.predict(testMatrix), testClass)) print('Random Forest recognition rate: ', getRecognitionRate(clf_RF.predict(testMatrix), testClass)) print('Native Bayes Classifier recognition rate: ', getRecognitionRate(clf_NBC.predict(testMatrix), testClass)) print('Decision Tree Classifier recognition rate: ', getRecognitionRate(clf_DTC.predict(testMatrix), testClass)) print('Gradient Boosting Decision Tree recognition rate: ', getRecognitionRate(clf_GBDT.predict(testMatrix), testClass)) if __name__ == '__main__': print('K個訓(xùn)練集和測試集的平均識別率') totalAlgorithm_1() print('每類前x%訓(xùn)練,剩余測試,各個模型的識別率') totalAlgorithm_2() selectRFParam() print('隨機(jī)森林參數(shù)調(diào)優(yōu)完成!')
以上都是個人理解,如果有問題還望指出。希望大家多多支持腳本之家!
相關(guān)文章
Python Serial串口基本操作(收發(fā)數(shù)據(jù))
這篇文章主要介紹了Python Serial串口基本操作(收發(fā)數(shù)據(jù)),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-11-11python?open讀取文件內(nèi)容時的mode模式解析
這篇文章主要介紹了python?open讀取文件內(nèi)容時的mode模式解析,Python可以使用open函數(shù)來實(shí)現(xiàn)文件的打開,關(guān)閉,讀寫操作,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-05-05Python利用 utf-8-sig 編碼格式解決寫入 csv 文件亂碼問題
這篇文章主要介紹了Python利用 utf-8-sig 編碼格式解決寫入 csv 文件亂碼問題,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下2020-02-02python標(biāo)準(zhǔn)庫 datetime的astimezone設(shè)置時區(qū)遇到的坑及解決
這篇文章主要介紹了python標(biāo)準(zhǔn)庫 datetime的astimezone設(shè)置時區(qū)遇到的坑及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-09-09在Python的gevent框架下執(zhí)行異步的Solr查詢的教程
這篇文章主要介紹了在Python的gevent框架下執(zhí)行異步的Solr查詢的教程,Solr請求在處理I/O方面較為高效,需要的朋友可以參考下2015-04-04python利用smtplib實(shí)現(xiàn)QQ郵箱發(fā)送郵件
這篇文章主要為大家詳細(xì)介紹了python利用smtplib實(shí)現(xiàn)QQ郵箱發(fā)送郵件,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-05-05Python解方程組 scipy.optimize.fsolve()函數(shù)如何求解帶有循環(huán)求和的方程式
這篇文章主要介紹了Python解方程組 scipy.optimize.fsolve()函數(shù)如何求解帶有循環(huán)求和的方程式,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-06-06