您好,登錄后才能下訂單哦!
在機(jī)器學(xué)習(xí)中,我們經(jīng)常在訓(xùn)練集上訓(xùn)練模型,在測試集上測試模型。最終的目標(biāo)是希望我們的模型在測試集上有最好的表現(xiàn)。
但是,我們往往只有一個(gè)包含m個(gè)觀測的數(shù)據(jù)集D,我們既要用它進(jìn)行訓(xùn)練,又要對它進(jìn)行測試。此時(shí),我們就需要對數(shù)據(jù)集D進(jìn)行劃分。
對于數(shù)據(jù)集D的劃分,我們盡量需要滿足三個(gè)要求:
我們將分別介紹留出法、交叉驗(yàn)證法,以及各自的python實(shí)現(xiàn)。自助法(bootstrapping)將在下篇中加以介紹。
1.留出法
留出法是最常用最直接最簡單的方法,它直接將數(shù)據(jù)集D拆分成兩個(gè)互斥的集合,其中一個(gè)作為訓(xùn)練集R,另一個(gè)作為測試集T。 即
在使用留出法時(shí),需要注意:
當(dāng)然留出法的缺點(diǎn)也非常明顯,即它會(huì)損失一定的樣本信息;同時(shí)需要大樣本。
python實(shí)現(xiàn)留出法,只需要使用sklearn包就可以
from sklearn.model_selection import train_test_split #使用train_test_split劃分訓(xùn)練集和測試集 train_X , test_X, train_Y ,test_Y = train_test_split( X, Y, test_size=0.2,random_state=0) ''' X為原始數(shù)據(jù)的自變量,Y為原始數(shù)據(jù)因變量; train_X,test_X是將X按照8:2劃分所得; train_Y,test_Y是將X按照8:2劃分所得; test_size是劃分比例; random_state設(shè)置是否使用隨機(jī)數(shù) '''
2.交叉驗(yàn)證法
交叉驗(yàn)證法(cross validation)可以很好地解決留出法的問題,它對數(shù)據(jù)量的要求不高,并且樣本信息損失不多。
交叉驗(yàn)證法先將數(shù)據(jù)集D劃分為k個(gè)大小相似的互斥子集,即
為了保證數(shù)據(jù)分布的一致性,從D中隨機(jī)分層抽樣即可。
之后,每次都用k-1個(gè)子集的并集作為訓(xùn)練集,余下的那個(gè)子集作為測試集,這樣我們就可以獲得k組訓(xùn)練/測試集,從而進(jìn)行k次訓(xùn)練和測試,最終返回這k組測試的均值。
具體說來,我們以k=10為例:
第一次我們選取第10份數(shù)據(jù)為測試集,前9份為訓(xùn)練集;
第二次我們選取第9份數(shù)據(jù)為測試集,第1-8和10為訓(xùn)練集;
…
第十次我們選取第1份數(shù)據(jù)為測試集,第2-9為訓(xùn)練集;
由此,我們共獲得10組訓(xùn)練集和測試集,進(jìn)行10次訓(xùn)練和測試,最終返回10次測試結(jié)果的均值。
顯然,交叉驗(yàn)證法結(jié)果的穩(wěn)定性和保真性很大程度取決于k的選擇,為了強(qiáng)調(diào)這一點(diǎn),交叉驗(yàn)證法也稱作“k折交叉驗(yàn)證法”,k最常取的是10,也有取5或者20的。
同時(shí),我們也需要避免由于數(shù)據(jù)劃分的隨機(jī)性造成的誤差,我們可以重復(fù)進(jìn)行p次實(shí)驗(yàn)。
p次k折交叉驗(yàn)證法,相當(dāng)于做了pk次留出法(比例為k-1:1)
python實(shí)現(xiàn)交叉驗(yàn)證法,只需要使用sklearn包就可以。注意,函數(shù)返回的是樣本序號。
import pandas as pd from sklearn.model_selection import KFold data = pd.read_excel('') #導(dǎo)入數(shù)據(jù) kf = KFold(n_splits = 4,shuffle = False,random_state = None) '''n_splits表示將數(shù)據(jù)分成幾份;shuffle和random_state表示是否隨機(jī)生成。 如果shuffle = False,random_state = None,重復(fù)運(yùn)行將產(chǎn)生同樣的結(jié)果; 如果shuffle = True,random_state = None,重復(fù)運(yùn)行將產(chǎn)生不同的結(jié)果; 如果shuffle = True,random_state = (一個(gè)數(shù)值),重復(fù)運(yùn)行將產(chǎn)生相同的結(jié)果; ''' for train, test in kf.split(data): print("%s %s" % (train, test)) ''' 結(jié)果 [ 5 6 7 8 9 10 11 12 13 14 15 16 17 18] [0 1 2 3 4] [ 0 1 2 3 4 10 11 12 13 14 15 16 17 18] [5 6 7 8 9] [ 0 1 2 3 4 5 6 7 8 9 15 16 17 18] [10 11 12 13 14] [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14] [15 16 17 18] '''
如果想對數(shù)據(jù)集重復(fù)幾次使用交叉驗(yàn)證法劃分的話,使用RepeatedKFold函數(shù)即可,其中多了一個(gè)參數(shù)n_repeats
與留出法相比,交叉驗(yàn)證法的數(shù)據(jù)損失較小,更加適合于小樣本,但是其計(jì)算復(fù)雜度變高,存儲(chǔ)空間變大。極端的說來,如果將數(shù)據(jù)集D(m個(gè)樣本)分成m份,每次都取m-1個(gè)樣本為訓(xùn)練集,余下的那一個(gè)為測試集。共進(jìn)行m次訓(xùn)練和測試。這種方法被叫做留一法。
留一法的優(yōu)點(diǎn)顯而易見,其數(shù)據(jù)損失只有一個(gè)樣本,并且不會(huì)受到樣本隨即劃分的影響。但是,其計(jì)算復(fù)雜度過高,空間存儲(chǔ)占用過大。
python實(shí)現(xiàn)交叉驗(yàn)證法,只需要使用sklearn包就可以
from sklearn.model_selection import LeaveOneOut
X = [1, 2, 3, 4] loo = LeaveOneOut() for train, test in loo.split(data): print("%s %s" % (train, test)) '''結(jié)果 [1 2 3] [0] [0 2 3] [1] [0 1 3] [2] [0 1 2] [3] '''
綜上所述:
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持億速云。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。