k折交叉驗證(matlab和python程序實現)


參考鏈接

 

 

 一、例子

Data = rand(9,3);%創建維度為9×3的隨機矩陣樣本
indices = crossvalind('Kfold', 9, 3);%將數據樣本隨機分割為3部分
for i = 1:3 %循環3次,分別取出第i部分作為測試樣本,其余兩部分作為訓練樣本
    test = (indices == i);
    train = ~test;
    trainData = Data(train, :);
    testData = Data(test, :);
end

  程序解讀:1、創建9X3的矩陣

       2、把矩陣按將9行數據分成3個類

       3、拿出每一類的數據拿出來進行驗證

        例如,最后運行的是第三類,可以看到分類中,1,5,9行為第三類數據

 

  原始數據中的1,5,9行的數據為test_trian (檢驗數據),剩下的數據為測試數據。test對應的測試集數據邏輯值為1train對應的訓練集數據邏輯值為1

 

    

 

 

 

 

 

 

 

 二、k-重交叉驗證(k-fold crossValidation):

[M,N]=size(data);//數據集為一個M*N的矩陣,其中每一行代表一個樣本
indices=crossvalind('Kfold',data(1:M,N),10);//進行隨機分包
fork=1:10//交叉驗證k=10,10個包輪流作為測試集
test = (indices == k); //獲得test集元素在數據集中對應的單元編號
train = ~test;//train集元素的編號為非test元素的編號
train_data=data(train,:);//從數據集中划分出train樣本的數據
train_target=target(:,train);//獲得樣本集的測試目標,在本例中是實際分類情況
test_data=data(test,:);//test樣本集
test_target=target(:,test);

  

 三、利用十折交叉驗證計算錯誤分類率

   3.1代碼部分

load fisheriris
indices = crossvalind('Kfold',species,10); 
cp = classperf(species); 
for i = 1:10
      test = (indices == i); train = ~test;    %分別取第1、2、...、10份為測試集,其余為訓練集
      class = classify(meas(test,:),meas(train,:),species(train,:));
      classperf(cp,class,test);
end
cp.ErrorRate     %查詢錯誤分類率

 

  fisheriris為鳶尾花數據集:有meas和species兩部分

 

 

 

   3.2相關函數解釋

  3.2.1Indices = crossvalind('Kfold', N, K)

    1)參數'Kfold'表明為了K折十字交叉驗證,把數據集N隨機分成平均的(或近似評價的)K份,Indices中為每個樣本所屬部分的索引(從1到K)
     2)因為是隨機分,因此重復調用會產生不同分法。
     3)在K折十字交叉驗證中,K-1份被用做訓練,剩下的1份用來測試,這個過程被重復K次。

   3.2.2cp = classperf(truelabels)

      1)classperf是評估分類器性能(Evaluate performance of classifie)函數。

      2)truelabels中為每個樣本對應的真實類別,創建並初始化一個空的分類器性能對象CP。

   3.2.3class = classify(sample,training,group)  

      1)classify是判別分析(Discriminant Analysis)函數。

      2)若事先已經建立類別,則使用判別分析;若事先沒有建立類別,則使用聚類分析。一般地,若已有給定的若干總體的(即若干類別)的觀測資料,希望構造一個或多個判別函數,能由此函數對新的位置其所屬總體的樣品作出判斷,從而決定其應屬於哪個總體,這就是判別分析問題。

      3)判別分析是利用原有的分類信息,得到判別函數(判別函數關系式,一般是與分類相關的若干個指標的線性關系式),然后利用 該函數去判斷未知樣品屬於哪一類。因此,這是一個學習與預測的過程。常用的判別分析法有距離判別法、費歇爾判別法、貝葉斯判別法等。

      4)matlab中語法:class = classify(sample,training,group) ,默認線性判別分析,將sample的每個樣本進行判別,分到trainning指定的類中,返回該類表作為分類結果。還可以用參數type指定判別分析法。

    3.2.4classperf(cp, classout, testidx)

      1)根據分類結果,更新分類器性能對象CP。

      2)在十折交叉驗證法中,就是重復10次,可累積得到總的錯誤分類率。

四、10折交叉驗證例子  

  第1步,將數據等分到10個桶中。
 

  我們會將500名籃球運動員和500名非籃球運動員分到每個桶中。每個桶當中放入了100人的信息。

  第2步,下列步驟重復10次。

    (1)每一次迭代中留存其中一個桶。第一次迭代中留存桶1,第二次留存桶2,其余依此類推。

    (2)用其他9個桶的信息訓練分類器(第一次迭代中利用從桶2到桶10的信息訓練分類器)。

    (3)利用留存的數據來測試分類器並保存測試結果。在上例中,這些結果可能如下:

    35個籃球運動員被正確分類;

    29個非籃球運動員被正確分類。

  第3步,對上述結果匯總。

  通常情況下我們會將結果放到與下表類似的表格中:

  分成籃球運動員 分成非籃球運動員
實際為籃球運動員 372 128
實際為非籃球運動員 220 280

 

  在所有500名籃球運動員中,有372人被正確分類。可能需要做的一件事是將右下角的數字也加上去,也就是說1000人當中有652(372+280)人被正確分類。因此得到的精確率為65.2%。與2折或3折交叉驗證相比,基於10折交叉驗證得到的結果可能更接近於分類器的真實性能。之所以這樣,是因為每次采用90%而不是2折交叉驗證中僅僅50%的數據來訓練分類器。
 五、Pyton程序

def KFoldCV(D, A, k):
"""
k-fold 交叉驗證

參數說明:
D:給定數據集
A:學習函數
k:折數
"""
np.random.shuffle(D)
dataset = np.split(D, k)
acc_rate = 0
for i in range(k):
train_set = dataset.copy()
test_set = train_set.pop(i)
train_set = np.vstack(train_set)
A.train(train_set[:,:-1], train_set[:,-1]) # 每次的訓練集
labels = A.fit(test_set[:,:-1]) # 每次的測試集
acc_rate += np.mean(labels==test_set[:,-1]) # 計算平均誤差
return acc_rate/k

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM