Python中sklearn實(shí)現(xiàn)交叉驗(yàn)證示例分析
Python中sklearn實(shí)現(xiàn)交叉驗(yàn)證
一、概述
1.1 交叉驗(yàn)證的含義與作用
交叉驗(yàn)證的思想是,將數(shù)據(jù)集分為k等份,其中k-1份作為訓(xùn)練集,單獨(dú)留出的一份作為測(cè)試集。進(jìn)行模型驗(yàn)證的目的就是為了確定最合適的模型,對(duì)于監(jiān)督學(xué)習(xí)而言,為了使得創(chuàng)建的模型具有很好的泛化能力,通常需要將得到的數(shù)據(jù)預(yù)留出測(cè)試數(shù)據(jù)進(jìn)行交叉驗(yàn)證。因此,交叉驗(yàn)證的目的主要為了解決建立模型的過(guò)擬合問(wèn)題。交叉驗(yàn)證的具體過(guò)程為,將所有數(shù)據(jù)分為訓(xùn)練集與測(cè)試集兩部分,采用訓(xùn)練集對(duì)模型進(jìn)行訓(xùn)練。采用測(cè)試準(zhǔn)確度指標(biāo),對(duì)得到的模型用測(cè)試集來(lái)衡量模型的預(yù)測(cè)能力。
1.2 交叉驗(yàn)證的分類
1、k折交叉驗(yàn)證(KFold),將數(shù)據(jù)集劃分為k等份,使用python的sklearn.model_selection庫(kù)中的KFold方法實(shí)現(xiàn)。
2、p次k折交叉驗(yàn)證(RepeatedKFold),在實(shí)際應(yīng)用中,只進(jìn)行以此k折交叉驗(yàn)證往往不夠,需要進(jìn)行多次交叉驗(yàn)證,使用python的sklearn.model_selection庫(kù)中RepeatedKFold方法實(shí)現(xiàn)。
3、留一法(LeaveOneOut),是對(duì)整個(gè)數(shù)據(jù)集每次選取一個(gè)樣本作為驗(yàn)證集,其余樣本作為訓(xùn)練集。它是k折交叉驗(yàn)證的一種特殊情況,即k=n(n為數(shù)據(jù)集的個(gè)數(shù))的情況,使用python的sklearn.model_selection庫(kù)中的LeaveOneOut方法實(shí)現(xiàn)。
4、留p法(LeavePOut),原理與留一法一樣,只不過(guò)是對(duì)整個(gè)數(shù)據(jù)集每次選取p個(gè)樣本作為驗(yàn)證集,其余樣本作為訓(xùn)練集。它使用python的sklearn.model_selection庫(kù)中的LeavePOut方法實(shí)現(xiàn)。
5、隨機(jī)分配(ShuffleSplit),隨機(jī)把數(shù)據(jù)打亂,然后劃分訓(xùn)練集與測(cè)試集,使用python的sklearn.model_selection庫(kù)中的ShuffleSplit方法實(shí)現(xiàn)。
另外,針對(duì)某些特殊情況,通常采用特殊的交叉驗(yàn)證方法:
1、對(duì)于分類數(shù)據(jù),預(yù)測(cè)目標(biāo)可能是不均勻分配的,比如抽煙的煙得肺癌的比率彼不抽的人大,這種情況的數(shù)據(jù)劃分通常采用StratifiedKFold、StratifiedShuffleSplit方法。
2、對(duì)于分組數(shù)據(jù)來(lái)說(shuō),它的劃分方法是不一樣的,主要的方法有 GroupKFold,LeaveOneGroupOut,LeavePGroupOut,GroupShuffleSplit。
3、對(duì)于時(shí)間關(guān)聯(lián)的數(shù)據(jù),方法有TimeSeriesSplit。
二、交叉驗(yàn)證實(shí)例分析
本文python的版本為3.8,各個(gè)版本之間函數(shù)名字略有不同,但是原理都是一樣的,集成開(kāi)發(fā)環(huán)境使用的是Anaconda的Spyder,以下程序都是經(jīng)過(guò)編譯后,順利執(zhí)行的,讀者如果有什么疑問(wèn),可以留言。
2.1 留一法實(shí)例
留一法的python源代碼如下所示:
from sklearn.datasets import load_iris #導(dǎo)入鳶尾花數(shù)據(jù)庫(kù) #下面語(yǔ)句導(dǎo)入留一法LeaveOneOut,交叉驗(yàn)證評(píng)價(jià)指標(biāo)cross_val_score評(píng)價(jià)指標(biāo) from sklearn.model_selection import LeaveOneOut, cross_val_score #下面語(yǔ)句導(dǎo)入邏輯斯特回歸LogisticRegression from sklearn.linear_model import LogisticRegression iris = load_iris() #將鳶尾花數(shù)據(jù)庫(kù)中的數(shù)據(jù)放入iris變量中 print('Iris labels:\n{}'.format(iris.target)) #輸出鳶尾花的目標(biāo)分類,共有三種分別表示為0,1,2 logreg = LogisticRegression() #邏輯斯特回歸對(duì)象logreg loout = LeaveOneOut() #留一法對(duì)象loout #下面的語(yǔ)句計(jì)算評(píng)價(jià)指標(biāo)并輸出到scores對(duì)象,采用cress_val_score方法, #方法參數(shù)含義為,采用邏輯斯特回歸方法logreg擬合數(shù)據(jù):iris.data,iris.target, #交叉驗(yàn)證的方法為留一法loout scores = cross_val_score(logreg,iris.data,iris.target,cv=loout) #下面語(yǔ)句輸出每個(gè)樣本的擬合評(píng)價(jià)結(jié)果 print("leave-one-out cross validation scores:{}".format(scores)) #下面語(yǔ)句輸出整體評(píng)價(jià)結(jié)果,即所有樣本的評(píng)價(jià)結(jié)果平均值 print("Mean score of leave-one-out cross validation:{:.2f}".format(scores.mean()))
輸出結(jié)果如下圖所示:
2.2 留p法實(shí)例
留p法的python源代碼如下所示:
#導(dǎo)入訓(xùn)練集數(shù)據(jù)劃分方法庫(kù)train_test_split、留p法庫(kù)LevePOut from sklearn.model_selection import train_test_split, LeavePOut from sklearn import datasets #導(dǎo)入數(shù)據(jù)集 from sklearn import svm #導(dǎo)入支持向量機(jī)svm from sklearn.metrics import accuracy_score #導(dǎo)入評(píng)價(jià)指標(biāo)庫(kù) import numpy as np #導(dǎo)入數(shù)學(xué)分析庫(kù) iris = datasets.load_iris() #將鳶尾花數(shù)數(shù)據(jù)放入iris變量中 clf_svc = svm.SVC(kernel='linear') #線性核函數(shù)svm模型對(duì)象為clf_svc lpo = LeavePOut(p=3) #留p法對(duì)象lpo lpo.get_n_splits(iris.data) #對(duì)鳶尾花數(shù)據(jù)進(jìn)行劃分 mean_accuracy_score_list = [] for train_index, test_index in lpo.split(iris.data): clf_svc.fit(iris.data[train_index], iris.target[train_index]) prediction = clf_svc.predict(iris.data[test_index]) mean_accuracy_score_list.append(accuracy_score(iris.target[test_index],prediction)) print(np.average(mean_accuracy_score_list))
輸出結(jié)果如下圖所示:
2.3 k折交叉驗(yàn)證(Standard Cross Validation)實(shí)例
在python語(yǔ)言中,該方法需要通過(guò) train_test_split
方法對(duì)數(shù)據(jù)集進(jìn)行劃分,然后再不同的數(shù)據(jù)集上進(jìn)行訓(xùn)練、測(cè)試評(píng)估,進(jìn)而得到評(píng)價(jià)結(jié)果。k通常取5或者10,如果取10,則表示再原始數(shù)據(jù)集上,進(jìn)行10次劃分,每次劃分都進(jìn)行以此訓(xùn)練、評(píng)估,對(duì)5次劃分結(jié)果求取平均值作為最終的評(píng)價(jià)結(jié)果。10折交叉驗(yàn)證的原理圖如下所示:
這里以python自帶的乳腺癌數(shù)據(jù)為分析對(duì)象,采用k折交叉驗(yàn)證分析擬合模型的準(zhǔn)確性,k折交叉驗(yàn)證的python源代碼如下所示:
#以下幾行代碼,例行公事,載入需要的庫(kù)函數(shù) from sklearn.datasets import load_breast_cancer from sklearn.model_selection import cross_val_score from sklearn.linear_model import LogisticRegression cancer = load_breast_cancer() logreg = LogisticRegression() #以下指令中的cross_val_score自動(dòng)對(duì)乳腺癌數(shù)據(jù)進(jìn)行k折交叉驗(yàn)證, #注意:cross_val_score的參數(shù)cv沒(méi)有設(shè)置,默認(rèn)是3,可以修改cv為5或10, #則該方法則成為5或10折交叉驗(yàn)證 scores = cross_val_score(logreg,cancer.data,cancer.target) #打印分析結(jié)果,由于默認(rèn)cv為3,即3折交叉驗(yàn)證,所以第一個(gè)輸出為三個(gè)指標(biāo)值 print("Cross validation scores:{}".format(scores)) print("Mean cross validation score:{:2f}".format(scores.mean()))
輸出結(jié)果如下圖所示:
2.4 隨機(jī)分配交叉驗(yàn)證(Shuffle-split cross-validation)實(shí)例
使用ShuffleSplit方法,可以隨機(jī)的把數(shù)據(jù)打亂,然后分為訓(xùn)練集和測(cè)試集。隨機(jī)分配交叉驗(yàn)證的python源代碼如下所示:
from sklearn.datasets import load_iris from sklearn.model_selection import ShuffleSplit,cross_val_score from sklearn.linear_model import LogisticRegression iris = load_iris() shufspl = ShuffleSplit(train_size=.5,test_size=.4,n_splits=8) #迭代8次; logreg = LogisticRegression() scores = cross_val_score(logreg,iris.data,iris.target,cv=shufspl) print("shuffle split cross validation scores:\n{}".format(scores)) print("Mean score of shuffle split cross validation:{:.2f}".format(scores.mean()))
輸出結(jié)果如下圖所示:
2.5 分層交叉驗(yàn)證(Stratified k-fold cross validation)實(shí)例
分層交叉驗(yàn)證(Stratified k-fold cross validation):首先它屬于交叉驗(yàn)證類型,分層的意思是說(shuō)在每一折中都保持著原始數(shù)據(jù)中各個(gè)類別的比例關(guān)系,比如說(shuō):原始數(shù)據(jù)有3類,比例為1:2:1,采用3折分層交叉驗(yàn)證,那么劃分的3折中,每一折中的數(shù)據(jù)類別保持著1:2:1的比例,這樣的驗(yàn)證結(jié)果更加可信。通常情況下,可以設(shè)置cv參數(shù)來(lái)控制幾折,但是我們希望對(duì)其劃分等加以控制,所以出現(xiàn)了KFold,KFold控制劃分折,可以控制劃分折的數(shù)目,是否打亂順序等,可以賦值給cv,用來(lái)控制劃分。分層交叉驗(yàn)證的python源代碼如下所示:
from sklearn.datasets import load_iris from sklearn.model_selection import ShuffleSplit,cross_val_score from sklearn.linear_model import LogisticRegression iris = load_iris() shufspl = ShuffleSplit(train_size=.5,test_size=.4,n_splits=8) #迭代8次; logreg = LogisticRegression() scores = cross_val_score(logreg,iris.data,iris.target,cv=shufspl) print("shuffle split cross validation scores:\n{}".format(scores)) print("Mean score of shuffle split cross validation:{:.2f}".format(scores.mean()))
輸出結(jié)果如下圖所示:
到此這篇關(guān)于Python中sklearn實(shí)現(xiàn)交叉驗(yàn)證的文章就介紹到這了,更多相關(guān)Python sklearn交叉驗(yàn)證內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python函數(shù)值傳遞引用傳遞及形式參數(shù)和實(shí)際參數(shù)的區(qū)別
這篇文章主要介紹了Python函數(shù)值傳遞引用傳遞及形式參數(shù)和實(shí)際參數(shù)的區(qū)別,具有一定的參考價(jià)值,需要的小伙伴可以參考一下,希望對(duì)你的學(xué)習(xí)有所幫助2022-05-05Python?pass函數(shù)使用及其應(yīng)用的詳解
Python中,pass是一種空語(yǔ)句,即不做任何事情,只起到占位符的作用,本文主要介紹了Python?pass函數(shù)使用及其應(yīng)用的詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07Python-Tkinter Text輸入內(nèi)容在界面顯示的實(shí)例
今天小編就為大家分享一篇Python-Tkinter Text輸入內(nèi)容在界面顯示的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-07-07Python基礎(chǔ)練習(xí)之用戶登錄實(shí)現(xiàn)代碼分享
這篇文章主要介紹了Python基礎(chǔ)練習(xí)之用戶登錄實(shí)現(xiàn)代碼分享,還是比較不錯(cuò)的,這里分享給大家,供需要的朋友參考。2017-11-11