1

Ich habe eine Liste wie die ähnlich wie diese:One-hot-Codierung von Kategorien

list = ['Opinion, Journal, Editorial', 
     'Opinion, Magazine, Evidence-based', 
     'Evidence-based'] 

wo die Kommas zB zwischen Kategorien aufgeteilt. Meinung und Journal sind zwei getrennte Kategorien. Die echte Liste ist viel größer und hat mehr mögliche Kategorien. Ich möchte die One-Hot-Codierung verwenden, um die Liste so zu transformieren, dass sie für maschinelles Lernen verwendet werden kann. Zum Beispiel aus dieser Liste würde ich gerne eine spärliche Matrix wie die Daten enthält, produzieren:

list = [[1, 1, 1, 0, 0], 
     [1, 0, 0, 0, 1], 
     [0, 0, 0, 0, 1]] 

Idealerweise würde ich scikit-learn's one hot encoder verwenden mag, wie ich nehme an, dies am effizientesten wäre.

Als Reaktion auf @nbrayns Kommentar:

Die Idee ist, die Liste der Kategorien von Text in ein Vektor zu transformieren wherby wenn es zu dieser Kategorie gehört es wird 1 zugeordnet werden, sonst 0. Für das obige Beispiel des Überschriften wären:

headings = ['Opinion', 'Journal', 'Editorial', 'Magazine', 'Evidence-based'] 
+0

Welche Werte sollten 1 sein, und was sollte 0 sein? – nbryans

+0

@nbryans Haben die Frage bearbeitet. – user7347576

Antwort

0

Dies ist möglicherweise nicht die effizienteste Methode, aber wahrscheinlich leicht zu verstehen.
Wenn Sie noch keine Liste aller möglichen Wörter haben, müssen Sie diese erstellen. Im folgenden Code heißt es unique. Die Spalten der Ausgangsmatrix s entsprechen dann diesen eindeutigen Wörtern; Die Zeilen sind der Eintrag aus der Liste.

import numpy as np 

lis = ['Opinion, Journal, Editorial','Opinion, Magazine, Evidence-based','Evidence-based'] 

unique=list(set(", ".join(lis).split(", "))) 
print unique 
# prints ['Opinion', 'Journal', 'Magazine', 'Editorial', 'Evidence-based'] 

s = np.zeros((len(lis), len(unique))) 
for i, item in enumerate(lis): 
    for j, notion in enumerate(unique): 
     if notion in item: 
      s[i,j] = 1 

print s 
# prints [[ 1. 1. 0. 1. 0.] 
#   [ 1. 0. 1. 0. 1.] 
#   [ 0. 0. 0. 0. 1.]] 
-1

Sehr einfach in pandas:

import pandas as pd 
s = pd.Series(['a','b','c']) 
pd.get_dummies(s) 

Ausgang:

a b c 
0 1 0 0 
1 0 1 0 
2 0 0 1 
0

Eine weitere Möglichkeit:

l = ['Opinion, Journal, Editorial', 'Opinion, Magazine, Evidence-based', 'Evidence-based'] 

# Get list of unique classes 
classes = list(set([j for i in l for j in i.split(', ')])) 
=> ['Journal', 'Opinion', 'Editorial', 'Evidence-based', 'Magazine'] 

# Get indices in the matrix 
indices = np.array([[k, classes.index(j)] for k, i in enumerate(l) for j in i.split(', ')]) 
=> array([[0, 1], 
      [0, 0], 
      [0, 2], 
      [1, 1], 
      [1, 4], 
      [1, 3], 
      [2, 3]]) 

# Generate output 
output = np.zeros((len(l), len(classes)), dtype=int) 
output[indices[:, 0], indices[:, 1]]=1 
=> array([[ 1, 1, 1, 0, 0], 
      [ 0, 1, 0, 1, 1], 
      [ 0, 0, 0, 1, 0]]) 
3

Wenn Sie in der Lage sind Pandas zu verwenden, diese Funktionalität im wesentlichen dort eingebaut:

import pandas as pd 

l = ['Opinion, Journal, Editorial', 'Opinion, Magazine, Evidence-based', 'Evidence-based'] 
pd.Series(l).str.get_dummies(', ') 
Editorial Evidence-based Journal Magazine Opinion 
0   1    0  1   0  1 
1   0    1  0   1  1 
2   0    1  0   0  0 

Wenn Sie mit dem sklearn Ökosystem bleiben möchten, können Sie suchen MultiLabelBinarizer, nicht für OneHotEncoder. Wie der Name andeutet, unterstützt OneHotEncoder nur eine Ebene pro Beispiel pro Kategorie, während Ihr Dataset mehrere hat.

from sklearn.preprocessing import MultiLabelBinarizer 

mlb = MultiLabelBinarizer() # pass sparse_output=True if you'd like 
mlb.fit_transform(s.split(', ') for s in l) 
[[1 0 1 0 1] 
[0 1 0 1 1] 
[0 1 0 0 0]] 

Um die Spalten wieder auf kategorische Ebenen abzubilden, Sie mlb.classes_ zugreifen können. Für das obige Beispiel ergibt dies ['Editorial' 'Evidence-based' 'Journal' 'Magazine' 'Opinion'].

+0

Funktioniert das unabhängig von der Reihenfolge der Kategorien? – user7347576

+1

@ user7347576 Ja, wenn Sie fragen, ob "Opinion, Journal" oder "Journal, Opinion" einen Unterschied macht, dann nicht. –

Verwandte Themen