Get_dummies (पंडों) और OneHotEncoder (Scikit-learn) के बीच पेशेवरों और विपक्ष क्या हैं?


92

मैं मशीन-लर्निंग क्लासिफायर के लिए श्रेणीबद्ध चर को संख्यात्मक में बदलने के लिए अलग-अलग तरीके सीख रहा हूं। मैं pd.get_dummiesविधि के पार आया sklearn.preprocessing.OneHotEncoder()और मैं यह देखना चाहता था कि प्रदर्शन और उपयोग के मामले में वे कैसे भिन्न हैं।

मैं कैसे उपयोग करने के लिए पर एक ट्यूटोरियल पाया OneHotEncoder()पर https://xgdgsc.wordpress.com/2015/03/20/note-on-using-onehotencoder-in-scikit-learn-to-work-on-categorical-features/ के बाद से sklearnप्रलेखन इस सुविधा पर भी सहायक नहीं था। मुझे लग रहा है कि मैं इसे सही तरीके से नहीं कर रहा हूं ... लेकिन

कुछ पेशेवरों और विपक्ष का उपयोग करने का व्याख्या कर सकते हैं pd.dummiesभर में sklearn.preprocessing.OneHotEncoder()और इसके विपरीत? मुझे पता है कि OneHotEncoder()आप एक विरल मैट्रिक्स देता है, लेकिन इसके अलावा, मुझे यकीन नहीं है कि इसका उपयोग कैसे किया जाता है और pandasविधि पर क्या लाभ हैं । क्या मैं इसका अकुशल उपयोग कर रहा हूं?

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

जवाबों:


56

OneHotEncoderसीधे स्ट्रिंग मान संसाधित नहीं किया जा सकता। यदि आपकी नाममात्र विशेषताएं तार हैं, तो आपको पहले उन्हें पूर्णांक में मैप करने की आवश्यकता है।

pandas.get_dummiesइसके विपरीत है। डिफ़ॉल्ट रूप से, यह केवल स्ट्रिंग कॉलम को एक-हॉट प्रतिनिधित्व में परिवर्तित करता है, जब तक कि कॉलम निर्दिष्ट न हों।


हे @ नोस, इस उत्तर पर आपको वापस पाने में देरी के लिए खेद है
O.rka

1
इसके अलावा, अन्य पर एक कुशल है?
अंकित सेठ

6
अद्यतन, OneHotEncoder0.20.0 संस्करण में भी तार पर लागू नहीं किया जा सकता है।
Bs वह

15
@BsHe अब sklearn में सच नहीं है। 0.20: OneHotEncoder(sparse=False).fit_transform(pd.DataFrame(pd.Series(['good','bad','worst','good', 'good', 'bad'])))काम करता है, जिसका अर्थ है कि OneHotEncoderहलचल पर लागू किया जा सकता है।
dzieciou

1
आप के साथ नए अनदेखी डेटा सांकेतिक शब्दों में बदलना नहीं कर सकते pd.get_dummies
जेंटेड

140

मशीन सीखने के लिए, आप लगभग निश्चित रूप से उपयोग करना चाहते हैं sklearn.OneHotEncoderसरल विश्लेषण जैसे अन्य कार्यों के लिए, आप उपयोग करने में सक्षम हो सकते हैं pd.get_dummies, जो थोड़ा अधिक सुविधाजनक है।

ध्यान दें कि sklearn.OneHotEncoderनवीनतम संस्करण में अपडेट किया गया है ताकि यह श्रेणीबद्ध चर, साथ ही पूर्णांकों के लिए तार को स्वीकार करे

इसका सार यह है कि sklearnएनकोडर एक फ़ंक्शन बनाता है जो लगातार बना रहता है और फिर नए डेटा सेटों पर लागू किया जा सकता है जो लगातार परिणाम के साथ एक ही श्रेणीगत चर का उपयोग करते हैं

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)

ध्यान दें कि हम उसी एनकोडर को कैसे लागू करते हैं जिसे हमने X_trainनए डेटा सेट के माध्यम से बनाया है X_test

विचार करें कि क्या होता है यदि इसके एक चर के लिए X_testअलग-अलग स्तर होते हैं X_train। उदाहरण के लिए, मान लें कि X_train["color"]इसमें केवल "red"और ही हैं "green", लेकिन इसके अलावा, X_test["color"]कभी-कभी होते हैं "blue"

यदि हम उपयोग करते हैं pd.get_dummies, X_testतो एक अतिरिक्त "color_blue"कॉलम के साथ समाप्त हो जाएगा जो X_trainकि नहीं है, और असंगति शायद बाद में हमारे कोड को तोड़ देगी, खासकर यदि हम X_testएक sklearnमॉडल को खिला रहे हैं जिसे हमने प्रशिक्षित किया था X_train

और अगर हम इस तरह के डेटा को उत्पादन में संसाधित करना चाहते हैं, जहां हम एक बार में एक ही उदाहरण प्राप्त कर रहे हैं, pd.get_dummiesतो इसका उपयोग नहीं होगा।

साथ sklearn.OneHotEncoderदूसरे हाथ पर, एक बार हम एनकोडर बना लिया है, हम इसे पुन: उपयोग एक ही आउटपुट हर बार निर्माण करने के लिए, केवल के लिए कॉलम के साथ कर सकते हैं "red"और "green"। और हम स्पष्ट रूप से नियंत्रित कर सकते हैं कि क्या होता है जब यह नए स्तर का सामना करता है "blue": अगर हमें लगता है कि यह असंभव है, तो हम इसे एक त्रुटि के साथ फेंकने के लिए कह सकते हैं handle_unknown="error"; अन्यथा हम इसे जारी रखने के लिए कह सकते हैं और बस लाल और हरे कॉलम को 0 पर सेट कर सकते हैं handle_unknown="ignore"


23
मेरा मानना ​​है कि इस जवाब का स्वीकृत से कहीं अधिक प्रभाव है। असली जादू अज्ञात श्रेणीगत विशेषताओं को संभाल रहा है जो उत्पादन में पॉप अप करने के लिए बाध्य हैं।
बार्कर

2
मुझे लगता है कि यह एक बेहतर, स्वीकृत उत्तर की तुलना में अधिक पूर्ण उत्तर है।
चिराज़ बेनअबेल्काडर

1
हाँ। IMHO, यह स्वीकृत उत्तर की तुलना में बेहतर उत्तर है।
डेमीमैक्स

1
हाँ । यह उत्तर निश्चित रूप से बेहतर बताता है कि one_hot_encoder एक स्पष्ट उदाहरण के साथ बेहतर क्यों हो सकता है
बिनोद मैथ्यूज

1
यह एक सुंदर व्याख्या थी। आप के लिए
Kudos

4

आप केवल कैश क्यों नहीं करेंगे या इसके परिणामस्वरूप get_dummies से चर col_list के रूप में कॉलम को बचाएंगे। ट्रेन बनाम परीक्षण डेटासेट को संरेखित करने के लिए pd.reindex का उपयोग करें .... उदाहरण:

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) 

यह प्रश्न का उत्तर कैसे देता है?
जोरिजस्मिट

पिछले टिप्पणी का खंडन करने के लिए और अधिक कि Sklearn OHE हैंडल_unknown के कारण खराब है। पंडों के रेनडेक्स का उपयोग करके इसे पूरा किया जा सकता है।
कार्ल

एक बंद रन के रूप में get_dummies का उपयोग करने के साथ एक डरपोक समस्या हो सकती है। यदि आपके पास drop_first = True है और अगला नमूना गिरा हुआ मान शामिल नहीं करता है तो क्या होता है?
मिंट

3

मैं वास्तव में कार्ल के जवाब को पसंद करता हूं और इसे उभारता हूं। मैं सिर्फ कार्ल के उदाहरण का थोड़ा विस्तार करूंगा ताकि अधिक लोग उम्मीद करें कि pd.get_dummies अज्ञात को संभाल सकता है। नीचे दिए गए दो उदाहरणों से पता चलता है कि pd.get_dummies OHE के रूप में अज्ञात को संभालने में एक ही बात को पूरा कर सकता है।

# 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']))

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

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.]])

क्या आप ड्रॉप_फर्स्ट = ट्रू के साथ एक उदाहरण शामिल करने के लिए अपने उत्तर का विस्तार कर सकते हैं, और फिर नया डेटा भी दिखा सकते हैं जिसमें गिरा हुआ मूल्य शामिल नहीं है।
मिंट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.