How to print labels and column names for Confusion Matrix? - classification

I get the confusion matrix but since my actual data set has lot of classification categories, it's difficult to understand.
Example -
>>> from sklearn.metrics import confusion_matrix
>>> y_test
['a', 'a', 'b', 'c', 'd', 'd', 'e', 'a', 'c']
>>> y_pred
['b', 'a', 'b', 'c', 'a', 'd', 'e', 'a', 'c']
>>>
>>>
>>> confusion_matrix(y_test, y_pred)
array([[2, 1, 0, 0, 0],
[0, 1, 0, 0, 0],
[0, 0, 2, 0, 0],
[1, 0, 0, 1, 0],
[0, 0, 0, 0, 1]], dtype=int64)
But how to print the labels/column names for better understanding?
I even tried this -
>>> pd.factorize(y_test)
(array([0, 0, 1, 2, 3, 3, 4, 0, 2], dtype=int64), array(['a', 'b', 'c', 'd', 'e'], dtype=object))
>>> pd.factorize(y_pred)
(array([0, 1, 0, 2, 1, 3, 4, 1, 2], dtype=int64), array(['b', 'a', 'c', 'd', 'e'], dtype=object))
Any help please?

Try something like this:
from sklearn.metrics import confusion_matrix
import pandas as pd
import numpy as np
y_test = ['a', 'a', 'b', 'c', 'd', 'd', 'e', 'a', 'c']
y_pred = ['b', 'a', 'b', 'c', 'a', 'd', 'e', 'a', 'c']
labels = np.unique(y_test)
a = confusion_matrix(y_test, y_pred, labels=labels)
pd.DataFrame(a, index=labels, columns=labels)
Output:
a b c d e
a 2 1 0 0 0
b 0 1 0 0 0
c 0 0 2 0 0
d 1 0 0 1 0
e 0 0 0 0 1

Related

Matlab inverse kinematics for 6 DOF arm robot

i want to specify limit between two angels for every joint how i can do that
i tried to make conition but i don't know how to do it
L(1)= Link('d', 0 , 'a', 39.08, 'alpha', pi/2);
L(2)= Link('d', 53.72, 'a', 259.6, 'alpha', 0);
L(3)= Link('d', 0 , 'a', 0, 'alpha', -pi/2);
L(4)= Link('d', 138.3 , 'a', 0, 'alpha', pi/2);
L(5)= Link('d', 0 , 'a', 52.6, 'alpha', -pi/2);
L(6)= Link('d', 0 , 'a', 97.9, 'alpha', 0);
Arm= SerialLink(L, 'name', 'Inmoov');
T=SE3(200,300,100)*SE3.Rx(90);
q = Arm.ikine(T, [0 0 0 0 0], 'mask', [1 1 1 1 1 1]);
Arm.teach(q);

How do I extract specific rows from a PDL matrix?

Suppose I have:
$a = [
[1, 0, 1]
[0, 1, 0]
[0, 1, 1]
]
and I want to extract all rows where $row[2] == 1. My resulting piddle would look like:
$b = [
[1, 0, 1]
[0, 1, 1]
]
Is this possible with PDL?
You need to use which to generate a list of indexes of your matrix which have a value of 1 in the third column
which($aa->index(2) == 1)
and pass this to dice_axis, which will select the rows with the given indexes. Axis 0 is the columns and axis 1 is the rows, so the code looks like this
use strict;
use warnings 'all';
use PDL;
my $aa = pdl <<__END_PDL__;
[
[1, 0, 1]
[0, 1, 0]
[0, 1, 1]
]
__END_PDL__
my $result = $aa->dice_axis(1, which($aa->index(2) == 1));
print $result;
output
[
[1 0 1]
[0 1 1]
]
I'm new to PDL, but it seems like you can use which result as a mask.
You need to transpose original variable first, then transpose it back after using slice.
pdl> $a = pdl [[1, 0, 1], [0, 1, 0], [0, 1, 1]]
pdl> p which($a(2) == 1)
[0 2]
pdl> p $a->transpose
[
[1 0 0]
[0 1 1]
[1 0 1]
]
pdl> p $a->transpose->slice(which($a(2) == 1))->transpose
[
[1 0 1]
[0 1 1]
]

Expanding each element in a (2-by-2) matrix to a (3-by-2) block

I want to expand each element in a (2-by-2) matrix to a (3-by-2) block, using Python 3 --- with professional and elegant codes. Since I don't know the python codes, I will just describe the following in maths
X = # X is an 2-by-2 matrix.
1, 2
3, 4
d = (3,2) # d is the shape that each element in X should be expanded to.
Y = # Y is the result
1, 1, 2, 2
1, 1, 2, 2
1, 1, 2, 2
3, 3, 4, 4
3, 3, 4, 4
3, 3, 4, 4
Not that every element in X is now an 3-by-2 block in Y. The position of the block in Y is the same as the position of the element in X.
Here is the MATLAB code
X = [1,2;3,4];
d = [3,2]
[row, column] = size(X);
a = num2cell(X);
b = cell(row, column);
[b{:}] = deal(ones(d));
Y = cell2mat(cellfun(#times,a,b,'UniformOutput',false));
I appreciate your help. Thanks in advance.
If you are okay with using NumPy module with Python, you can use numpy.kron -
np.kron(X,np.ones((3,2),dtype=int))
Sample run -
In [15]: import numpy as np
In [16]: X = np.arange(4).reshape(2,2)+1 # Create input array
In [17]: X
Out[17]:
array([[1, 2],
[3, 4]])
In [18]: np.kron(X,np.ones((3,2),dtype=int))
Out[18]:
array([[1, 1, 2, 2],
[1, 1, 2, 2],
[1, 1, 2, 2],
[3, 3, 4, 4],
[3, 3, 4, 4],
[3, 3, 4, 4]])
In fact, this is a direct translation of how one would achieved the desired result in MATLAB in an elegant and professional way as well, as shown below -
>> X = [1,2;3 4]
X =
1 2
3 4
>> kron(X,ones(3,2))
ans =
1 1 2 2
1 1 2 2
1 1 2 2
3 3 4 4
3 3 4 4
3 3 4 4
Another way to do it with ndarray.repeat:
>>> X = np.arange(4).reshape(2,2)+1
>>> X.repeat(3, axis=0).repeat(2, axis=1)
array([[1, 1, 2, 2],
[1, 1, 2, 2],
[1, 1, 2, 2],
[3, 3, 4, 4],
[3, 3, 4, 4],
[3, 3, 4, 4]])

Is it possible to change the inequality behaviour of interp1 when using 'previous' or 'next'

Consider as examples:
interp1([0, 1], [2, 3], 0 , 'previous')
interp1([0, 1], [2, 3], 0 , 'next')
which produces
ans =
2
ans =
2
That is, in each respective case it finds the value in [0, 1] closest to and not exceeding 0 (respectively closest to and not below 0), then returns the corresponding value of [2,3]. I would like to change the second condition to "closest to and above 0", that is, it should return the same results as:
interp1([0, 1], [2, 3], 0.1 , 'previous')
interp1([0, 1], [2, 3], 0.1 , 'next')
which gives
ans =
2
ans =
3
In this case this works as 0.1 is a value in between [0, 1].

Elegant way of stripping the 1st layer of cell array in MATLAB?

I have a 1x2 cell array a such that
a{1, 1} is a 5x1 int array containing [1 2 3 4 5]
a{1, 2} is a 5x1 cell array containing 'aa', 'bb', 'cc', 'dd', 'ee'
What is the most elegant way of stripping the first layer, producing a 5x2 cell array as follows?
1 'aa'
2 'bb'
3 'cc'
4 'dd'
5 'ee'
How about:
% original cell
a = cell(1,2);
a{1} = [1 2 3 4 5];
a{2} = {'aa', 'bb', 'cc', 'dd', 'ee'};
% flattened
aa = reshape([num2cell(a{1}) a{2}], [], 2)
I figured one solution out, but am not sure about its "elegantness".
a = cell(1, 2);
a{1, 1} = [1, 2, 3, 4, 5];
a{1, 2} = {'aa','bb','cc','dd','ee'};
result = [num2cell(a{1, 1})' a{1, 2}']
result =
[1] 'aa'
[2] 'bb'
[3] 'cc'
[4] 'dd'
[5] 'ee'
You can try this code:
a{1, 1} = [1,2,3,4,5];
a{1, 2} = {'aa','bb','cc','dd','ee'};
temp = num2cell(a{1});
b = {temp{:};a{2}{:}}.'
b =
[1] 'aa'
[2] 'bb'
[3] 'cc'
[4] 'dd'
[5] 'ee'