我有一个矩阵(我想在MatLab中你称之为结构)或数据结构:
data: [150x4 double]
labels: [150x1 double]
这是我的matrix.data看起来像假设我加载我的文件名称为矩阵:
5.1000 3.5000 1.4000 0.2000
4.9000 3.0000 1.4000 0.2000
4.7000 3.2000 1.3000 0.2000
4.6000 3.1000 1.5000 0.2000
5.0000 3.6000 1.4000 0.2000
5.4000 3.9000 1.7000 0.4000
4.6000 3.4000 1.4000 0.3000
5.0000 3.4000 1.5000 0.2000
4.4000 2.9000 1.4000 0.2000
4.9000 3.1000 1.5000 0.1000
5.4000 3.7000 1.5000 0.2000
4.8000 3.4000 1.6000 0.2000
4.8000 3.0000 1.4000 0.1000
4.3000 3.0000 1.1000 0.1000
5.8000 4.0000 1.2000 0.2000
5.7000 4.4000 1.5000 0.4000
5.4000 3.9000 1.3000 0.4000
5.1000 3.5000 1.4000 0.3000
5.7000 3.8000 1.7000 0.3000
5.1000 3.8000 1.5000 0.3000
这是我的matrix.labels看起来像
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
我正在尝试创建10个交叉折叠验证而不使用MatLab中的任何现有函数,并且由于我非常有限的MatLab知识,我无法继续使用我的内容。任何帮助都会很棒。
这是我到目前为止所做的,我相信这可能不是matlab方式,但我对matlab很新。
function[output] = fisher(dataFile, number_of_folds)
data = load(dataFile);
%create random permutation indx
idx = randperm(150);
output = data.data(idx(1:15),:);
end
答案 0 :(得分:5)
以下是我对此交叉验证的看法。我使用魔法创建虚拟数据(10)我也随机创建标签。想法如下,我们得到我们的数据和标签,并将它们与随机列结合起来。考虑遵循虚拟代码。
>> data = magic(4)
data =
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
>> dataRowNumber = size(data,1)
dataRowNumber =
4
>> randomColumn = rand(dataRowNumber,1)
randomColumn =
0.8147
0.9058
0.1270
0.9134
>> X = [ randomColumn data]
X =
0.8147 16.0000 2.0000 3.0000 13.0000
0.9058 5.0000 11.0000 10.0000 8.0000
0.1270 9.0000 7.0000 6.0000 12.0000
0.9134 4.0000 14.0000 15.0000 1.0000
如果我们根据第1列对X进行排序,我们会随机对数据进行排序。这将给我们交叉验证随机性。然后接下来就是根据交叉验证百分比划分X.一个案例很容易实现这一点。让我们考虑%75%是火车案例,%25%是测试案例。我们这里的大小是4,然后3/4 =%75和1/4是%25。
testDataset = X(1,:)
trainDataset = X(2:4,:)
但是对于N交叉褶皱来说,实现这一点要困难得多。因为我们需要做N次。对于循环是必要的。适用于5个交叉折叠。我得到了,在第一个f
以下代码是此过程的示例:
data = magic(10);
dataRowNumber = size(data,1);
labels= rand(dataRowNumber,1) > 0.5;
randomColumn = rand(dataRowNumber,1);
X = [ randomColumn data labels];
SortedData = sort(X,1);
crossValidationFolds = 5;
numberOfRowsPerFold = dataRowNumber / crossValidationFolds;
crossValidationTrainData = [];
crossValidationTestData = [];
for startOfRow = 1:numberOfRowsPerFold:dataRowNumber
testRows = startOfRow:startOfRow+numberOfRowsPerFold-1;
if (startOfRow == 1)
trainRows = [max(testRows)+1:dataRowNumber];
else
trainRows = [1:startOfRow-1 max(testRows)+1:dataRowNumber];
end
crossValidationTrainData = [crossValidationTrainData ; SortedData(trainRows ,:)];
crossValidationTestData = [crossValidationTestData ;SortedData(testRows ,:)];
end
答案 1 :(得分:3)
index = 1; subsample = 1; newmat = zeros("150","6")
< 150是样本数,6 = 4宽数据+ 1宽标签+ 1我们稍后将使用while ( length(labels) > 0 )
randNum = randi(length(labels))
?我认为这是一个随机的int,从1到你的标签数组的大小(它可能是0,请检查文档 - 如果是,做简单的数学使它1< rand< length)newmat(index,:) = [data(randNum,:) labels(randNum) subsample]
<最后一列是1-10 data(randNum,:) = []; same for labels
<请注意,这将从矩阵中物理删除一行,这就是为什么我们必须使用while循环并检查长度> 0而不是for循环和简单索引index = index + 1; subsample = subsample + 1;
最后,您应该拥有一个看起来几乎与原始数据完全相同的大型数据矩阵,但随机分配了“折叠标签”。
编辑:以更易于访问的方式放置代码。注意它仍然是伪代码,并且不完整!此外,您应该注意,这不是最有效的方法,但如果您不能使用matlab函数,那么不应该太糟糕。
for k = 1:10
index = 1; subsample = 1; newmat = zeros("150","6");
while ( length(labels) > 0 )
randNum = randi(length(labels));
newmat(index,:) = [data(randNum,:) labels(randNum) subsample];
data(randNum,:) = []; same for labels
index = index + 1; subsample = subsample + 1;
if ( subsample == 11 )
subsample = 1;
end
end
% newmat is complete, now run code here using the sampled data
%(ie pick a random number from 1:10 and use that as your validation fold. the rest for training
end
编辑答案#2:
另一种方法是创建一个与数据集一样长的载体
foldLabels = zeros("150",1);
然后,循环那么长(150),为随机索引分配标签!
foldL = 1;
numAssigned = 0;
while ( numAssigned < 150 )
idx = randi(150);
% no need to reassign a given label, so check if is still 0
if ( foldLabels(idx) == 0 )
foldLabels(idx) = foldL;
numAssigned++; % not matlab code, just got lazy. you get it
foldL++;
if ( foldL > 10 )
foldL = 1;
end
end
end
编辑答案#2.5
foldLabels = zeros("150",1);
for i = 1:150
notChosenLabels = [notChosenLabels i];
end
foldL = 1;
numAssigned = 0;
while ( length(notChosenLabels) > 0 )
labIdx = randi(length(notChosenLabels));
idx = notChosenLabels(labIdx);
foldLabels(idx) = foldL;
numAssigned++; % not matlab code, just got lazy. you get it
foldL++;
if ( foldL > 10 )
foldL = 1;
end
notChosenLabels(labIdx) = [];
end
编辑RANDPERM
用randperm
生成索引idxs = randperm(150);
现在只需分配
foldLabels = zeros(150,1);
for i = 1:150
foldLabels(idxs(i)) = sampleLabel;
sampleLabel = sampleLabel + 1;
if ( sampleLabel > 10 )
sampleLabel = 1;
end
end