1. 程式人生 > >python 機器學習劃分訓練集/測試集/驗證集

python 機器學習劃分訓練集/測試集/驗證集

1.留出法(hold-out)

直接將資料集D劃分為兩個互斥的集合,訓練集S、測試集T,用S訓練模型,用T來評估其測試誤差。

需要注意劃分時儘可能保持資料分佈的一致性,保持樣本類別比例相似。可採用分層取樣的方式。

在使用留出法時,一般要採用若干次隨機劃分、重複進行實驗評估後取平均值作為留出法的評估結果。通常情況下我們將2/3~4/5的樣本劃分出來用於訓練。

使用sklearn.model_selection中的train_test_split()來分割我們的資料集,其具體引數如下:

X、y代表帶劃分資料集所有樣本特徵集合(自變數)和標籤集合(因變數);

test_size:測試集所佔的比例,有以下幾種輸入型別:

  1.float型,0.0~1.0之間,此時傳入的引數即作為測試集的比例;

  2.int型,此時傳入的引數的絕對值即作為測試集樣本的數量;

  3.None,這時需要另一個引數train_size有輸入才生效,此時測試集取為train_size指定的比例或數量的補集;

  4.預設時為0.25,但要注意只有在train_size和test_size都不輸入值時預設值才會生效;

train_size:基本同test_size,但預設值為None,其實test_size和train_size輸入一個即可;

random_state:int型,控制隨機數種子,預設為None,即純隨機(偽隨機);隨機數種子其實就是該組隨機數的編號,在需要重複試驗的時候,保證得到一組一樣的隨機數。比如你每次都填1,其他引數一樣的情況下你得到的隨機陣列是一樣的。但填0或不填,每次都會不一樣。
隨機數的產生取決於種子,隨機數和種子之間的關係遵從以下兩個規則:

種子不同,產生不同的隨機數;種子相同,即使例項不同也產生相同的隨機數

stratify:控制分類問題中的分層抽樣,為了保持split前類的分佈,預設為None,即不進行分層抽樣,當傳入為陣列時,則依據該陣列進行分層抽樣(一般傳入因變數所在列即y);

shuffle:bool型,用來控制是否在分割資料前打亂原資料集的順序,預設為True

返回值:

依次返回訓練集自變數、測試集自變數、訓練集因變數、測試集因變數,因此使用該函式賦值需在等號右邊採取X_trainX_testy_trainy_test的形式;

如下是隨機抽樣時的sklearn實現:

from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.3)

如下是分層抽樣時的sklearn實現:

from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.3,stratify=y)

隨機劃分法還有以下幾種函式可以實現:ShuffleSplit,GroupShuffleSplit,StratifiedShuffleSplit

2.交叉驗證法

交叉驗證法(cross validation先將資料集D劃分為k個大小相似的互斥子集,即D=D1UD2U...UDk,DiDj=Φ(i≠j),每個子集Di都儘可能保持資料分佈的一致性,即從D中通過分層取樣得到。然後每次用k-1個子集的並集作為訓練集,剩下的那一個子集作為驗證集;從而可以進行k次訓練與測試,最終返回的是這k個測試結果的均值。顯然,交叉驗證法的穩定性和保真性在很大程度上取決與k的取值,因此交叉驗證法又稱作“k折交叉驗證”(k-fold cross validation),k最常見的取值為10,即“10折交叉驗證”,其他常見的有5,20等;

這個方法充分利用了所以樣本,但計算比較繁瑣,需要訓練k次,測試k次

交叉驗證法的一個特例:留一法(Leave-one-out,即LOO),留一法不受隨機樣本劃分方式的影響,因為m個樣本只有唯一的方式劃分m個子集——每個子集包含一個樣本,其優缺點如下:

1)優點:留一法使用的訓練集與初始資料集相比只少了一個樣本,這就使得在絕大多數情況下,留一法中被實際評估的模型與期望評估的用D訓練出的模型很相似,因此,留一法的評估結果往往被認為比較準確,

2)缺點:當資料集比較大時,訓練m個模型的計算成本是難以想象的;

 

我們使用sklearn.model_selection裡的函式進行交叉驗證

K折交叉驗證:KFold,GroupKFold,StratifiedKFold

留一法:LeaveOneGroupOut,LeavePGroupsOut,LeaveOneOut,LeavePOut

 

3.自助法(bootstrapping

自助法則是使用有放回重複取樣的方式進行資料取樣,即我們每次從資料集D中取一個樣本作為訓練集中的元素,然後把該樣本放回,重複該行為m次,這樣我們就可以得到大小為m的訓練集,在這裡面有的樣本重複出現,有的樣本則沒有出現過,我們把那些沒有出現過的樣本作為測試集。通過估計m次取樣後每個樣本大約有0.368的概率不被取樣,因此我們可以認為在D中約有36.8%的資料沒有在訓練集中出現過。

優點:這種方法對於那些資料集小、難以有效劃分訓練/測試集時很有用

缺點:該方法改變了資料的初始分佈導致會引入估計偏差。

這個可以自己自定義函式程式設計實現。

總結:

  1. 對於資料量充足的時候,通常採用留出法或者k折交叉驗證法來進行訓練/測試集的劃分;
  2. 對於資料集小且難以有效劃分訓練/測試集時使用自助法
  3. 對於資料集小且可有效劃分的時候最好使用留一法來進行劃分,因為這種方法最為準確

 

TimeSeriesSplit():

  在機器學習中還存在著一種叫做時間序列的資料型別,這種資料的特點是高度的自相關性,前後相鄰時段的資料關聯程度非常高,因此在對這種資料進行分割時不可以像其他機器學習任務那樣簡單隨機抽樣的方式取樣,對時間序列資料的取樣不能破壞其時段的連續型,在sklearn.model_selection中我們使用TimeSeriesSplit()來分割時序資料,其主要引數如下:

n_splits:int型,控制產生(訓練集+驗證集)的數量;

max_train_size:控制最大的時序資料長度;

 

參考資料:https://www.cnblogs.com/feffery/p/8823405.html

                 https://www.cnblogs.com/nolonely/p/7007432.html



1.留出法(hold-out)

直接將資料集D劃分為兩個互斥的集合,訓練集S、測試集T,用S訓練模型,用T來評估其測試誤差。

需要注意劃分時儘可能保持資料分佈的一致性,保持樣本類別比例相似。可採用分層取樣的方式。

在使用留出法時,一般要採用若干次隨機劃分、重複進行實驗評估後取平均值作為留出法的評估結果。通常情況下我們將2/3~4/5的樣本劃分出來用於訓練。

使用sklearn.model_selection中的train_test_split()來分割我們的資料集,其具體引數如下:

X、y代表帶劃分資料集所有樣本特徵集合(自變數)和標籤集合(因變數);

test_size:測試集所佔的比例,有以下幾種輸入型別:

  1.float型,0.0~1.0之間,此時傳入的引數即作為測試集的比例;

  2.int型,此時傳入的引數的絕對值即作為測試集樣本的數量;

  3.None,這時需要另一個引數train_size有輸入才生效,此時測試集取為train_size指定的比例或數量的補集;

  4.預設時為0.25,但要注意只有在train_size和test_size都不輸入值時預設值才會生效;

train_size:基本同test_size,但預設值為None,其實test_size和train_size輸入一個即可;

random_state:int型,控制隨機數種子,預設為None,即純隨機(偽隨機);隨機數種子其實就是該組隨機數的編號,在需要重複試驗的時候,保證得到一組一樣的隨機數。比如你每次都填1,其他引數一樣的情況下你得到的隨機陣列是一樣的。但填0或不填,每次都會不一樣。
隨機數的產生取決於種子,隨機數和種子之間的關係遵從以下兩個規則:

種子不同,產生不同的隨機數;種子相同,即使例項不同也產生相同的隨機數

stratify:控制分類問題中的分層抽樣,為了保持split前類的分佈,預設為None,即不進行分層抽樣,當傳入為陣列時,則依據該陣列進行分層抽樣(一般傳入因變數所在列即y);

shuffle:bool型,用來控制是否在分割資料前打亂原資料集的順序,預設為True

返回值:

依次返回訓練集自變數、測試集自變數、訓練集因變數、測試集因變數,因此使用該函式賦值需在等號右邊採取X_trainX_testy_trainy_test的形式;

如下是隨機抽樣時的sklearn實現:

from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.3)

如下是分層抽樣時的sklearn實現:

from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.3,stratify=y)

隨機劃分法還有以下幾種函式可以實現:ShuffleSplit,GroupShuffleSplit,StratifiedShuffleSplit

2.交叉驗證法

交叉驗證法(cross validation先將資料集D劃分為k個大小相似的互斥子集,即D=D1UD2U...UDk,DiDj=Φ(i≠j),每個子集Di都儘可能保持資料分佈的一致性,即從D中通過分層取樣得到。然後每次用k-1個子集的並集作為訓練集,剩下的那一個子集作為驗證集;從而可以進行k次訓練與測試,最終返回的是這k個測試結果的均值。顯然,交叉驗證法的穩定性和保真性在很大程度上取決與k的取值,因此交叉驗證法又稱作“k折交叉驗證”(k-fold cross validation),k最常見的取值為10,即“10折交叉驗證”,其他常見的有5,20等;

這個方法充分利用了所以樣本,但計算比較繁瑣,需要訓練k次,測試k次

交叉驗證法的一個特例:留一法(Leave-one-out,即LOO),留一法不受隨機樣本劃分方式的影響,因為m個樣本只有唯一的方式劃分m個子集——每個子集包含一個樣本,其優缺點如下:

1)優點:留一法使用的訓練集與初始資料集相比只少了一個樣本,這就使得在絕大多數情況下,留一法中被實際評估的模型與期望評估的用D訓練出的模型很相似,因此,留一法的評估結果往往被認為比較準確,

2)缺點:當資料集比較大時,訓練m個模型的計算成本是難以想象的;

 

我們使用sklearn.model_selection裡的函式進行交叉驗證

K折交叉驗證:KFold,GroupKFold,StratifiedKFold

留一法:LeaveOneGroupOut,LeavePGroupsOut,LeaveOneOut,LeavePOut

 

3.自助法(bootstrapping

自助法則是使用有放回重複取樣的方式進行資料取樣,即我們每次從資料集D中取一個樣本作為訓練集中的元素,然後把該樣本放回,重複該行為m次,這樣我們就可以得到大小為m的訓練集,在這裡面有的樣本重複出現,有的樣本則沒有出現過,我們把那些沒有出現過的樣本作為測試集。通過估計m次取樣後每個樣本大約有0.368的概率不被取樣,因此我們可以認為在D中約有36.8%的資料沒有在訓練集中出現過。

優點:這種方法對於那些資料集小、難以有效劃分訓練/測試集時很有用

缺點:該方法改變了資料的初始分佈導致會引入估計偏差。

這個可以自己自定義函式程式設計實現。

總結:

  1. 對於資料量充足的時候,通常採用留出法或者k折交叉驗證法來進行訓練/測試集的劃分;
  2. 對於資料集小且難以有效劃分訓練/測試集時使用自助法
  3. 對於資料集小且可有效劃分的時候最好使用留一法來進行劃分,因為這種方法最為準確

 

TimeSeriesSplit():

  在機器學習中還存在著一種叫做時間序列的資料型別,這種資料的特點是高度的自相關性,前後相鄰時段的資料關聯程度非常高,因此在對這種資料進行分割時不可以像其他機器學習任務那樣簡單隨機抽樣的方式取樣,對時間序列資料的取樣不能破壞其時段的連續型,在sklearn.model_selection中我們使用TimeSeriesSplit()來分割時序資料,其主要引數如下:

n_splits:int型,控制產生(訓練集+驗證集)的數量;

max_train_size:控制最大的時序資料長度;

 

參考資料:https://www.cnblogs.com/feffery/p/8823405.html

                 https://www.cnblogs.com/nolonely/p/7007432.html