If you use tf.keras.utils.to_categorical to one-hot the label vector, the integers should start from 0 to num_classes, source. In your case, you should do as follows
import tensorflow as tf
import numpy as np
a = np.array([1,2,4,3,5,2,4,2,1])
y_tf = tf.keras.utils.to_categorical(a-1, num_classes = 5)
y_tf
array([[1., 0., 0., 0., 0.],
[0., 1., 0., 0., 0.],
[0., 0., 0., 1., 0.],
[0., 0., 1., 0., 0.],
[0., 0., 0., 0., 1.],
[0., 1., 0., 0., 0.],
[0., 0., 0., 1., 0.],
[0., 1., 0., 0., 0.],
[1., 0., 0., 0., 0.]], dtype=float32)
or, you can use pd.get_dummies,
import pandas as pd
import numpy as np
a = np.array([1,2,4,3,5,2,4,2,1])
a_pd = pd.get_dummies(a).astype('float32').values
a_pd
array([[1., 0., 0., 0., 0.],
[0., 1., 0., 0., 0.],
[0., 0., 0., 1., 0.],
[0., 0., 1., 0., 0.],
[0., 0., 0., 0., 1.],
[0., 1., 0., 0., 0.],
[0., 0., 0., 1., 0.],
[0., 1., 0., 0., 0.],
[1., 0., 0., 0., 0.]], dtype=float32)
Answer from Innat on Stack Overflowclassification - How to use one hot encoding of string categorical features in keras? - Data Science Stack Exchange
neural network - Beyond one-hot encoding for LSTM model in Keras - Data Science Stack Exchange
How can I decode one hot vector? (and when can we use it?)
What are embedding layers?
For string data, use get_dummies() (from Pandas). to_categorical() takes integers as inputs.
There are two important differences between
Keras: to_categorical() and
Pandas: get_dummies().
Keras: to_categorical()
to_categorical()takes integers as input (no strings allowed).to_categorical()generates dummies starting at 0 by default!
Looking at the help function:
print(help(to_categorical))
Says:
to_categorical(y, num_classes=None, dtype='float32')
Converts a class vector (integers) to binary class matrix.
E.g. for use with categorical_crossentropy.
# Arguments
y: class vector to be converted into a matrix
(integers from 0 to num_classes).
num_classes: total number of classes.
dtype: The data type expected by the input, as a string
(`float32`, `float64`, `int32`...)
...
So if your data is numeric (int), you can use to_categorical(). You can check if your data is an np.array by looking at .dtype and/or type().
import numpy as np
npa = np.array([2,2,3,3,4,4])
print(npa.dtype, type(npa))
print(npa)
Result:
int32 <class 'numpy.ndarray'>
[2 2 3 3 4 4]
Now you can use to_categorical():
from keras.utils import to_categorical
cat1 = to_categorical(npa)
print(cat1.dtype, type(cat1))
print(cat1)
Which yields a matrix:
float32 <class 'numpy.ndarray'>
[[0. 0. 1. 0. 0.]
[0. 0. 1. 0. 0.]
[0. 0. 0. 1. 0.]
[0. 0. 0. 1. 0.]
[0. 0. 0. 0. 1.]
[0. 0. 0. 0. 1.]]
Note that the matrix contains five columns (starting at zero up to four, which is my max. value in the np.array). The first two columns (representing 0 and 1 in the original data) are 0 in the whole matrix, because none of these values are found in the original data.
to_categorical() also takes input which is not explicitly defined as np.array. For instance the statements below would also be legal.
alt1 = to_categorical([0,0,1,1,2,2])
print(alt1.dtype, type(alt1))
print(alt1)
alt2 = to_categorical((0,0,1,1,2,2))
print(alt2.dtype, type(alt2))
print(alt2)
Because the range of values now is between 0 and 2, the result would look like:
[[1. 0. 0.]
[1. 0. 0.]
[0. 1. 0.]
[0. 1. 0.]
[0. 0. 1.]
[0. 0. 1.]]
Pandas: get_dummies()
When you have a Pandas df, you can convert some column to dummies using get_dummies(), regardless of the data type in the column. So it is also possible to convert a column of strings to dummies.
import pandas as pd
df = pd.DataFrame(data={'col1':["A", "A", "B", "B", "C", "C"]})
alt3 = pd.get_dummies(df['col1'])
print(type(alt3))
This gives:
<class 'pandas.core.frame.DataFrame'>
A B C
0 1 0 0
1 1 0 0
2 0 1 0
3 0 1 0
4 0 0 1
5 0 0 1
Note that the result is (again) a Pandas df. So we need to convert it to a np.array.
alt3 = alt3.to_numpy()
print(alt3.dtype, type(alt3))
print(alt3)
This yields:
uint8 <class 'numpy.ndarray'>
[[1 0 0]
[1 0 0]
[0 1 0]
[0 1 0]
[0 0 1]
[0 0 1]]
So that it is ready to be used with Keras.
Note that the matrix generated here does not (!) start at zero. Instead each distinct value in the chosen Pandas column gets it's own column in the dummy matrix.
Try:
X = dataset[:,0:17].astype(float).astype(int)
I think that if you have a string like '45.2', you will have to cast it as a floating-point first and from float you can cast them into integer.
I will be glad if an editor could corroborate/correct this answer.
You are looking for top-k categorical accuracy. This is actually implemented in keras, but you might want to change the k, which can be done with partial function. This is the related link.
If you're doing multilabel, you should do binary-crossentropy and sigmoid in a final layer. You must score your labels separately. Here's an example.