如何在matlab中随机分割数据为k-folds?

时间:2013-11-05 10:48:01

标签: matlab statistics cross-validation

我有一个数据集,为简单起见,假设它有1000个样本(每个都是一个向量)。

我想分割我的数据用于交叉验证,用于训练和测试,非随机 1 ,所以例如如果我想要4倍交叉验证,我应该得到:

fold1 :train = 1:250; test = 251:1000
fold2 :train = 251:500,test = [1:250; 501:1000]
fold3 :train = 501:750,test = [1:500; 751:1000]
fold4 :train = 751:1000,test = 1:750

我知道CVPARTITION,但AFAIK - 它会随机分割数据 - 这不是我需要的。

我想我可以为它编写代码,但我认为可能有一个我可以使用的函数。


(1)数据已经改组,我需要能够轻松地重现实验。

3 个答案:

答案 0 :(得分:2)

假设您有k*n个问题,您希望将k个样本分为n个样本和(k-1)*n个问题k = 4n = 250)。
然后

 >> foldId = kron( 1:k, ones(1,n) );

foldId为您提供每个样本所属的训练折叠的索引。

对于折叠f,您可以使用

获取训练和测试样本的索引
 >> trainIdx = find( foldId == f );
 >> testIdx  = find( foldId ~= f );

(您可以使用逻辑索引而不是find并加快速度。)

答案 1 :(得分:2)

这是一个通常执行此操作的函数:

function [test, train] = kfolds(data, k)

  n = size(data,1);

  test{k,1} = [];
  train{k,1} = [];

  chunk = floor(n/k);

  test{1} = data(1:chunk,:);
  train{1} = data(chunk+1:end,:);

  for f = 2:k
      test{f} = data((f-1)*chunk+1:(f)*chunk,:);
      train{f} = [data(1:(f-1)*chunk,:); data(f*chunk+1:end, :)];
  end
end

它不是一个优雅的1衬里,但它相当健壮,不需要k成为你的样本数量的因子,在2D矩阵上工作并输出实际集而不是索引。

答案 2 :(得分:1)

要将数据集划分为k长度n的折叠,您可以使用:

f=arrayfun(@(x)struct('train',x*n+(1:n),'test',setdiff(1:n*k,x*n+(1:n))), 0:k-1);

其中f是一个结构数组,其中包含字段traintest,其中包含相应折叠的索引。 例如,n=5k=3以及折叠2

>> f(2).train
ans =
     6     7     8     9    10
>> f(2).test
ans =
     1     2     3     4     5    11    12    13    14    15

您甚至可以直接提取数据。假设您的数据是n*k

的二维矩阵
E=arrayfun(...
@(x) struct('train', D(x*n+(1:n),:), ...
            'test',  D(setdiff(1:n*k, x*n+(1:n)),:)), 0:k-1)

说出你的数据

D = [(1:15).^2; (1:15).^3].';

对于折叠2E包含:

>> E(2).train
ans =
          36         216
          49         343
          64         512
          81         729
         100        1000
>> E(2).test
ans =
           1           1
           4           8
           9          27
          16          64
          25         125
         121        1331
         144        1728
         169        2197
         196        2744
         225        3375