機器學習:模型評估與選擇-數據集劃分(附代碼實現)

通過學習得到的一個學習器,我們要知道它的泛化性能,即面對新的數據,算法產生的結果好不好。顯然,我們不能用使用過的數據進行評估。所以,對於手裏有限的數據集,我們要進行劃分,劃分爲訓練集和測試集,測試樣本儘量不在訓練集中出現,訓練集用來訓練模型,測試集用來評估模型的性能。這裏介紹3種劃分方法。

1、留出法

數據集D劃分爲訓練集S和測試集T,D=S並T,S交T=空集。如1000個數據集,500個正樣本,500個負樣本,700個作爲訓練集(350個正樣本,350個負樣本),300個作爲測試集(150個正樣本,150個負樣本),注意數據劃分時數據分佈儘量一致,例如在分類任務中,樣本的類別比例相似。不同的劃分,模型評估的結果也會有差別,所以一般會進行若干次隨機劃分,最後取平均值。

2、交叉驗證法

如把數據集劃分爲10個大小相似的互斥子集,每次用9個作爲訓練集,剩下的1個作爲測試集,則可以進行10次訓練和測試,最後返回10次測試結果的均值,稱爲10折交叉驗證。爲減小樣本的不同劃分引入的差別,通常隨機使用不同劃分重複p次,如10次,則可稱爲“10次10折交叉驗證”。

3、自助法(改變了初始數據集的分佈,會引入估計偏差)

每次從數據集D中挑選一個樣本拷貝進D',然後將該樣本放回D中,在下次採樣仍然可能被採樣到。重複執行m次則得到包含m個樣本的數據集D',樣本在m次採樣中始終不被採樣到的概率爲(1-1/m)^m,取極值得1/e,約爲0.368,即D中約有36.8%的樣本未出現在採樣集D'中,我們可將D'作爲訓練集,D-D'作爲測試集。

自助法在數據集較小時比較有用,數據集足夠時,留出法和交叉驗證法更常用

交叉驗證法代碼(含留一法,即N個樣本進行N折交叉驗證):

%留一法
if k==x1_rows+x2_rows,
  x = [x1;x2];
  y = [y1;y2];
  for i=1:k,
    %留一的放回
    if length(x_test)>0&&length(y_test)>0,
      x = [x;x_test];
      y = [y;y_test];
    end;
    
    %留一
    x_test = x(1,:);
    y_test = y(1);
    %訓練集
    x(1,:) = [];
    y(1) = [];
    
    [w L] = logisticFunc(x,y,iters,lambda);
    
    
    p0 = 1/(1+exp(x_test*w));
    p(i) = p0;
    if (y_test==0&&p0<=0.5)||(y_test==1&&p0>=0.5),
      error_num = error_num+1;
    end;
  end;
  error = error_num/k;
else%k折
  
  x1_test = [];
  x2_test = [];
  y1_test = [];
  y2_test = [];
  
  x1_num = floor(x1_rows/k);%向下取整,2.5取2
  x2_num = floor(x2_rows/k);
  
  for i=1:k,
    
    %測試集放回
    if length(x_test)>0&&length(y_test)>0,
      x1 = [x1;x1_test];
      x2 = [x2;x2_test];
      y1 = [y1;y1_test];
      y2 = [y2;y2_test];
    end;
    
    %最後一組取剩下的全部數據
    if i==k,
      x1_num = x1_rows - x1_num*(k-1);
      x2_num = x2_rows - x2_num*(k-1);
    end;
    
    %測試集
    x1_test = x1(1:x1_num,:);
    y1_test = y1(1:x1_num,1);
    x2_test = x2(1:x2_num,:);
    y2_test = y2(1:x2_num,1);
    
    x_test = [x1_test;x2_test];
    y_test = [y1_test;y2_test];
    
    %訓練集
    x1(1:x1_num,:) = [];
    y1(1:x1_num) = [];
    x2(1:x2_num,:) = [];
    y2(1:x2_num) = [];
    
    x = [x1;x2];
    y = [y1;y2];
    
    [w L] = logisticFunc(x,y,iters,lambda);
    
    p0 = 1./(1+exp(x_test*w));
    
    error_num = 0;
    for j=1:length(y_test),
      if (y_test(j)==0 && p0(j)<=0.5)||(y_test(j)==1&&p0(j)>=0.5),
        error_num = error_num + 1;
      end;
    end;
    %error_num
    error = error + error_num/length(y_test);
    
  end;
  
  error = error/k;
end;
微信交流
多謝打賞

參考資料:周志華《機器學習》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章