Precision Function Numeric Variable Error in R - neural-network

I am currently working on Neural Networks and for some odd reason I am getting a random error saying that the results need to be numeric when passing them to the precision function as it can be seen below.
Code Snippet:
originalValues <- max.col(dataTest[,11:15])
originalValues
predictedValues <- max.col(predictedResult)
predictedValues
CrossTable(originalValues, predictedValues, prop.r = FALSE, prop.c = FALSE, prop.t = FALSE,
prop.chisq = FALSE)
originalValues
predictedValues
Accuracy(originalValues, predictedValues)
Precision(originalValues, predictedValues)
Recall(originalValues, predictedValues)
When running this code for some reason the Accuracy function is working and the Precision and Recall functions are working strange as seen below.
Result:
> originalValues
[1] 1 1 1 1 1 2 2 3 3 3 4 4 4 4 4 5 5 5
> predictedValues
[1] 2 2 2 2 2 2 2 3 3 3 5 5 5 5 5 5 5 5
> Accuracy(originalValues, predictedValues)
[1] 0.4444444
> Precision(originalValues, predictedValues)
Error in FUN(X[[i]], ...) :
only defined on a data frame with all numeric variables
> Recall(originalValues, predictedValues)
[1] NA

Related

What algorithm is used when rows in tables are sorted?

Let's assume that we have a table with two columns. The table contains data and our goal is to sort that table.
Assume our data looks like this, where y1 and y2 are the data in the columns.
You can produce that plot with MATLAB or GNU Octave.
% Simulate the model
[t,y] = ode45(#odefunc,[0 20],[1; -2]);
% Plot the simulation
close all
plot(t,y(:,1),'-r',t,y(:,2),'-b')
title('Solution of van der Pol Equation (\mu = 1) with ODE45');
xlabel('Time t');
ylabel('Solution y');
legend('y_1','y_2')
grid on
function dydt = odefunc(t,y)
dydt = [y(2); (1-0.1*y(1)^2)*y(2)-y(1) + 1];
end
If we look above the plot, we are going to se the data like this:
You can create that plot with this code:
% Plot 3D bar
figure
imagesc(y)
colorbar
Here we can see that the plot have a very much like a "table-look". My question is what algorithm is used when sorting the rows in the table so every row that looks almost the same, have it's own unique position in the table.
For example, if we have a table like this.
0 2 4
1 3 5
2 4 6
3 5 7
4 6 8
5 7 9
0 2 4
1 3 5
2 4 6
3 5 7
4 6 8
5 7 9
0 2 4
1 3 5
2 4 6
3 5 7
4 6 8
5 7 9
0 2 4
1 3 5
The code if you want to create that table.
j = 0;
rows = 20;
for i = 1:rows
disp(sprintf("%i %i %i", j, j+2, j+4))
j = j + 1;
if(j + 4 >= 10)
j = 0;
end
end
We can see that there are four rows of 0 2 4 and three rows of 5 7 9.
I want all rows 0 2 4 close to each other and all rows 5 7 9 close to each other. And.... 0 2 4 cannot be after 5 7 9 because then the plot would look terrible.
For example, assume that we begining with row 1, the first row 0 2 4. Then we are looking for the same rows of 0 2 4 and let's say we found four rows 0 2 4. Then we sort them.
0 2 4
0 2 4
0 2 4
0 2 4
Now next row would be 1 3 5 and we find two rows of 1 3 5. We sorting them.
0 2 4
0 2 4
0 2 4
0 2 4
1 3 5
1 3 5
After we have sorted for a while, we are going to have a table like this.
0 2 4
0 2 4
0 2 4
0 2 4
1 3 5
1 3 5
2 4 6
2 4 6
2 4 6
2 4 6
3 5 7
3 5 7
3 5 7
.
.
.
.
5 7 9
5 7 9
5 7 9
And now, we found 1 2 4, which is very similar to 0 2 4. So we need to place 1 2 4 close to 0 2 4, perhaps between 0 2 4 or 1 3 5 or after 0 2 4 or before 0 2 4. How do I even know that 1 2 4 should be placed close to 0 2 4? That's the issue!!!.
How can I sort that?
I need to do that in C-programming language because speed is most important here, but I think I will start to do it in GNU Octave. I'm pretty sure that there is a SQL-sorting algorithm I'm looking for.
Notice in practice, there are numbers, integers, 10-bit e.g values between 0-1023.

Nested loop and conditional statement (Matlab)

If you have a random matrix, for example a 5x5:
A(i,j) = (5 4 3 2 1
4 3 2 1 0
5 4 3 2 1
4 3 2 1 0
5 4 3 2 1)
And a second array:
B(1,j) = (4 5 6 7 8)
How can I then assign values of B to A if this only needs to be done when the value of B(1,j) is larger than any of the values from a certain colomn of A?
For example, B(1,1) = 4 and in the first colomn of A it is larger than A(1,1), A(3,1) and A(5,1), so these must be replaced by 4. In the second colomn, nothing needs to be replaced, etc.
Thanks already!
You can do this without any explicit looping using bsxfun:
A = [5 4 3 2 1
4 3 2 1 0
5 4 3 2 1
4 3 2 1 0
5 4 3 2 1];
B = [4 5 6 7 8];
A = bsxfun(#min,A,B);
Result:
A =
4 4 3 2 1
4 3 2 1 0
4 4 3 2 1
4 3 2 1 0
4 4 3 2 1
In later versions of MATLAB (2016b and later) you can even omit the bsxfun and get the same result.
A = min(A,B);
Matlab "find" may be of use to you.
https://www.mathworks.com/help/matlab/matlab_prog/find-array-elements-that-meet-a-condition.html
If you aren't concerned about speed or efficiency, you could also set up a two nested for loops with a condition (i.e. an if) statement comparing the values of A and B.
If you only interested in column wise comparison to B, you could use the increment of the outer loop in the inner loop.
for i,...
for j,...
if B(1,i) > A(j,i)
A(j,i)=B(i,j)

MATLAB - Frequency of an array element with a condition

I need some help please. I have an array, as shown below, 6 rows and 5 columns, none of the elements in any one row repeats. The elements are all single digit numbers.
I want to find out, per row, when a number, let's say 1 appears, I want to keep of how often the other numbers of the row appear. For example, 1 shows up 3 times in rows one, three and five. When 1 shows up, 2 shows up one time, 3 shows up two times, 4 shows up two times, 5 shows up one time, 6 shows up two times, 7 shows up one time, 8 shows up three times, and 9 shows up zero times. I want to keep a vector of this information that will look like, V = [3,1,2,2,1,2,1,3,0], by starting with a vector like N = [1,2,3,4,5,6,7,8,9]
ARRAY =
1 5 8 2 6
2 3 4 6 7
3 1 8 7 4
6 5 7 9 4
1 4 3 8 6
5 7 8 9 6
The code I have below does not give the feedback I am looking for, can someone help please? Thanks
for i=1:length(ARRAY)
for j=1:length(N)
ARRAY(i,:)==j
V(j) = sum(j)
end
end
Using indices that is in A creae a zero and one 6 * 9 matrix that [i,j] th element of it is 1 if i th row of A contains j.
Then multiply the zero and one matrix with its transpose to get desirable result:
A =[...
1 5 8 2 6
2 3 4 6 7
3 1 8 7 4
6 5 7 9 4
1 4 3 8 6
5 7 8 9 6]
% create a matrix with the size of A that each row contains the row number
rowidx = repmat((1 : size(A,1)).' , 1 , size(A , 2))
% z_o a zero and one 6 * 9 matrix that [i,j] th element of it is 1 if i th row of A contains j
z_o = full(sparse(rowidx , A, 1))
% matrix multiplication with its transpose to create desirable result. each column relates to number N
out = z_o.' * z_o
Result: each column relates to N
3 1 2 2 1 2 1 3 0
1 2 1 1 1 2 1 1 0
2 1 3 3 0 2 2 2 0
2 1 3 4 1 3 3 2 1
1 1 0 1 3 3 2 2 2
2 2 2 3 3 5 3 3 2
1 1 2 3 2 3 4 2 2
3 1 2 2 2 3 2 4 1
0 0 0 1 2 2 2 1 2
I don't understand how you are approaching the problem with your sample code but here is something that should work. This uses find, any and accumarray and in each iteration for the loop it will return a V corresponding to the ith element in N
for i=1:length(N)
rowIdx = find(any(A == N(i),2)); % Find all the rows contain N(j)
A_red = A(rowIdx,:); % Get only those rows
V = [accumarray(A_red(:),1)]'; % Count occurrences of the 9 numbers
V(end+1:9) = 0; % If some numbers don't exist place zeros on their counts
end

Matlab(the same cell in different matrix)

I have two matrix A and B. Suppose I would like to find in each row of matrix A the smallest number, and for the same cell that this number is in Matrix A, do find the corresponding number of the same cell in matrix B. For example the number in matrix A will be in the position A(1,3), A(2,9)...and I want the corresponding number in B(1,3), B(2,9)... Is it possible to do it, or I am asking something hard for matlab. Hope someone will help me.
What you can do is use min and find the minimum across all of the rows for each column. You would actually use the second output in order to find the location of each column per row that you want to find. Once you locate these, simply use sub2ind to access the corresponding values in B. As such, try something like this:
[~,ind] = min(A,[],2);
val = B(sub2ind(size(A), (1:size(A,1)).', ind));
val would contain the output values in the matrix B which correspond to the same positions as the minimum values of each row in A. This is also assuming that A and B are the same size. As an illustration, here's an example. Let's set A and B to be a random 4 x 4 array of integers each.
rng(123);
A = randi(10, 4, 4)
B = randi(10, 4, 4)
A =
7 8 5 5
3 5 4 1
3 10 4 4
6 7 8 8
B =
2 7 8 3
2 9 4 7
6 8 4 1
6 7 3 5
By running the first line of code, we get this:
[~,ind] = min(A,[],2)
ind =
3
4
1
1
This tells us that the minimum value of the first row is the third column, the minimum value of the next row is the 4th column, and so on and so forth. Once we have these column numbers, let's access what the corresponding values are in B, so we would want row and columns (1,3), (2,4), etc. Therefore, after running the second statement, we get:
val = B(sub2ind(size(A), (1:size(A,1)).', ind))
val =
8
7
6
6
If you quickly double check the accessed positions in B in comparison to A, we have found exactly those spots in B that correspond to A.
A = randi(9,[5 5]);
B = randi(9,[5 5]);
[C,I] = min(A');
B.*(A == repmat(C',1,size(A,2)))
example,
A =
2 1 6 9 1
2 4 4 4 2
5 6 5 5 5
9 3 9 3 6
4 5 6 8 3
B =
3 5 6 8 1
9 2 9 7 1
5 6 6 5 6
4 6 1 4 5
5 3 7 1 9
ans =
0 5 0 0 1
9 0 0 0 1
5 0 6 5 6
0 6 0 4 0
0 0 0 0 9
You can use it like,
B(A == repmat(C',1,5))
ans =
9
5
5
6
6
5
4
1
1
6
9

How to subtract every nth column in Matlab

If I have an arbitrary n*m matrix called data and I would like to take differences of the matrix using gradually bigger steps.
The first case would have a first column equal to data(:,2)-data(:,1), the next column would be data(:,3)-data(:,2) and so on. This can be done with the following function.
data = diff(data,1,2)
Similarly I would also like to take differences based of every second column, so that the first entry would be data(:,3)-data(:,1) and the next data(:,5)-data(:,3) and so on.
This can't be done with diff, but is there any other function or method that can do it without resorting to looping?
I need to do the same thing for every n value up to 50.
Use column indexing to select the "right" columns and then use your favourite diff -
A = randi(9,4,9) %// Input array
stepsize = 2; %// Edit this for a different stepsize
out = diff(A(:,1:stepsize:end),1,2)
Output -
A =
8 9 9 8 3 2 6 8 7
2 5 5 7 5 3 9 6 3
2 7 7 2 4 1 2 4 1
6 2 1 5 4 9 9 3 7
out =
1 -6 3 1
3 0 4 -6
5 -3 -2 -1
-5 3 5 -2
I just wrote a simple wrapper function for the purpose.
function [ out ] = diffhigh( matrix, offset )
matrix_1 = matrix(:,(offset+1):size(matrix,1));
matrix_2 = matrix(:, 1:(size(matrix,1)-offset));
out = matrix_1 - matrix_2;
end
>> a
a =
3 5 1 2 4
1 2 3 4 5
1 4 5 3 2
1 2 4 3 5
2 1 5 3 4
>> diffhigh(a, 2)
ans =
-2 -3 3
2 2 2
4 -1 -3
3 1 1
3 2 -1
>> diffhigh(a, 3)
ans =
-1 -1
3 3
2 -2
2 3
1 3