Ich lerne verschiedene Methoden, um kategoriale Variablen für maschinell lernende Klassifikatoren in numerische umzuwandeln. Ich bin auf die pd.get_dummies
Methode gestoßen sklearn.preprocessing.OneHotEncoder()
und wollte sehen, wie sie sich in Bezug auf Leistung und Nutzung unterscheiden.
Ich habe seitdem ein Tutorial zur Verwendung OneHotEncoder()
unter https://xgdgsc.wordpress.com/2015/03/20/note-on-using-onehotencoder-in-scikit-learn-to-work-on-categorical-features/ gefunden Die sklearn
Dokumentation war für diese Funktion nicht allzu hilfreich. Ich habe das Gefühl, ich mache es nicht richtig ... aber
Können einige die Vor- und Nachteile der Verwendung von pd.dummies
Over erklären sklearn.preprocessing.OneHotEncoder()
und umgekehrt? Ich weiß, dass OneHotEncoder()
Sie eine spärliche Matrix erhalten, aber ansonsten bin ich mir nicht sicher, wie sie verwendet wird und welche Vorteile sie gegenüber der pandas
Methode haben. Benutze ich es ineffizient?
import pandas as pd
import numpy as np
from sklearn.datasets import load_iris
sns.set()
%matplotlib inline
#Iris Plot
iris = load_iris()
n_samples, m_features = iris.data.shape
#Load Data
X, y = iris.data, iris.target
D_target_dummy = dict(zip(np.arange(iris.target_names.shape[0]), iris.target_names))
DF_data = pd.DataFrame(X,columns=iris.feature_names)
DF_data["target"] = pd.Series(y).map(D_target_dummy)
#sepal length (cm) sepal width (cm) petal length (cm) petal width (cm) \
#0 5.1 3.5 1.4 0.2
#1 4.9 3.0 1.4 0.2
#2 4.7 3.2 1.3 0.2
#3 4.6 3.1 1.5 0.2
#4 5.0 3.6 1.4 0.2
#5 5.4 3.9 1.7 0.4
DF_dummies = pd.get_dummies(DF_data["target"])
#setosa versicolor virginica
#0 1 0 0
#1 1 0 0
#2 1 0 0
#3 1 0 0
#4 1 0 0
#5 1 0 0
from sklearn.preprocessing import OneHotEncoder, LabelEncoder
def f1(DF_data):
Enc_ohe, Enc_label = OneHotEncoder(), LabelEncoder()
DF_data["Dummies"] = Enc_label.fit_transform(DF_data["target"])
DF_dummies2 = pd.DataFrame(Enc_ohe.fit_transform(DF_data[["Dummies"]]).todense(), columns = Enc_label.classes_)
return(DF_dummies2)
%timeit pd.get_dummies(DF_data["target"])
#1000 loops, best of 3: 777 µs per loop
%timeit f1(DF_data)
#100 loops, best of 3: 2.91 ms per loop
OneHotEncoder
kann in der Version 0.20.0 nicht auch auf Strings angewendet werden.OneHotEncoder(sparse=False).fit_transform(pd.DataFrame(pd.Series(['good','bad','worst','good', 'good', 'bad'])))
funktioniert, was bedeutet,OneHotEncoder
dass auf stirngs angewendet werden kann.pd.get_dummies
.Für maschinelles Lernen möchten Sie fast definitiv verwenden
sklearn.OneHotEncoder
. Für andere Aufgaben wie einfache Analysen können Sie diese möglicherweise verwendenpd.get_dummies
, was etwas bequemer ist.Beachten Sie, dass
sklearn.OneHotEncoder
dies in der neuesten Version aktualisiert wurde, sodass Zeichenfolgen für kategoriale Variablen sowie Ganzzahlen akzeptiert werden .Der springende Punkt dabei ist, dass der
sklearn
Encoder eine Funktion erstellt, die bestehen bleibt und dann auf neue Datensätze angewendet werden kann, die dieselben kategorialen Variablen verwenden, mit konsistenten Ergebnissen .from sklearn.preprocessing import OneHotEncoder # Create the encoder. encoder = OneHotEncoder(handle_unknown="ignore") encoder.fit(X_train) # Assume for simplicity all features are categorical. # Apply the encoder. X_train = encoder.transform(X_train) X_test = encoder.transform(X_test)
Beachten Sie, wie wir denselben Encoder, über
X_train
den wir erstellt haben, auf den neuen Datensatz anwendenX_test
.Überlegen Sie, was passiert, wenn
X_test
andere Ebenen alsX_train
für eine der Variablen enthalten sind. Nehmen wir zum Beispiel an,X_train["color"]
enthält nur"red"
und"green"
, aber zusätzlich zu diesen,X_test["color"]
enthält manchmal"blue"
.Wenn wir verwenden
pd.get_dummies
,X_test
wird eine zusätzliche"color_blue"
Spalte angezeigt, dieX_train
nicht vorhanden ist, und die Inkonsistenz wird wahrscheinlich später unseren Code beschädigen, insbesondere wenn wirX_test
einsklearn
Modell füttern, auf dem wir trainiert habenX_train
.Und wenn wir die Daten so in der Produktion verarbeiten möchten, wo wir jeweils nur ein Beispiel erhalten,
pd.get_dummies
ist dies nicht von Nutzen.Mit
sklearn.OneHotEncoder
auf der anderen Seite, wenn wir den Encoder erstellt haben, können wir es wieder verwenden die gleiche Leistung jedes Mal zu erzeugen, mit Spalten nur für"red"
und"green"
. Und wir können explizit steuern, was passiert, wenn es auf das neue Level trifft"blue"
: Wenn wir denken, dass dies unmöglich ist, können wir es anweisen, einen Fehler mit zu werfenhandle_unknown="error"
; Andernfalls können wir es anweisen, fortzufahren, und einfach die roten und grünen Spalten mit auf 0 setzenhandle_unknown="ignore"
.quelle
Warum sollten Sie die Spalten nicht einfach als Variable col_list aus den resultierenden get_dummies zwischenspeichern oder speichern und dann mit pd.reindex den Zug gegen Testdatensätze ausrichten? Beispiel:
df = pd.get_dummies(data) col_list = df.columns.tolist() new_df = pd.get_dummies(new_data) new_df = new_df.reindex(columns=col_list).fillna(0.00)
quelle
Ich mag Carls Antwort sehr und habe sie positiv bewertet. Ich werde nur Carls Beispiel ein wenig erweitern, damit mehr Leute hoffentlich zu schätzen wissen, dass pd.get_dummies mit Unbekanntem umgehen kann. Die beiden folgenden Beispiele zeigen, dass pd.get_dummies bei der Handhabung von Unbekanntem wie OHE dasselbe erreichen kann.
# data is from @dzieciou's comment above >>> data =pd.DataFrame(pd.Series(['good','bad','worst','good', 'good', 'bad'])) # new_data has two values that data does not have. >>> new_data= pd.DataFrame( pd.Series(['good','bad','worst','good', 'good', 'bad','excellent', 'perfect']))
Verwenden von pd.get_dummies
>>> df = pd.get_dummies(data) >>> col_list = df.columns.tolist() >>> print(df) 0_bad 0_good 0_worst 0 0 1 0 1 1 0 0 2 0 0 1 3 0 1 0 4 0 1 0 5 1 0 0 6 0 0 0 7 0 0 0 >>> new_df = pd.get_dummies(new_data) # handle unknow by using .reindex and .fillna() >>> new_df = new_df.reindex(columns=col_list).fillna(0.00) >>> print(new_df) # 0_bad 0_good 0_worst # 0 0 1 0 # 1 1 0 0 # 2 0 0 1 # 3 0 1 0 # 4 0 1 0 # 5 1 0 0 # 6 0 0 0 # 7 0 0 0
Verwenden von OneHotEncoder
>>> encoder = OneHotEncoder(handle_unknown="ignore", sparse=False) >>> encoder.fit(data) >>> encoder.transform(new_data) # array([[0., 1., 0.], # [1., 0., 0.], # [0., 0., 1.], # [0., 1., 0.], # [0., 1., 0.], # [1., 0., 0.], # [0., 0., 0.], # [0., 0., 0.]])
quelle