Powiedzmy, że mam tablicę numeryczną 1d
a = array([1,0,3])
Chciałbym zakodować to jako tablicę 2d 1-hot
b = array([[0,1,0,0], [1,0,0,0], [0,0,0,1]])
Czy jest na to szybki sposób? To znaczy szybsze niż zapętlanie w a
celu ustawienia elementów b
, to znaczy.
python
numpy
machine-learning
numpy-ndarray
one-hot-encoding
James Atwood
źródło
źródło
b = np.zeros((a.size, a.max()+1))
następnie `b [np. Zmiana (a.size), a] = 1`źródło
values
powinna być tablica Numpy, a nie lista Python, to działa ona we wszystkich wymiarach, nie tylko w 1D.np.max(values) + 1
jako liczbę segmentów może nie być pożądane, jeśli Twój zestaw danych jest, powiedzmy, losowo próbkowany i przypadkiem może nie zawierać maksymalnej wartości. Liczba segmentów powinna być raczej parametrem, a sprawdzenie / sprawdzenie może być na miejscu, aby sprawdzić, czy każda wartość mieści się w przedziale 0 (włącznie), a liczba segmentów (bez).numpy
dokumentów): w każdej lokalizacji w oryginalnej macierzy (values
) mamy liczbę całkowitąk
i „umieszczamy” 1-gorący wektoreye(n)[k]
w tej lokalizacji . Dodaje to wymiar, ponieważ „umieszczamy” wektor w miejscu skalara w oryginalnej macierzy.W przypadku korzystania z keras istnieje wbudowane narzędzie do tego:
I robi to prawie tak samo jak odpowiedź @ YXD (patrz kod źródłowy ).
źródło
Oto, co uważam za przydatne:
Tutaj
num_classes
oznacza liczbę klas masz. Więc jeśli masza
wektor o kształcie (10000,), ta funkcja przekształca go w (10000, C) . Zauważ, żea
jest indeksowany na zero, tzn .one_hot(np.array([0, 1]), 2)
Da[[1, 0], [0, 1]]
.Dokładnie to, co chciałeś mieć, wierzę.
PS: źródłem są modele sekwencyjne - deeplearning.ai
źródło
np.eye(num_classes)[a.reshape(-1)]. What you are simply doing is using
np.eye` tworzysz macierz diagonalną z każdym indeksem klasy jako 1 resztę zero, a później używając podanych indeksów przya.reshape(-1)
produkcji na wyjściu odpowiadający indeksunp.eye()
. Nie zrozumiałem potrzeby,np.sqeeze
ponieważ używamy go do usuwania pojedynczych wymiarów, których nigdy nie będziemy mieć, ponieważ w wymiarze wyjściowym zawsze będzie(a_flattened_size, num_classes)
Możesz użyć
sklearn.preprocessing.LabelBinarizer
:Przykład:
wynik:
Między innymi możesz zainicjować,
sklearn.preprocessing.LabelBinarizer()
aby wyniktransform
był rzadki.źródło
Możesz także użyć funkcji oka numpy:
numpy.eye(number of classes)[vector containing the labels]
źródło
np.identity(num_classes)[indices]
może być lepsze. Niezła odpowiedź!Oto funkcja, która konwertuje wektor 1-D na 2-D z jedną gorącą macierzą.
Poniżej znajduje się przykładowe użycie:
źródło
assert
możliwości sprawdzenia kształtu wektora;)).assert ___
naif not ___ raise Exception(<Reason>)
.Do kodowania 1 na gorąco
Na przykład
CIESZ SIĘ KODOWANIEM
źródło
>>> 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
Myślę, że krótka odpowiedź brzmi „nie”. Dla bardziej ogólnego przypadku
n
wymiarów wymyśliłem to:Zastanawiam się, czy istnieje lepsze rozwiązanie - nie podoba mi się to, że muszę tworzyć te listy w dwóch ostatnich wierszach. W każdym razie zrobiłem kilka pomiarów
timeit
i wydaje się, że wersjenumpy
-basing (indices
/arange
) i wersje iteracyjne działają mniej więcej tak samo.źródło
Aby rozwinąć doskonałą odpowiedź z K3 --- rnc , oto bardziej ogólna wersja:
Również tutaj jest szybkie i-brudny odniesienia tej metody i sposób od obecnie przyjętego odpowiedzi przez YXD (nieco zmieniona, tak, że oferują one tego samego API chyba że ten ostatni działa tylko z ndarrays 1D):
Ta druga metoda jest ~ 35% szybsza (MacBook Pro 13 2015), ale pierwsza jest bardziej ogólna:
źródło
Możesz użyć następującego kodu do konwersji na wektor z jednym gorącym:
niech x jest normalnym wektorem klas mającym pojedynczą kolumnę z klasami 0 do pewnej liczby:
jeśli 0 nie jest klasą; następnie usuń +1.
źródło
Niedawno natknąłem się na problem tego samego rodzaju i znalazłem wspomniane rozwiązanie, które okazało się satysfakcjonujące tylko wtedy, gdy masz liczby mieszczące się w określonej formacji. Na przykład, jeśli chcesz zakodować jednym kodem, ta lista:
śmiało, opublikowane rozwiązania są już wspomniane powyżej. Ale co jeśli rozważymy te dane:
Jeśli zrobisz to za pomocą metod wymienionych powyżej, prawdopodobnie uzyskasz 90 pojedynczych kolumn. Jest tak, ponieważ wszystkie odpowiedzi zawierają coś podobnego
n = np.max(a)+1
. Znalazłem bardziej ogólne rozwiązanie, które mi się przydało i chciałem się z Tobą podzielić:Mam nadzieję, że ktoś napotkał takie same ograniczenia na powyższe rozwiązania i może się to przydać
źródło
Tego rodzaju kodowanie jest zwykle częścią tablicy numpy. Jeśli używasz tablicy numpy takiej jak ta:
to jest bardzo prosty sposób przekonwertować to na kodowanie 1-hot
Otóż to.
źródło
czyste i łatwe rozwiązanie:
źródło
Za pomocą kroku rurociągu Neuraxle :
Link do dokumentacji: neuraxle.steps.numpy.OneHotEncoder
źródło
Oto przykładowa funkcja, którą napisałem, aby to zrobić na podstawie powyższych odpowiedzi i własnego przypadku użycia:
źródło
Dodaję do zakończenia prostą funkcję, używając tylko operatorów numpy:
Jako dane wejściowe przyjmuje macierz prawdopodobieństwa: np .:
I wróci
źródło
Oto niezależne od wymiarów niezależne rozwiązanie.
Spowoduje to przekształcenie dowolnej N-wymiarowej tablicy
arr
liczb całkowitych nieujemnych w jedno-gorącą tablicę N + 1-wymiarowąone_hot
, o ileone_hot[i_1,...,i_N,c] = 1
to możliwearr[i_1,...,i_N] = c
. Możesz odzyskać dane wejściowe za pośrednictwemnp.argmax(one_hot, -1)
źródło
Użyj następującego kodu. Działa najlepiej.
Znaleziono tutaj PS Nie musisz wchodzić w link.
źródło