Search code examples
pythonkerasscaleperceptron

How do I get Keras predictions to be one hot encoded?


hi i write these code and it's totally fine but don't know how to reverse ypred to compare with ytest

import numpy as np
import pandas as pd
from keras.models import Sequential
from keras.layers import Dense
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn import datasets

from keras.utils import to_categorical


data=datasets.load_iris()

x=data.data
y=to_categorical(data.target)

xtrain, xtest, ytrain, ytest=train_test_split(x, y,test_size=1/3)

sc=StandardScaler()
xtrain=sc.fit_transform(xtrain)
xtest=sc.transform(xtest)

ann_model=Sequential()

ann_model.add(Dense(units=4,activation='relu', kernel_initializer='uniform', input_dim=4))
ann_model.add(Dense(units=4, activation='relu', kernel_initializer='uniform'))
ann_model.add(Dense(units=3, activation='softmax', kernel_initializer='uniform'))

ann_model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

ann_model.fit(xtrain, ytrain,batch_size=8,epochs=800)

ypred=ann_model.predict(xtest)

after this i get a standardized ypred like this:

   [9.9993205e-01, 6.7994297e-05, 1.4203579e-19],
   [5.3556296e-12, 4.2303108e-02, 9.5769691e-01],
   [3.1650116e-04, 9.9964631e-01, 3.7194797e-05],
   [1.4751430e-05, 9.9975187e-01, 2.3338773e-04],
   [9.9994361e-01, 5.6439614e-05, 6.4687055e-20],
   [2.6651847e-04, 9.9968839e-01, 4.5110301e-05],
   [1.6542191e-06, 9.9968910e-01, 3.0929857e-04],
   [9.9991632e-01, 8.3733095e-05, 3.4217699e-19],
   [5.8562500e-07, 9.9891603e-01, 1.0833564e-03],
   [2.7507697e-06, 9.9960250e-01, 3.9476002e-04],
   [9.9997449e-01, 2.5457492e-05, 2.2423828e-21],
   [7.1067189e-14, 5.0079697e-03, 9.9499208e-01],

but i want my ypred be ones and zeros like ytest:

 [0., 1., 0.],
   [0., 0., 1.],
   [1., 0., 0.],
   [0., 0., 1.],
   [0., 1., 0.],
   [1., 0., 0.],
   [0., 0., 1.],
   [0., 0., 1.],
   [0., 0., 1.],

how can i reverse my ypred thank you for helping.


Solution

  • You can use np.argmax and keras.utils.to_categorical:

    import numpy as np
    from tensorflow.keras.utils import to_categorical
    
    arr = np.array([[9.9993205e-01, 6.7994297e-05, 1.4203579e-19],
       [5.3556296e-12, 4.2303108e-02, 9.5769691e-01],
       [3.1650116e-04, 9.9964631e-01, 3.7194797e-05],
       [1.4751430e-05, 9.9975187e-01, 2.3338773e-04],
       [9.9994361e-01, 5.6439614e-05, 6.4687055e-20],
       [2.6651847e-04, 9.9968839e-01, 4.5110301e-05],
       [1.6542191e-06, 9.9968910e-01, 3.0929857e-04],
       [9.9991632e-01, 8.3733095e-05, 3.4217699e-19],
       [5.8562500e-07, 9.9891603e-01, 1.0833564e-03],
       [2.7507697e-06, 9.9960250e-01, 3.9476002e-04],
       [9.9997449e-01, 2.5457492e-05, 2.2423828e-21],
       [7.1067189e-14, 5.0079697e-03, 9.9499208e-01]])
    
    new_array = to_categorical(np.argmax(arr, axis=1), 3)
    

    np.argmax will return the the index where the value is highest (0, 1, or 2), and to_categorical will one-hot this new array, so there is a 1 where the prediction was highest. Result:

    array([[1., 0., 0.],
           [0., 0., 1.],
           [0., 1., 0.],
           [0., 1., 0.],
           [1., 0., 0.],
           [0., 1., 0.],
           [0., 1., 0.],
           [1., 0., 0.],
           [0., 1., 0.],
           [0., 1., 0.],
           [1., 0., 0.],
           [0., 0., 1.]], dtype=float32)
    

    To skip one step, you can also use

    ypred=ann_model.predict_classes(xtest)
    

    which will predict 0, 1 or 2, and then you will just have to do the last step that I suggested:

    new_array = to_categorical(y_pred, 3)
    

    Although full disclosure, I haven't tried the last solution (I don't have a working example).