Digamos que eu tenho uma matriz numpy 1d
a = array([1,0,3])
Gostaria de codificar isso como uma matriz 2d 1-hot
b = array([[0,1,0,0], [1,0,0,0], [0,0,0,1]])
Existe uma maneira rápida de fazer isso? Mais rápido do que apenas fazer um loop a
para definir elementos b
, é isso.
python
numpy
machine-learning
numpy-ndarray
one-hot-encoding
James Atwood
fonte
fonte
b = np.zeros((a.size, a.max()+1))
:, então `b [np.arange (a.size), a] = 1`fonte
values
deve ser um array Numpy, em vez de uma lista Python, e funciona em todas as dimensões, não apenas em 1D.np.max(values) + 1
como número de buckets pode não ser desejável se o seu conjunto de dados for amostrado aleatoriamente e, por acaso, ele pode não conter o valor máximo. O número de buckets deve ser um parâmetro e pode ser feita uma asserção / verificação para verificar se cada valor está dentro de 0 (incl) e a contagem de buckets (excl).numpy
documentos): em cada local na matriz original (values
), temos um número inteirok
e "colocamos" o vetor 1 quenteeye(n)[k]
nesse local . Isso adiciona uma dimensão, porque estamos "colocando" um vetor no local de um escalar na matriz original.Caso você esteja usando keras, existe um utilitário interno para isso:
E faz praticamente o mesmo que a resposta do @ YXD (consulte o código-fonte ).
fonte
Aqui está o que eu acho útil:
Aqui
num_classes
representa o número de classes que você tem. Portanto, se você tiver uma
vetor com formato de (10000,), essa função o transforma em (10000, C) . Observe quea
é indexado a zero, ou sejaone_hot(np.array([0, 1]), 2)
, dará[[1, 0], [0, 1]]
.Exatamente o que você queria ter, eu acredito.
PS: a fonte é modelos de sequência - deeplearning.ai
fonte
np.eye(num_classes)[a.reshape(-1)]. What you are simply doing is using
np.eye`, você está criando uma matriz diagonal com cada índice de classe como 1 resto zero e posteriormente usando os índices fornecidos pora.reshape(-1)
produzir a saída que corresponde ao índice denp.eye()
. Eu não entendi a necessidade denp.sqeeze
uma vez que usá-lo para simplesmente remover dimensões individuais que nunca teremos como na dimensão da saída será sempre(a_flattened_size, num_classes)
Você pode usar
sklearn.preprocessing.LabelBinarizer
:Exemplo:
resultado:
Entre outras coisas, você pode inicializar
sklearn.preprocessing.LabelBinarizer()
para que a saída detransform
seja esparsa.fonte
Você também pode usar a função ocular de numpy:
numpy.eye(number of classes)[vector containing the labels]
fonte
np.identity(num_classes)[indices]
pode ser melhor. Boa resposta!Aqui está uma função que converte um vetor 1-D em um array 2-D one-hot.
Abaixo está um exemplo de uso:
fonte
assert
como verificar a forma do vetor;)).assert ___
emif not ___ raise Exception(<Reason>)
.Para codificação 1 quente
Por exemplo
APRECIE CODIFICAÇÃO
fonte
>>> import numpy as np >>> import pandas >>> a = np.array([1,0,3]) >>> one_hot_encode=pandas.get_dummies(a) >>> print(one_hot_encode) 0 1 3 0 0 1 0 1 1 0 0 2 0 0 1 >>> print(one_hot_encode[1]) 0 1 1 0 2 0 Name: 1, dtype: uint8 >>> print(one_hot_encode[0]) 0 0 1 1 2 0 Name: 0, dtype: uint8 >>> print(one_hot_encode[3]) 0 0 1 0 2 1 Name: 3, dtype: uint8
Eu acho que a resposta curta é não. Para um caso mais genérico em
n
dimensões, vim com isso:Gostaria de saber se existe uma solução melhor - não gosto que tenha que criar essas listas nas duas últimas linhas. De qualquer forma, fiz algumas medições
timeit
e parece que as versões comnumpy
base (indices
/arange
) e iterativa têm o mesmo desempenho.fonte
Apenas para elaborar a excelente resposta do K3 --- rnc , aqui está uma versão mais genérica:
Além disso, aqui está uma referência rápida e suja desse método e um método da resposta atualmente aceita pelo YXD (ligeiramente alterada, para que eles ofereçam a mesma API, exceto que o último funciona apenas com ndarrays 1D):
O último método é ~ 35% mais rápido (MacBook Pro 13 2015), mas o primeiro é mais geral:
fonte
Você pode usar o seguinte código para converter em um vetor quente:
deixe x é o vetor de classe normal com uma única coluna com classes 0 a algum número:
se 0 não é uma classe; depois remova o +1.
fonte
Recentemente, encontrei um problema do mesmo tipo e encontrei a referida solução, que acabou sendo satisfatória apenas se você tiver números que se enquadram em uma determinada formação. Por exemplo, se você deseja codificar com hot-list a seguinte lista:
vá em frente, as soluções publicadas já são mencionadas acima. Mas e se considerar esses dados:
Se você fizer isso com os métodos mencionados acima, provavelmente terminará com 90 colunas de uma só vez. Isso ocorre porque todas as respostas incluem algo parecido
n = np.max(a)+1
. Encontrei uma solução mais genérica que funcionou para mim e queria compartilhar com você:Espero que alguém tenha encontrado as mesmas restrições nas soluções acima e isso possa ser útil
fonte
Esse tipo de codificação geralmente faz parte de um array numpy. Se você estiver usando uma matriz numpy como esta:
então existe uma maneira muito simples de converter isso em codificação 1-hot
É isso aí.
fonte
solução limpa e fácil:
fonte
Usando uma etapa do pipeline Neuraxle :
Link para a documentação: neuraxle.steps.numpy.OneHotEncoder
fonte
Aqui está um exemplo de função que eu escrevi para fazer isso com base nas respostas acima e no meu próprio caso de uso:
fonte
Estou adicionando para concluir uma função simples, usando apenas operadores numpy:
Toma como entrada uma matriz de probabilidade: por exemplo:
E vai voltar
fonte
Aqui está uma solução independente de dimensionalidade.
Isso converterá qualquer matriz N-dimensional
arr
de números inteiros não negativos em uma matriz N-1 dimensional quenteone_hot
, ondeone_hot[i_1,...,i_N,c] = 1
significaarr[i_1,...,i_N] = c
. Você pode recuperar a entrada vianp.argmax(one_hot, -1)
fonte
Use o seguinte código. Funciona melhor.
Encontre aqui PS Você não precisa entrar no link.
fonte