首页 文章

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

提问于
浏览
2

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

我想分割我的数据用于交叉验证,用于训练和测试,例如,如果我想要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 回答

  • 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
    

    它相当健壮,不需要 k 作为您的样本数量的因子,在2D矩阵上工作并输出实际集而不是索引 .

  • 1

    假设你有 k*n smaples,你想用火箭中的 n 样本和测试中的 (k-1)*n 分割 k 折叠(在你的问题 k = 4n = 250 中) .
    然后

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

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

    对于折叠 f ,您可以使用获得训练和测试样本的索引

    >> trainIdx = find( foldId == f );
     >> testIdx  = find( foldId ~= f );
    

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

  • 2

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

    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 行的2D矩阵

    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
    

相关问题