使用sklearn的cross_val_score進(jìn)行交叉驗(yàn)證實(shí)例
在構(gòu)建模型時(shí),調(diào)參是極為重要的一個(gè)步驟,因?yàn)橹挥羞x擇最佳的參數(shù)才能構(gòu)建一個(gè)最優(yōu)的模型。但是應(yīng)該如何確定參數(shù)的值呢?所以這里記錄一下選擇參數(shù)的方法,以便后期復(fù)習(xí)以及分享。
(除了貝葉斯優(yōu)化等方法)其它簡(jiǎn)單的驗(yàn)證有兩種方法:
1、通過(guò)經(jīng)常使用某個(gè)模型的經(jīng)驗(yàn)和高超的數(shù)學(xué)知識(shí)。
2、通過(guò)交叉驗(yàn)證的方法,逐個(gè)來(lái)驗(yàn)證。
很顯然我是屬于后者所以我需要在這里記錄一下
sklearn 的 cross_val_score:
我使用是cross_val_score方法,在sklearn中可以使用這個(gè)方法。交叉驗(yàn)證的原理不好表述下面隨手畫(huà)了一個(gè)圖:

(我都沒(méi)見(jiàn)過(guò)這么丑的圖)簡(jiǎn)單說(shuō)下,比如上面,我們將數(shù)據(jù)集分為10折,做一次交叉驗(yàn)證,實(shí)際上它是計(jì)算了十次,將每一折都當(dāng)做一次測(cè)試集,其余九折當(dāng)做訓(xùn)練集,這樣循環(huán)十次。通過(guò)傳入的模型,訓(xùn)練十次,最后將十次結(jié)果求平均值。將每個(gè)數(shù)據(jù)集都算一次
交叉驗(yàn)證優(yōu)點(diǎn):
1:交叉驗(yàn)證用于評(píng)估模型的預(yù)測(cè)性能,尤其是訓(xùn)練好的模型在新數(shù)據(jù)上的表現(xiàn),可以在一定程度上減小過(guò)擬合。
2:還可以從有限的數(shù)據(jù)中獲取盡可能多的有效信息。
我們?nèi)绾卫盟鼇?lái)選擇參數(shù)呢?
我們可以給它加上循環(huán),通過(guò)循環(huán)不斷的改變參數(shù),再利用交叉驗(yàn)證來(lái)評(píng)估不同參數(shù)模型的能力。最終選擇能力最優(yōu)的模型。
下面通過(guò)一個(gè)簡(jiǎn)單的實(shí)例來(lái)說(shuō)明:(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 #一個(gè)簡(jiǎn)單的模型,只有K一個(gè)參數(shù),類似K-means
import matplotlib.pyplot as plt
iris = datasets.load_iris() #加載sklearn自帶的數(shù)據(jù)集
X = iris.data #這是數(shù)據(jù)
y = iris.target #這是每個(gè)數(shù)據(jù)所對(duì)應(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的來(lái)劃分 訓(xùn)練集訓(xùn)練結(jié)果 測(cè)試集測(cè)試結(jié)果
k_range = range(1,31)
cv_scores = [] #用來(lái)放每個(gè)模型的結(jié)果值
for n in k_range:
knn = KNeighborsClassifier(n) #knn模型,這里一個(gè)超參數(shù)可以做預(yù)測(cè),當(dāng)多個(gè)超參數(shù)時(shí)需要使用另一種方法GridSearchCV
scores = cross_val_score(knn,train_X,train_y,cv=10,scoring='accuracy') #cv:選擇每次測(cè)試折數(shù) accuracy:評(píng)價(jià)指標(biāo)是準(zhǔn)確度,可以省略使用默認(rèn)值,具體使用參考下面。
cv_scores.append(scores.mean())
plt.plot(k_range,cv_scores)
plt.xlabel('K')
plt.ylabel('Accuracy') #通過(guò)圖像選擇最好的參數(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)) #看看評(píng)分
最后得分0.94

關(guān)于 cross_val_score 的 scoring 參數(shù)的選擇,通過(guò)查看官方文檔后可以發(fā)現(xiàn)相關(guān)指標(biāo)的選擇可以在這里找到:文檔。
這應(yīng)該是比較簡(jiǎn)單的一個(gè)例子了,上面的注釋也比較清楚,如果我表達(dá)不清楚可以問(wèn)我。
補(bǔ)充拓展:sklearn分類算法匯總
廢話不多說(shuō),上代碼吧!
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矩陣,每行一個(gè)樣本,每個(gè)樣本維度是4
y = iris.target #樣本類別矩陣,150維行向量,每個(gè)元素代表一個(gè)樣本的類別
#讀取本地excel表格內(nèi)的數(shù)據(jù)集(抽取每類60%樣本組成訓(xùn)練集,剩余樣本組成測(cè)試集)
#返回一個(gè)元祖,其內(nèi)有4個(gè)元素(類型均為numpy.ndarray):
#(1)歸一化后的訓(xùn)練集矩陣,每行為一個(gè)訓(xùn)練樣本,矩陣行數(shù)=訓(xùn)練樣本總數(shù),矩陣列數(shù)=每個(gè)訓(xùn)練樣本的特征數(shù)
#(2)每個(gè)訓(xùn)練樣本的類標(biāo)
#(3)歸一化后的測(cè)試集矩陣,每行為一個(gè)測(cè)試樣本,矩陣行數(shù)=測(cè)試樣本總數(shù),矩陣列數(shù)=每個(gè)測(cè)試樣本的特征數(shù)
#(4)每個(gè)測(cè)試樣本的類標(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個(gè)訓(xùn)練集和測(cè)試集的組合)
#【K的含義】假設(shè)一共有1000個(gè)樣本,K取10,那么就將這1000個(gè)樣本切分10份(一份100個(gè)),那么就產(chǎn)生了10個(gè)測(cè)試集
#對(duì)于每一份的測(cè)試集,剩余900個(gè)樣本即作為訓(xùn)練集
#結(jié)果返回一個(gè)字典:鍵為集合編號(hào)(1train, 1trainclass, 1test, 1testclass, 2train, 2trainclass, 2test, 2testclass...),值為數(shù)據(jù)
#其中1train和1test為隨機(jī)生成的第一組訓(xùn)練集和測(cè)試集(1trainclass和1testclass為訓(xùn)練樣本類別和測(cè)試樣本類別),其他以此類推
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']))
#獲取每個(gè)樣本的特征以及類標(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) #二維矩陣,一行是一個(gè)樣本,行數(shù)=樣本總數(shù),列數(shù)=樣本特征數(shù)
classM = np.array(sampleClass) #一維列向量,每個(gè)元素對(duì)應(yīng)每個(gè)樣本所屬類別
#調(diào)用StratifiedKFold方法生成訓(xùn)練集和測(cè)試集
skf = StratifiedKFold(n_splits = 10)
setDict = {} #創(chuàng)建字典,用于存儲(chǔ)生成的訓(xùn)練集和測(cè)試集
count = 1
for trainI, testI in skf.split(sampleM, classM):
trainSTemp = [] #用于存儲(chǔ)當(dāng)前循環(huán)抽取出的訓(xùn)練樣本數(shù)據(jù)
trainCTemp = [] #用于存儲(chǔ)當(dāng)前循環(huán)抽取出的訓(xùn)練樣本類標(biāo)
testSTemp = [] #用于存儲(chǔ)當(dāng)前循環(huán)抽取出的測(cè)試樣本數(shù)據(jù)
testCTemp = [] #用于存儲(chǔ)當(dāng)前循環(huán)抽取出的測(cè)試樣本類標(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)
#生成測(cè)試集
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ī)森林決策樹(shù)(Random Forest)
def RF():
clf = RandomForestClassifier()
return clf
#多項(xiàng)式樸素貝葉斯分類器
def native_bayes_classifier():
clf = MultinomialNB(alpha = 0.01)
return clf
#決策樹(shù)
def decision_tree_classifier():
clf = tree.DecisionTreeClassifier()
return clf
#GBDT
def gradient_boosting_classifier():
clf = GradientBoostingClassifier(n_estimators = 200)
return clf
#計(jì)算識(shí)別率
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é)果存儲(chǔ)到本地F盤(pán)(路徑可自行修改,其中n_top是指定輸出前多少個(gè)最優(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()
#自動(dòng)調(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個(gè)訓(xùn)練集和測(cè)試集,即數(shù)據(jù)集采用getData_3()函數(shù)獲取,計(jì)算這K個(gè)組合的平均識(shí)別率)
def totalAlgorithm_1():
#獲取各個(gè)分類器
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)練集和測(cè)試集
setDict = getData_3()
setNums = len(setDict.keys()) / 4 #一共生成了setNums個(gè)訓(xùn)練集和setNums個(gè)測(cè)試集,它們之間是一一對(duì)應(yīng)關(guān)系
#定義變量,用于將每個(gè)分類器的所有識(shí)別率累加
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)
#計(jì)算識(shí)別率
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)
#輸出各個(gè)分類器的平均識(shí)別率(K個(gè)訓(xùn)練集測(cè)試集,計(jì)算平均)
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)練集,剩余作為測(cè)試集,即數(shù)據(jù)集用getData_2()方法獲取,計(jì)算識(shí)別率)
def totalAlgorithm_2():
#獲取各個(gè)分類器
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)練集和測(cè)試集
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)
#輸出各個(gè)分類器的識(shí)別率
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個(gè)訓(xùn)練集和測(cè)試集的平均識(shí)別率')
totalAlgorithm_1()
print('每類前x%訓(xùn)練,剩余測(cè)試,各個(gè)模型的識(shí)別率')
totalAlgorithm_2()
selectRFParam()
print('隨機(jī)森林參數(shù)調(diào)優(yōu)完成!')
以上都是個(gè)人理解,如果有問(wèn)題還望指出。希望大家多多支持腳本之家!
相關(guān)文章
淺談Selenium+Webdriver 常用的元素定位方式
這篇文章主要介紹了淺談Selenium+Webdriver 常用的元素定位方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01
python SVM 線性分類模型的實(shí)現(xiàn)
這篇文章主要介紹了python SVM 線性分類模型的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07
python 安裝庫(kù)幾種方法之cmd,anaconda,pycharm詳解
在python項(xiàng)目開(kāi)發(fā)的過(guò)程中,需要安裝大大小小的庫(kù),本文會(huì)提供幾種安裝庫(kù)的方法,通過(guò)實(shí)例截圖給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下2020-04-04
python list格式數(shù)據(jù)excel導(dǎo)出方法
今天小編就為大家分享一篇python list格式數(shù)據(jù)excel導(dǎo)出方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-10-10
Python+Turtle繪制一個(gè)可愛(ài)的生日蛋糕
每當(dāng)有朋友過(guò)生日時(shí),生日蛋糕自然是必不可少的。本文將利用Python中的turtle、math和random繪制一個(gè)可愛(ài)的生日蛋糕,需要的可以參考一下2022-05-05

