Função para codificar rótulos inteiros na codificação one-hot

Esta função é também chamada de conversão para dados categóricos. Temos 3 classes de flores: Iris setosa, Iris virginica and Iris versicolor. Estas classes podem ser codificadas como classes 0, 1 e 2 (rótulos numéricos) ou na codificação com 3 variáveis binárias:

Espécie Y Y_oh[0] Y_oh[1] Y_oh[2]
Iris setosa 0 1 0 0
Iris virginica 1 0 1 0
Iris versicolor 2 0 0 1

A função oneHotIt a seguir implementa de forma eficiente esta conversão, utilizando a facilidade de criação de arrays esparsos.

A entrada da função é o vetor Y e a saída será um array com o mesmo número de linhas que o número de elementos de Y e a largura terá o número de colunas do maior rótulo disponível em Y:

A título de ilustração e exercício de programação matricial, apresentamos a seguir duas implementações da função que converte os labels para a codificação "one-hot":


In [2]:
import numpy as np

Primeira solução: Qual é a técnica?


In [ ]:
def oneHotIt2(Y,n_classes):
    Y = Y.reshape(-1,1) # matriz coluna
    i = np.arange(n_classes).reshape(1,n_classes) # matriz linha
    Y_oh = (Y == i).astype(int)
    return Y_oh

Segunda solução: Qual é a técnica?


In [1]:
def oneHotIt(Y,n_classes):
    n_samples = Y.size # número de amostras
    i = np.arange(n_samples)
    Y_oh = np.zeros(shape=(n_samples,n_classes))
    Y_oh[i,Y] = 1
    return Y_oh

In [8]:
Y = np.arange(10)%7
Y_oh = oneHotIt2(Y,7)
Y_oh


Out[8]:
array([[1, 0, 0, 0, 0, 0, 0],
       [0, 1, 0, 0, 0, 0, 0],
       [0, 0, 1, 0, 0, 0, 0],
       [0, 0, 0, 1, 0, 0, 0],
       [0, 0, 0, 0, 1, 0, 0],
       [0, 0, 0, 0, 0, 1, 0],
       [0, 0, 0, 0, 0, 0, 1],
       [1, 0, 0, 0, 0, 0, 0],
       [0, 1, 0, 0, 0, 0, 0],
       [0, 0, 1, 0, 0, 0, 0]])

In [9]:
Y = np.arange(10000)%10
%timeit oneHotIt(Y,10000)


10 loops, best of 3: 34.9 ms per loop

In [10]:
%timeit oneHotIt2(Y,10000)


1 loop, best of 3: 933 ms per loop

In [ ]: