我有一个数据集,为简单起见,假设它有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)数据已经改组,我需要能够轻松地重现实验。
答案 0 :(得分:2)
假设您有k*n
个问题,您希望将k
个样本分为n
个样本和(k-1)*n
个问题k = 4
, n = 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
是一个结构数组,其中包含字段train
和test
,其中包含相应折叠的索引。
例如,n=5
和k=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].';
对于折叠2
,E
包含:
>> 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