Matlab: 10 fold cross giving same fold over and over - matlab

I have attached the data at the bottom of the question: I have following code that return the 10 fold in a cell, such a way that cell{1,1} consider the training data and cell{1,2} test data but for some reason beyond cell{1,1} which cell{1,2}.... has same data repeating over and over. I am not really sure why its happening. I debug so many rounds and was not able to figure the reason.
Here is the code,
%Function that accept data file as a name and the number of folds
%For the cross fold
function [results_cell] = GetTenFold(dataFile, x)
%loading the data file
dataMatrix = load(dataFile);
%combine the data and labels as one matrix
X = [dataMatrix.data dataMatrix.labels];
%geting the length of the of matrix
dataRowNumber = length(dataMatrix.data);
%shuffle the matrix while keeping rows intact
shuffledMatrix = X(randperm(size(X,1)),:);
crossValidationFolds = x;
%Assinging number of rows per fold
numberOfRowsPerFold = dataRowNumber / crossValidationFolds;
%Assigning 10X2 cell to hold each fold as training and test data
results_cell = cell(10,2);
%starting from the first row and segment it based on folds
i = 1;
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];
i = i + 1;
end
%for i=1:10
results_cell{i,1} = shuffledMatrix(trainRows ,:);
results_cell{i,2} = shuffledMatrix(testRows ,:);
end
end
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
5.4000 3.4000 1.7000 0.2000
5.1000 3.7000 1.5000 0.4000
4.6000 3.6000 1.0000 0.2000
5.1000 3.3000 1.7000 0.5000
4.8000 3.4000 1.9000 0.2000
5.0000 3.0000 1.6000 0.2000
5.0000 3.4000 1.6000 0.4000
5.2000 3.5000 1.5000 0.2000
5.2000 3.4000 1.4000 0.2000
4.7000 3.2000 1.6000 0.2000
4.8000 3.1000 1.6000 0.2000
5.4000 3.4000 1.5000 0.4000
5.2000 4.1000 1.5000 0.1000
5.5000 4.2000 1.4000 0.2000
4.9000 3.1000 1.5000 0.1000
5.0000 3.2000 1.2000 0.2000
5.5000 3.5000 1.3000 0.2000
4.9000 3.1000 1.5000 0.1000
4.4000 3.0000 1.3000 0.2000
5.1000 3.4000 1.5000 0.2000
5.0000 3.5000 1.3000 0.3000
4.5000 2.3000 1.3000 0.3000
4.4000 3.2000 1.3000 0.2000
5.0000 3.5000 1.6000 0.6000
5.1000 3.8000 1.9000 0.4000
4.8000 3.0000 1.4000 0.3000
5.1000 3.8000 1.6000 0.2000
4.6000 3.2000 1.4000 0.2000
5.3000 3.7000 1.5000 0.2000
5.0000 3.3000 1.4000 0.2000
7.0000 3.2000 4.7000 1.4000
6.4000 3.2000 4.5000 1.5000
6.9000 3.1000 4.9000 1.5000
5.5000 2.3000 4.0000 1.3000
6.5000 2.8000 4.6000 1.5000
5.7000 2.8000 4.5000 1.3000
6.3000 3.3000 4.7000 1.6000
4.9000 2.4000 3.3000 1.0000
6.6000 2.9000 4.6000 1.3000
5.2000 2.7000 3.9000 1.4000
5.0000 2.0000 3.5000 1.0000
5.9000 3.0000 4.2000 1.5000
6.0000 2.2000 4.0000 1.0000
6.1000 2.9000 4.7000 1.4000
5.6000 2.9000 3.6000 1.3000
6.7000 3.1000 4.4000 1.4000
5.6000 3.0000 4.5000 1.5000
5.8000 2.7000 4.1000 1.0000
6.2000 2.2000 4.5000 1.5000
5.6000 2.5000 3.9000 1.1000
5.9000 3.2000 4.8000 1.8000
6.1000 2.8000 4.0000 1.3000
6.3000 2.5000 4.9000 1.5000
6.1000 2.8000 4.7000 1.2000
6.4000 2.9000 4.3000 1.3000
6.6000 3.0000 4.4000 1.4000
6.8000 2.8000 4.8000 1.4000
6.7000 3.0000 5.0000 1.7000
6.0000 2.9000 4.5000 1.5000
5.7000 2.6000 3.5000 1.0000
5.5000 2.4000 3.8000 1.1000
5.5000 2.4000 3.7000 1.0000
5.8000 2.7000 3.9000 1.2000
6.0000 2.7000 5.1000 1.6000
5.4000 3.0000 4.5000 1.5000
6.0000 3.4000 4.5000 1.6000
6.7000 3.1000 4.7000 1.5000
6.3000 2.3000 4.4000 1.3000
5.6000 3.0000 4.1000 1.3000
5.5000 2.5000 4.0000 1.3000
5.5000 2.6000 4.4000 1.2000
6.1000 3.0000 4.6000 1.4000
5.8000 2.6000 4.0000 1.2000
5.0000 2.3000 3.3000 1.0000
5.6000 2.7000 4.2000 1.3000
5.7000 3.0000 4.2000 1.2000
5.7000 2.9000 4.2000 1.3000
6.2000 2.9000 4.3000 1.3000
5.1000 2.5000 3.0000 1.1000
5.7000 2.8000 4.1000 1.3000
6.3000 3.3000 6.0000 2.5000
5.8000 2.7000 5.1000 1.9000
7.1000 3.0000 5.9000 2.1000
6.3000 2.9000 5.6000 1.8000
6.5000 3.0000 5.8000 2.2000
7.6000 3.0000 6.6000 2.1000
4.9000 2.5000 4.5000 1.7000
7.3000 2.9000 6.3000 1.8000
6.7000 2.5000 5.8000 1.8000
7.2000 3.6000 6.1000 2.5000
6.5000 3.2000 5.1000 2.0000
6.4000 2.7000 5.3000 1.9000
6.8000 3.0000 5.5000 2.1000
5.7000 2.5000 5.0000 2.0000
5.8000 2.8000 5.1000 2.4000
6.4000 3.2000 5.3000 2.3000
6.5000 3.0000 5.5000 1.8000
7.7000 3.8000 6.7000 2.2000
7.7000 2.6000 6.9000 2.3000
6.0000 2.2000 5.0000 1.5000
6.9000 3.2000 5.7000 2.3000
5.6000 2.8000 4.9000 2.0000
7.7000 2.8000 6.7000 2.0000
6.3000 2.7000 4.9000 1.8000
6.7000 3.3000 5.7000 2.1000
7.2000 3.2000 6.0000 1.8000
6.2000 2.8000 4.8000 1.8000
6.1000 3.0000 4.9000 1.8000
6.4000 2.8000 5.6000 2.1000
7.2000 3.0000 5.8000 1.6000
7.4000 2.8000 6.1000 1.9000
7.9000 3.8000 6.4000 2.0000
6.4000 2.8000 5.6000 2.2000
6.3000 2.8000 5.1000 1.5000
6.1000 2.6000 5.6000 1.4000
7.7000 3.0000 6.1000 2.3000
6.3000 3.4000 5.6000 2.4000
6.4000 3.1000 5.5000 1.8000
6.0000 3.0000 4.8000 1.8000
6.9000 3.1000 5.4000 2.1000
6.7000 3.1000 5.6000 2.4000
6.9000 3.1000 5.1000 2.3000
5.8000 2.7000 5.1000 1.9000
6.8000 3.2000 5.9000 2.3000
6.7000 3.3000 5.7000 2.5000
6.7000 3.0000 5.2000 2.3000
6.3000 2.5000 5.0000 1.9000
6.5000 3.0000 5.2000 2.0000
6.2000 3.4000 5.4000 2.3000
5.9000 3.0000 5.1000 1.8000
labels =
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3

Related

Find the closest value in each group in a matrix column

This is another operation based on the same matrix data, as I talked about in the previous question. I have a matrix as below.
a = [1.05 2.1 3.4 1; 1.06 2.2 3.6 1; 2.04 2.3 3.8 2; 2.15 2.2 4.0 2; 1.37 2.3 3.7 1;3.12 2.1 4.1 3;3.02 2.2 4.2 3;3.42 2.3 4.5 3;3.24 2.4 4.8 3]
a =
1.0500 2.1000 3.4000 1.0000
1.0600 2.2000 3.6000 1.0000
2.0400 2.3000 3.8000 2.0000
2.1500 2.2000 4.0000 2.0000
1.3700 2.3000 3.7000 1.0000
3.1200 2.1000 4.1000 3.0000
3.0200 2.2000 4.2000 3.0000
3.4200 2.3000 4.5000 3.0000
3.2400 2.4000 4.8000 3.0000
a(:,4) is group numbers. Based on group numbers, I split the matrix data into 3 groups: 1, 2 and 3.
I would like to find the index of value closest to 2.2 in a(:,2) in each group. From the data you can see, there is a 2.2 in row 2 belong to group 1, a 2.2 in row 4 belong to group 2, and a 2.2 in row 7 belong to group 3.
My code is shown as below:
[minValue,closestIndex] = splitapply(#(x)min(abs(2.2-x)), a(:,2), findgroups(a(:,4)))
The outcome is:
minValue =
0
0
0
This is consistent as we can find from the data.
closestIndex =
2
2
2
This is supposed to be the indexes of three 2.2 in the matrix, which should be 2, 4 and 7. But the outcome is 2, 2 and 2.
What is wrong with my code?
How to solve this problem?
I think you misunderstand how this function works. It split your initial setup:
a =
1.0500 2.1000 3.4000 1.0000
1.0600 2.2000 3.6000 1.0000
2.0400 2.3000 3.8000 2.0000
2.1500 2.2000 4.0000 2.0000
1.3700 2.3000 3.7000 1.0000
3.1200 2.1000 4.1000 3.0000
3.0200 2.2000 4.2000 3.0000
3.4200 2.3000 4.5000 3.0000
3.2400 2.4000 4.8000 3.0000
to
x1=
1.0500 2.1000 3.4000 1.0000
1.0600 2.2000 3.6000 1.0000 (index = 2)
1.3700 2.3000 3.7000 1.0000
x2=
2.0400 2.3000 3.8000 2.0000
2.1500 2.2000 4.0000 2.0000 (index = 2)
x3=
3.1200 2.1000 4.1000 3.0000
3.0200 2.2000 4.2000 3.0000 (index = 2)
3.4200 2.3000 4.5000 3.0000
3.2400 2.4000 4.8000 3.0000
The indexes are examined separately so indeed - 2,2,2 is correct answer for this query. According to the documentation "The splitapply function calls func once per group" so there is not simple possibility to obtain indexes from initial matrix directly. Maybe you can workaround it by adding another column like 1 2 3 4 5 6 7 8 9 and store the number from it or something in this way but it is not so elegant and would require quite complicated func.

create a 3D scatter in matlab and connect groups of scattered points, with coloured lines

I have this matrix that is ready to be plotted in "Matlab" with scatter3, if the following command is used
scatter3( F(:,[1]) , F(:,[2]) , F(:,[3]) , F(:,[4]) , F(:,[5]) )
(I am basically splitting the F matrix in 5 column vectors)
F =
52.5000 12.6000 288.0000 20.0000 1.0000
52.5000 6.3000 408.0000 20.0000 1.0000
52.5000 4.8000 467.0000 20.0000 1.0000
52.5000 3.5000 559.0000 20.0000 1.0000
52.5000 2.0000 730.0000 20.0000 1.0000
52.5000 1.3000 902.0000 20.0000 1.0000
26.2500 12.6000 203.0000 20.0000 2.0000
26.2500 6.3000 288.0000 20.0000 2.0000
26.2500 4.8000 332.0000 20.0000 2.0000
26.2500 3.5000 389.0000 20.0000 2.0000
26.2500 2.0000 516.0000 20.0000 2.0000
26.2500 1.3000 637.0000 20.0000 2.0000
10.0000 12.6000 125.0000 20.0000 3.0000
10.0000 6.3000 177.0000 20.0000 3.0000
10.0000 4.8000 204.0000 20.0000 3.0000
10.0000 3.5000 240.0000 20.0000 3.0000
10.0000 2.0000 318.0000 20.0000 3.0000
10.0000 1.3000 392.0000 20.0000 3.0000
5.0000 12.6000 88.0000 20.0000 4.0000
5.0000 6.3000 125.0000 20.0000 4.0000
5.0000 4.8000 144.0000 20.0000 4.0000
5.0000 3.5000 169.0000 20.0000 4.0000
5.0000 2.0000 224.0000 20.0000 4.0000
5.0000 1.3000 277.0000 20.0000 4.0000
2.0000 12.6000 55.0000 20.0000 5.0000
2.0000 6.3000 78.0000 20.0000 5.0000
2.0000 4.8000 90.0000 20.0000 5.0000
2.0000 3.5000 106.0000 20.0000 5.0000
2.0000 2.0000 141.0000 20.0000 5.0000
2.0000 1.3000 175.0000 20.0000 5.0000
1.0000 6.3000 55.0000 20.0000 6.0000
1.0000 4.8000 63.0000 20.0000 6.0000
1.0000 3.5000 75.0000 20.0000 6.0000
1.0000 2.0000 99.0000 20.0000 6.0000
1.0000 1.3000 123.0000 20.0000 6.0000
0.5000 6.3000 38.0000 20.0000 7.0000
0.5000 4.8000 44.0000 20.0000 7.0000
0.5000 3.5000 52.0000 20.0000 7.0000
0.5000 2.0000 70.0000 20.0000 7.0000
0.5000 1.3000 86.0000 20.0000 7.0000
If you plot this you'll see that the points are grouped in 7 same coloured groups (taken from column 5 of the F matrix).
I would like to plot lines connecting the same coloured points. Of course the lines should have the same colour as the points they connect.
I have attempted to split the F matrix in five 6x5 matrices (named F1-F5) and 2 5x5 matrices (named F6 and F7) and use scatter3() along with line() commands and hold on to create my 3D graph, but it did not do what I wanted.
For every new set of points that is plotted with scatter3() the sets of points already plotted change colour. So assigning a short name colour in the line() function does not help.
What options do I have? Perhaps scatter3 is not the best function to use in this case?
EDIT
plot3() is promising , but has a limited color set. Indeed I would prefer to avoid using colours "white" and "yellow", which do not show up nice on white background.
So, I will assume you are going to separate your matrices into 7, in this case, and save them in a cell array, as dynamic variables are BAD!
Assuming you have a cell array called F this works:
C=hsv(7);
hold on
for ii=1:size(F,2)
% //plot lines
plot3(F{ii}(:,1),F{ii}(:,2),F{ii}(:,3),'Color',C(ii,:));
% // plot points
plot3(F{ii}(:,1),F{ii}(:,2),F{ii}(:,3),'.','MarkerSize',F{ii}(1,4),'Color',C(ii,:));
end
The only problem it has is that it doesnt allow for multiple marker sizes, so if you want the points to have different marker sizes, you'd need to add another loop and go plotting the points one by one. I hope you are able to get it from here ;)

How do I append elements to a matrix using a for loop?

I have following data matrix, I want to iterate over this matrix and look at a value in the last column based on a given row and add that row - last element of that row to a new matrix.
5.1000 3.3000 1.7000 0.5000 1.0000
6.8000 3.2000 5.9000 2.3000 3.0000
5.0000 2.3000 3.3000 1.0000 2.0000
7.4000 2.8000 6.1000 1.9000 3.0000
6.5000 3.2000 5.1000 2.0000 3.0000
4.8000 3.4000 1.9000 0.2000 1.0000
4.9000 3.0000 1.4000 0.2000 1.0000
5.1000 3.8000 1.5000 0.3000 1.0000
5.1000 3.4000 1.5000 0.2000 1.0000
5.5000 2.6000 4.4000 1.2000 2.0000
This is the code that I have
M1 = [];
M2 = [];
M3 = [];
for i=1:length(currentCell)
if currentCell(1,5) == 1.00
m3Data = currentCell(1:1,1:4);
%how can I add m3Data to M1
end
end
Let your original matrix be M, then this
M1 = M(find(M(:,5)==1),1:4)
puts all the rows ending with a 1 into M1, excluding the final column. Is that what you want ?
You could do it with a for loop if you want, but I don't see any need.

extracting variable from multiple matlab files into one file

I have this project task, and I'm having problems solving it.
I took samples of the words from 1 to 10 spoken by 10 people.
From each sample I extracted each word e.g, I extracted the word 1 from all samples into different files. I now have 10 files each having the extracted first word. I want to combine these into one single array.
file = wavread( 'G:\Segmented Data\amir.wav');
t = linspace(0,8,length(file));
t2=linspace(0,.8,8820);
section1 = file(1:8820,:);
sound(section1, 11025);
figure(1),
plot(t2,section1);
I have 10 files having the above code. I want to extract the variable section from all these into a new file, and store them in an array.
Do you want to concatenate arrays?
>> a = 1.0:0.1:1.9 % your data, obtained from `wavread()`
a =
1.0000 1.1000 1.2000 1.3000 1.4000 1.5000 1.6000 1.7000 1.8000 1.9000
>> b = 2.0:0.1:2.9 % your data, obtained from `wavread()`
b =
2.0000 2.1000 2.2000 2.3000 2.4000 2.5000 2.6000 2.7000 2.8000 2.9000
>> c = 3.0:0.1:3.9 % your data, obtained from `wavread()`
c =
3.0000 3.1000 3.2000 3.3000 3.4000 3.5000 3.6000 3.7000 3.8000 3.9000
>> combined = [a; b; c] % a, b, and c in one array
combined =
1.0000 1.1000 1.2000 1.3000 1.4000 1.5000 1.6000 1.7000 1.8000 1.9000
2.0000 2.1000 2.2000 2.3000 2.4000 2.5000 2.6000 2.7000 2.8000 2.9000
3.0000 3.1000 3.2000 3.3000 3.4000 3.5000 3.6000 3.7000 3.8000 3.9000
This will, of course, only work if a, b and c are the same number of columns wide. If they are different sizes, you will have to pad them out with zeros so that they are the same size.

Is there a way to do partial average over matrix in matlab

I have a matrix (table actually) which I imported from a file:
1.0000 1.9736
4.0000 0.2016
9.0000 0.0584
10.0000 0.0495
5.0000 0.1845
2.0000 0.6873
1.0000 1.4177
2.0000 0.4699
5.0000 0.1555
10.0000 0.0435
13.0000 0.0326
8.0000 0.0860
5.0000 0.1685
4.0000 0.1956
5.0000 0.1433
8.0000 0.0675
13.0000 0.0335
13.0000 0.0327
10.0000 0.0431
9.0000 0.0582
10.0000 0.0551
13.0000 0.0308
I want to get the average of each of the occurance on left column. That is:
avg = [
1.0000 1.69565
2.0000 0.5786
4.0000 0.1978]
and so on. I could do this with a wile or for group but this is not the matlab way. So how can I do this?
a=[randi(5,10,1) rand(10,1)];
a =
4.0000 0.4387
1.0000 0.3816
2.0000 0.7655
1.0000 0.7952
1.0000 0.1869
5.0000 0.4898
4.0000 0.4456
2.0000 0.6463
5.0000 0.7094
1.0000 0.7547
[uniqueID,~,uniqueInd]=unique(a(:,1));
[uniqueID accumarray(uniqueInd,a(:,2))./accumarray(uniqueInd,1)]
ans =
1.0000 0.5296
2.0000 0.7059
4.0000 0.4422
5.0000 0.5996
If your matrix is called a, try
>> accumarray(grp2idx(a(:,1)),a(:,2),[],#mean)
ans =
1.6957
0.5786
0.1986
0.16295
0.07675
0.0583
0.0478
0.0324
Note that grp2idx is part of Statistics Toolbox. If you don't have that, you can use the unique command to get the same results.