1. 程式人生 > >交叉驗證法及Bootstrap取樣

交叉驗證法及Bootstrap取樣

一、Cross Validation(交叉驗證)

1.  解決的問題

用於驗證分類器的效能的資料分析方法,可以抽樣(抽取合適的訓練集和測試集)、可以評估模型(計算模型的預測誤差)。

2.  如何解決

基本原理:將原始資料分組,一部分做訓練集,一部分做測試集。如k-fold cross validation均分成n組,抽取一組為測試集,剩下n-1組為訓練集,依次抽遍,測試結果取預測誤差平均值。

演算法步驟:

Step1: 將學習樣本空間 C分為大小相等的 K

Step2: fori =1 to K

取第i份作為測試集

forj =1 to K:

ifi !=j:

將第j份加到訓練集中,作為訓練集的一部分

endif

endfor

endfor

Step3: fori in (K-1訓練集)

訓練第i個訓練集,得到一個分類模型

使用該模型在第N個數據集上測試,計算並儲存模型評估指標

endfor

Step4: 計算模型的平均效能

Step5:  用這K個模型在最終驗證集的分類準確率平均值作為此K-CV下分類器的效能指標.

實現抽樣:(matlab/python裡的scikit-learn庫sklearn.cross_validation

(1)K-fold(K組)

from sklearn.model_selection import KFold

X=["a","b","c","d"]

kf=KFold(n_splits=4)//分成四組,訓練四次

for train,test in kf.split(X):

        print("%s %s" % (train,test))

>>> 

[1 2 3] [0]

[0 2 3] [1]

[0 1 3] [2]

[0 1 2] [3]

(2)Repeated K-Fold(隨機分組n次,每次按K組分)

import numpy as np

from sklearn.model_selection import RepeatedKFold

X=np.array([[1,2],[3,4],[1,2],[3,4]])

random_state=12883823

rkf=RepeatedKFold(n_splits=2,n_repeats=2,random_state=random_state)//隨機分成兩組,隨機分組兩次

for train,test in rkf.split(X):

   print("%s %s" % (train,test))

>>> 

[2 3] [0 1]

[0 1] [2 3]

[0 2] [1 3]

[1 3] [0 2]

(3)LeaveOneOut/LeavePOut(隨機拿出P個數據作為測試集)

from sklearn.model_selection import LeavePOut/LeaveOneOut

X=[1,2,3,4]

lpo=LeavePOut(p=2)/LeaveOneOut()

for train,test in lpo.split(X):

   print("%s %s" % (train,test))

>>> 

[2 3] [0 1]

[1 3] [0 2]

[1 2] [0 3]

[0 3] [1 2]

[0 2] [1 3]

[0 1] [2 3]

(4)ShuffleSplit(洗牌加隨機抽樣)

import numpy as np

from sklearn.model_selection import ShuffleSplit

X=np.arange(5)

ss=ShuffleSplit(n_splits=3,test_size=2/5,random_state=0)//隨機抽三次,每次抽出測試資料佔2/5)

for train_index,test_index in ss.split(X):

   print("%s %s" % (train_index,test_index))

>>> 

[1 3 4] [2 0]

[1 4 3] [0 2]

[4 0 2] [1 3]

PS:一個不均衡樣本的例項:http://blog.csdn.net/dream_angel_z/article/details/47110077

3.  優缺點

優點:幾乎能夠訓練到所有資料

缺點:如何確定K的最佳取值(也許碰運氣吧)


二、自助法(Bootstrap)

1.  可以解決的問題

是一種統計方法,適用於小樣本抽樣,可以劃分train/test,可以通過方差估計構造置信區間。(整合學習中的bagging有運用)。

2.  如何解決

基本原理:其實就是利用樣本再生成自助樣本,自助樣本估計樣本,樣本再估計總體。在原始資料中有放回的隨機抽樣,樣本容量仍為n,所得樣本稱為bootstrap樣本。

演算法步驟:

#這個虛擬碼自己寫的,希望可以得到改正

fori =1 to K

i次取樣

iflen(train) < m:

隨機抽取一個數據新增到train

endfor

endfor

Python實現:(用bootstrap抽樣)

import random

#抽樣物件

class Sampling(object):

    def__init__(self):

        pass

    defsampling(self):

        pass

#bootstrap抽樣

class BootStrap(Sampling):

    def __init__(self,n_samples):

       self.n_samples=n_samples

    def sampling(self):

       _slice=[]

        whilelen(_slice)<self.n_samples:

           p=random.randrange(0,self.n_samples)

           _slice.append(p)

       return _slice

if __name__ == '__main__':

    bootstrap=BootStrap(10)//樣本數十個,則bootstrap樣本容量也為10

    for i inrange(5)://bootstrap抽樣次數為5,即抽出五組

       _slice=bootstrap.sampling()

       print(_slice)

>>> 

[8, 0, 6, 2, 8, 7, 2, 6, 7, 1]

[7, 1, 4, 6, 6, 0, 5, 1, 3, 8]

[2, 1, 2, 6, 1, 0, 0, 1, 3, 8]

[1, 4, 4, 2, 5, 9, 4, 6, 0, 1]

[8, 7, 3, 5, 4, 9, 3, 9, 4, 3]

PS:資料前處理例項

https://github.com/Lehyu/pyml/tree/9bcb213b5bd5702f9b7df5d03f3fedcad32e08ae/preprocessing

3.  優缺點

優點:在資料集較小時適合使用;可以從原始資料中產生多個訓練集。

缺點:改變了原始資料的分佈,會引入估計偏差。

如何劃分訓練集/驗證集/測試集?