Pandas: قائمة الرغبات: اجعل get_dummies () قابلة للاستخدام في إطار التدريب / الاختبار

تم إنشاؤها على ٢٨ نوفمبر ٢٠١٤  ·  21تعليقات  ·  مصدر: pandas-dev/pandas

يعد الحصول على get_dummies () في Pandas أمرًا رائعًا حقًا ، ولكن لكي تكون مفيدة للتعلم الآلي ، يجب أن تكون قابلة للاستخدام في إطار عمل تدريب / اختبار (أو "fit_transform" و "تحويل" ، باستخدام مصطلحات sklearn). اسمحوا لي أن أعرف إذا كان هذا يحتاج إلى مزيد من التفسيرات.

لذلك ، أعتقد أن هذا تقرير بقائمة الرغبات لإضافة هذه الوظيفة إلى Pandas. يمكنني حتى إنشاء طلب سحب ، إذا اتفق الناس على أن هذا سيكون شيئًا مفيدًا في Pandas (ولديهم الرغبة في التدريب قليلاً والقيام بمراجعة الكود لما ستكون مساهمتي الأولى في هذا المشروع).

Categorical Reshaping Usage Question

التعليق الأكثر فائدة

تحتاج ببساطة إلى جعل المتغيرات الخاصة بك Categorical إذا كنت تريد تحديد المتغيرات التي لا يمكن ملاحظتها _ربما _. يمكن القيام بذلك في وقت الإنشاء أو بعد ذلك ، راجع المستندات

In [5]: df_train = pd.DataFrame({"car":Series(["seat","bmw"]).astype('category',categories=['seat','bmw','mercedes']),"color":["red","green"]})

In [6]: df_train
Out[6]: 
    car  color
0  seat    red
1   bmw  green

In [7]: pd.get_dummies(df_train )
Out[7]: 
   car_seat  car_bmw  car_mercedes  color_green  color_red
0         1        0             0            0          1
1         0        1             0            1          0

السؤال الأصلي غير محدد جيدًا ، لذا خاتمة.

ال 21 كومينتر

حسنًا ، ماذا عن مثال كود زائف مع مدخلات ومخرجات من إطار عينة سيكون مفيدًا

@ chrish42 ، سيكون المثال رائعًا.

لدى FYI scikit- Learn فئة

شيء من هذا القبيل يجب أن تعمل؟

import pandas as pd
from sklearn.pipeline import TransformerMixin

class DummyEncoder(TransformerMixin):

    def __init__(self, columns=None):

        self.columns = columns

    def transform(self, X, y=None, **kwargs):

        return pd.get_dummies(X, columns=self.columns)

    def fit(self, X, y=None, **kwargs):

        return self

إعطاء

In [15]: df
Out[15]: 
   A  B  C
0  1  a  a
1  2  b  a

In [16]: DummyEncoder().transform(df)
Out[16]: 
   A  B_a  B_b  C_a
0  1    1    0    1
1  2    0    1    1

كن حذرا مع ترتيب الأعمدة.

TomAugspurger ، في الواقع التوافق مع خط أنابيب معالجة sklearn نفسه ليس هو الجزء الذي يهمني. ما أرغب فيه هو القدرة على حفظ التحويل الذي تم إجراؤه بواسطة get_dummes () إلى مجموعة بيانات ، ثم تطبيق التحويل المذكور كما هو (إنشاء نفس الأعمدة بالضبط) ، حتى لو كانت مجموعة البيانات الثانية تحتوي على مجموعة فرعية من قيم المجموعة الأولى في بعض الأعمدة ، إلخ. هذا ما قصدته في الواقع بعبارة "قابلة للاستخدام في إطار تدريب / اختبار". هل هذا التفسير أوضح؟ (يمكنني إضافة مثال يعتقد شخص ما أنه لا يزال مطلوبًا.)

أنا على دراية بفئة OneHotEncoder في sklearn ، لكن لها قيود أخرى.

لقد عثرت على نفس المشكلة مثل @ chrish42 ووجدت أن get_dummies تسبب لي بعض الصداع.

مثال على قيود الحصول على الدمى الحالية

لنفترض أننا نعمل مع البيانات من df_train DataFrame التالي

"". بايثون
df_train = pandas.DataFrame ({"car": ["seat"، "bmw"]، "color": ["red"، "green"]})
pandas.get_dummies (df_train)

car_bmw car_seat color_green color_red
0 0 1 0 1
1 1 0 1 0


Then we are provided with

``` .python
df_test = pandas.DataFrame({"car":["seat","mercedes"], "color":["red","green"]})
pandas.get_dummies(df_test )

         car_mercedes  car_seat  color_green  color_red
0             0         1            0          1
1             1         0            1          0

بما أنني لم ألاحظ مطلقًا قيمة "مرسيدس" لـ "سيارة" متغيرة في df_train ، أود أن أحصل على الترميز الساخن التالي:

"". بايثون
car_bmw car_seat color_green color_red
0 0 1 0 1
1 0 0 1 0


Where the column car_mercedes actually never appears.

This could be solved by allowing get_dummies to receive an input dictionary stating the accepted values that we allow for each column.  

Returning to the previous example, we could give as input to get_dummies the following dict of sets

``` .python
accepted_values_per_column = {'car': {'bmw', 'seat'}, 'color': {'green', 'red'}}

ونتوقع عودة get_dummies

"". بايثون
get_dummies (df_test، Accept_values_per_column = Accept_values_per_column)

       car_bmw  car_seat  color_green  color_red

0 0 1 0 1
1 0 0 1 0
""

ونتوقع أن تعيد get_dummies (df_test) ما يتم إرجاعه بالفعل.

تحتاج ببساطة إلى جعل المتغيرات الخاصة بك Categorical إذا كنت تريد تحديد المتغيرات التي لا يمكن ملاحظتها _ربما _. يمكن القيام بذلك في وقت الإنشاء أو بعد ذلك ، راجع المستندات

In [5]: df_train = pd.DataFrame({"car":Series(["seat","bmw"]).astype('category',categories=['seat','bmw','mercedes']),"color":["red","green"]})

In [6]: df_train
Out[6]: 
    car  color
0  seat    red
1   bmw  green

In [7]: pd.get_dummies(df_train )
Out[7]: 
   car_seat  car_bmw  car_mercedes  color_green  color_red
0         1        0             0            0          1
1         0        1             0            1          0

السؤال الأصلي غير محدد جيدًا ، لذا خاتمة.

وعندما تسير في الاتجاه الآخر ، من التشفير إلى الرجوع إلى Categorical ، ستستخدم Categorical.from_codes.

القليل من النصائح غير المرغوب فيها. إذا كنت مهتمًا على الإطلاق بالتقديرات الدقيقة للمعاملات في الفئات ، فقم بإسقاط أحد الأعمدة المشفرة وإلا فسيكون لديك خط متعدد الخطوط مع التقاطع (إذا كان لديك واحد).

في 5 أكتوبر 2015 ، في الساعة 05:34 ، كتب Jeff Reback [email protected] :

تحتاج ببساطة إلى جعل المتغيرات الخاصة بك فئوية إذا كنت تريد تحديد متغيرات ربما لا يتم ملاحظتها. يمكن القيام بذلك في وقت الإنشاء أو بعد ذلك ، راجع المستندات

في [5]: df_train = pd.DataFrame ({"car": Series (["seat"، "bmw"]). astype ('category'، categories = ['seat'، 'bmw'، 'mercedes'] ) ، "اللون": ["أحمر" ، "أخضر"]})

في [6]: df_train
خارج [6]:
لون السيارة
0 مقعد أحمر
1 بي ام دبليو خضراء

في [7]: pd.get_dummies (df_train)
خارج [7]:
car_seat car_bmw car_mercedes color_green color_red
0 1 0 0 0 1
1 0 1 0 1 0
السؤال الأصلي غير محدد جيدًا ، لذا خاتمة.

-
قم بالرد على هذا البريد الإلكتروني مباشرةً أو قم بعرضه على GitHub.

TomAugspurgerjreback أعتقد أنني واجهت نفس المشكلة في الآونة الأخيرة، وأنا أود أن أذكر مثالا

train_a = pd.DataFrame ({"IsBadBuy": [0،1،0]، "Make": ['Toyota'، 'Mazda'، 'BMW']})

IsBadBuy Make_BMW Make_Mazda Make_Toyota
0 0 0 0 1
1 1 0 1 0
2 0 1 0 0

test_a = pd.DataFrame ({"Make": ['Toyota'، 'BMW']})
طباعة pd.get_dummies (test_a ، الأعمدة = ['Make'])

Make_BMW Make_Toyota
0 0 1
1 1 0

من الناحية المثالية ، يجب الحفاظ على عمود Make_Mazda لأن خوارزمية ML تتوقع نفس عدد الميزات والقيم التي نحصل عليها في الاختبار ستكون مجموعة فرعية من ذلك في القطار.

استخدم ملف. سيؤدي ذلك إلى توسيع العدد الصحيح من الأعمدة. لقد تحدثت عن هذا إذا كنت مهتمًا https://m.youtube.com/watch؟v=KLPtEBokqQ0

    _____________________________

من: Ajay Saxena [email protected]
تاريخ الإرسال: الخميس 12 يناير 2017 الساعة 18:31
الموضوع: Re: [pandas-dev / pandas] قائمة الرغبات: اجعل get_dummies () قابلة للاستخدام في إطار التدريب / الاختبار (# 8918)
إلى: pandas -dev /
نسخة إلى: Tom Augspurger [email protected] ، أذكر [email protected]

jreback أعتقد أنني واجهت نفس المشكلة مؤخرًا وأود أن أذكر مثالاً

train_a = pd.DataFrame ({"IsBadBuy": [0،1،0]، "Make": ['Toyota'، 'Mazda'، 'BMW']})

IsBadBuy Make_BMW Make_Mazda Make_Toyota
0 0 0 0 1
1 1 0 1 0
2 0 1 0 0

test_a = pd.DataFrame ({"Make": ['Toyota'، 'BMW']})
طباعة pd.get_dummies (test_a ، الأعمدة = ['Make'])

Make_BMW Make_Toyota
0 0 1
1 1 0

من الناحية المثالية ، يجب الحفاظ على عمود Make_Mazda لأن خوارزمية ML تتوقع نفس عدد الميزات والقيم التي نحصل عليها في الاختبار ستكون مجموعة فرعية من ذلك في القطار.

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذه الرسالة الإلكترونية مباشرةً ، أو اعرضها على GitHub ، أو قم بكتم صوت الموضوع.

TomAugspurger شكرا

حديث PyData Chicago 2016 الذي قدمه @ TomAugspurger كان جيدًا حقًا. لقد قام بعمل رائع في توضيح جميع أسباب عدم إغلاق هذه المشكلة / الطلب. يجب تضمين IMHO إما فئته DummyEncoder أو بعض المكافئ المعقول في Pandas المناسب. نعم يمكنني الذهاب إلى جيثب الخاص به ونسخ / محاكاة فصله ولكن سيكون من الأجمل بكثير أن يتم دعمه داخل المكتبة.

أعتقد أن هناك حاجة إلى مكتبة تعمل مبكرًا في نمذجة البيانات
خط أنابيب ويعمل بشكل جيد مع الباندا و scikit-Learn.
لكن الباندا لا تعتمد على scikit-Learn والعكس صحيح. أعتقد أن هناك
غرفة لمكتبة أخرى مبنية فوق كليهما.

يوم الأربعاء ، 10 مايو ، 2017 الساعة 6:13 مساءً ، Brian Wylie [email protected]
كتب:

حديث PyData Chicago 2016 الذي قدمه @ TomAugspurger
https://github.com/TomAugspurger كان جيدًا حقًا. لقد فعل
عمل رائع لتوضيح جميع الأسباب التي تجعل هذه المشكلة / الطلب يجب
لا تكون مغلقة. IMHO إما صفه DummyEncoder أو بعض المعقول
يجب تضمين ما يعادلها في Pandas المناسبة. نعم يمكنني الذهاب إلى جيثب الخاص به
ونسخ / محاكاة فصله ولكن سيكون من الأجمل بكثير الحصول عليه فقط
مدعوم داخل المكتبة.

راجع للشغل أعتقد أن TomAugspurger https://github.com/TomAugspurger قد يكون لي
معلم PyData الجديد المفضل. سأقوم بمطاردة كل شيء هو
انتهيت / تعمل وحاول أن تمتصه .. ليس بطريقة زاحفة / مطاردة .. أنت
تعرف فقط بطريقة طبيعية ليست مخيفة على الإطلاق. :)

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/pandas-dev/pandas/issues/8918#issuecomment-300638388 ،
أو كتم الخيط
https://github.com/notifications/unsubscribe-auth/ABQHIpTqgHSE7iFVF9Pp4_YoKB9DPLcEks5r4kSrgaJpZM4DB6Hb
.

إليك بعض الحلول التي عمل البعض عليها والتي قد تكون مفيدة للبعض هنا. المتغيرات الوهمية ذات القدرات الملائمة / التحويل.

https://github.com/joeddav/get_smarties

ردود الفعل والمساهمات ستكون مفيدة!

يبدو أن هذا متعلق بـ # 14017

لقد خلقت حلاً قد يكون مفيدًا بالضبط في هذه المشكلة. أحد المتغيرات القاطعة ذات التشفير الساخن في إطار اختبار القطار. يمكنه أيضًا التعامل مع الحالات التي تكون فيها مجموعة البيانات كبيرة جدًا بحيث لا يمكن وضعها في ذاكرة الجهاز.

https://github.com/yashu-seth/dummyPy

يمكنك أيضًا العثور على برنامج تعليمي صغير حول هذا هنا .

TomAugspurger هذا الرمز لا يعمل. عندما أذهب لتحويل بيانات الإنتاج الفردي الخاصة بي ، لا يعطيني سوى عمود واحد مشفر ساخن للقيمة الفردية الموجودة.
ماذا ينقصني؟

استيراد ملفات pyodbc
مخلل استيراد
من sklearn.linear_model استيراد LogisticRegression
من sklearn.linear_model استيراد LinearRegression

استيراد numpy كـ np
استيراد الباندا كما pd
من sklearn.pipeline استيراد TransformerMixin
من sklearn.pipeline استيراد make_pipeline

فئة DummyEncoder (TransformerMixin):
تناسب def (ذاتي ، X ، ص = لا شيء):
مؤشر self.index_ = X.index
self.columns_ = X.columns
self.cat_columns_ = X.select_dtypes (تشمل = ['category']). أعمدة
self.non_cat_columns_ = X.columns.drop (self.cat_columns_)

    self.cat_map_ = {col: X[col].cat for col in self.cat_columns_}

    left = len(self.non_cat_columns_)
    self.cat_blocks_ = {}
    for col in self.cat_columns_:
        right = left + len(X[col].cat.categories)
        self.cat_blocks_[col], left = slice(left, right), right
    return self

def transform(self, X, y=None):
    return np.asarray(pd.get_dummies(X))

def inverse_transform(self, X):
    non_cat = pd.DataFrame(X[:, :len(self.non_Cat_columns_)],
                             columns=self.non_cat_columns_)
    cats = []
    for col, cat in self.cat_map_.items():
        slice_ = self.cat_blocks_[col]
        codes = X[:, slice_].argmax(1)
        series = pd.Series(pd.Categorical.from_codes(
                codes, cat.categories, ordered=cat.ordered
        ), name=col)
        cats.append(series)
    df = pd.concat([non_cat] + cats, axis=1)[self.columns_]
    return df

استيراد البيانات من SQL إلى pandas Dataframe

cnxn = pyodbc.connect ('DRIVER = {SQL Server}؛ SERVER = {XXXXX}؛ DATABASE = {ML_Learn_Taxi}؛ UID = {XXXX}؛ PWD = {XXXX}')
sql = "" "
حدد أعلى 1 CONVERT (int، [order_key]) order_key
، CONVERT (int، [service_date_key]) service_date_key
، [order_source_desc]
، 1 كـ "return_flag"
من [ML_Return_Customer]. [dbo]. [return_customers_test_set]
أين [order_source_desc] = "متصل"
اتحاد
حدد أهم 2 CONVERT (int، [order_key])
، CONVERT (int، [service_date_key])
، [order_source_desc]
، 2
من [ML_Return_Customer]. [dbo]. [return_customers_test_set]
أين [order_source_desc] = "مكالمة واردة"
اتحاد
حدد أفضل 1 CONVERT (int، [order_key])
، CONVERT (int، [service_date_key])
، [order_source_desc]
، 1
من [ML_Return_Customer]. [dbo]. [return_customers_test_set]
أين [order_source_desc] = "مكالمة صادرة"
""

prod_sql = "" "
حدد أعلى 1 CONVERT (int، [order_key]) order_key
، CONVERT (int، [service_date_key]) service_date_key
، [order_source_desc]
، 1 كـ "return_flag"
من [ML_Return_Customer]. [dbo]. [return_customers_test_set]
أين [order_source_desc] = "متصل"
""

InputDataSet = pd.read_sql (sql، cnxn)
ProdDataSet = pd.read_sql (prod_sql، cnxn)

طباعة (" * * * * بيانات

* * * * * ")
طباعة (InputDataSet)

print (" * معلومات أعمدة الفئات

* * ")
الأعمدة = ['order_source_desc']
InputDataSet [أعمدة] = InputDataSet [أعمدة]. تطبيق (lambda x: x.astype ('category'))

InputDataSet.info ()

طباعة (" * الانحدار الخطي

* * ")

X = InputDataSet.drop ('return_flag' ، المحور = 1)
y = InputDataSet ['return_flag']

أ = ProdDataSet.drop ('return_flag' ، المحور = 1)
B = ProdDataSet ['return_flag']

enc = DummyEncoder ()
enc.fit (X)

مطر = تحويل تحويل (X)

إنتاج = enc.transform (A)

طباعة (إنتاج)

الإخراج: * * * * البيانات

* * * *
order_key service_date_key order_source_desc return_flag
0 10087937 20151214 عبر الإنترنت 1
1 10088174 20151201 مكالمة واردة 2
2 10088553 20151217 مكالمة واردة 2
3 663478 20160806 مكالمة صادرة 1
* معلومات أعمدة الفئات * *

RangeIndex: 4 إدخالات ، 0 إلى 3
أعمدة البيانات (إجمالي 4 أعمدة):
order_key 4 غير فارغة int64
service_date_key 4 غير خالي int64
order_source_desc 4 فئة غير فارغة
return_flag 4 غير فارغة int64
dtypes: الفئة (1) ، int64 (3)
استخدام الذاكرة: 284.0 بايت
* الانحدار الخطي * * *
[[10087937 20151214 1]]

لذلك أعتقد أن هذا الخيط فوضوي بعض الشيء ، لذا سأحاول تلخيص حل بسيط هنا وكيف أن هذا ممكن بالفعل. سأشرح في عمود واحد ، لكن يمكنك تعميمها على كثيرين.

لذا في "fit" ، اتصل فقط بما يلي:

categories = sorted(training_data.iloc[:, column_index].value_counts(dropna=True).index)

تخزن categories في الحالة التي تتعلمها أثناء التركيب.

ثم في "التحويل" يمكنك:

from pandas.api import types as pandas_types

categorical_data = testing_data.iloc[:, [column_index]].astype(
    pandas_types.CategoricalDtype(categories=categories),
)
one_hot_encoded = pandas.get_dummies(categorical_data)

وسيقوم بعمل تشفير واحد ساخن دائمًا في نفس التعيين للقيم. إذا لم تكن بعض القيمة الفئوية موجودة أثناء التدريب ، فسيتم اعتبارها NaN أثناء الاختبار. إذا لم يتم رؤية بعض القيم أثناء الاختبار ، فلن يتم تعيين أي عمود لها.

هذا لطيف جدا. أتمنى ألا يضطر كل من يريد القيام بذلك إلى اكتشافه من جديد. ؛-)

النهج الذي اقترحه mitar هو مثال قصير لطيف. لاستكشاف هذه المشكلة لفترة أطول ، إليك دفتر ملاحظات قد يكون مفيدًا / مفيدًا: https://nbviewer.jupyter.org/github/SuperCowPowers/scp-labs/blob/master/notebooks/Categorical_Encoding_Dangers.ipynb

شاهد الكود أدناه في ممارسة برنامج Kaggle XGBoost التعليمي. هذه هي الحيلة.

X_train = pd.get_dummies(X_train)
X_valid = pd.get_dummies(X_valid)
X_test = pd.get_dummies(X_test)
X_train, X_valid = X_train.align(X_valid, join='left', axis=1)
X_train, X_test = X_train.align(X_test, join='left', axis=1)

لقد واجهت أيضًا نفس المشكلة عدة مرات. لقد كتبت فصلًا (أخذ الأفكار من هذه المناقشة) أدناه مما جعل الأمور أسهل بالنسبة لي.

import pandas
from sklearn.preprocessing import LabelEncoder

class CategoryEncoder:
    '''
    labelEncoding : boolean -> True If the categorical columns are to be label encoded
    oneHotEncoding : boolean -> True If the categorical columns are to be one hot encoded (using pandas.get_dummies method)
    dropFirst : boolean -> True if first column is to be dropped (usually to avoid multi-collinearity) post one hot encoding
                           Doesn't matter if oneHotEncoding = False

    df : pandas.DataFrame() -> dataframe object that needs to be encoded
    catCols : list -> list of the categorical columns that need to be encoded
    '''
    def __init__(self,labelEncoding=True,oneHotEncoding=False,dropFirst=False):
        self.labelEncoding = labelEncoding
        self.oneHotEncoding = oneHotEncoding
        self.dropFirst = dropFirst
        self.labelEncoder = {}
        self.oneHotEncoder = {}

    def fit(self,df,catCols=[]):
        df1 = df.copy()
        if self.labelEncoding:
            for col in catCols:
                labelEncoder = LabelEncoder()
                labelEncoder.fit(df1.loc[:,col].astype(str))
                df1.loc[:,col] = labelEncoder.transform(df1.loc[:,col])
                self.labelEncoder[col] = labelEncoder.classes_

        if self.oneHotEncoding:
            for col in catCols:
                cats = sorted(df1.loc[:,col].value_counts(dropna=True).index)
                self.oneHotEncoder[col] = cats

    def transform(self,df,catCols=[]):
        df1 = df.copy()
        if self.labelEncoding:
            for col in catCols:
                labelEncoder = self.labelEncoder[col]
                labelEncoder = {v:i for i,v in enumerate(labelEncoder.tolist())}
                print(labelEncoder)
                df1.loc[:,col] = df1.loc[:,col].map(labelEncoder)

        if self.oneHotEncoding:
            for col in catCols:
                oneHotEncoder = self.oneHotEncoder[col]
                df1.loc[:,col] = df1.loc[:,col].astype(pandas.CategoricalDtype(categories=oneHotEncoder))
            df1 = pandas.get_dummies(df1,columns=catCols,drop_first=self.dropFirst)

        return df1

من السهل بدء واستخدام مثيل برنامج التشفير أيضًا.

enc1 = CategoryEncoder(True,False)     # Will label encode but not one-hot encode
enc2 = CategoryEncoder(False,True,True)     # Will one-hot encode but not label encode
enc3 = CategoryEncoder(True,True,True)     # Will label encode first and then one-hot encode

# List of categorical columns you want to encode
categorical_columns = ['col_1', 'col_2']

enc1.fit(train_df, categorical_columns)
enc1.transform(test_df, categorical_columns) # Returns the dataframe encoded columns

ملاحظة: لن يعتني ذلك بأي استثناءات ، مثل تمرير أسماء الأعمدة غير المتوفرة في إطار البيانات

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات
يستخدم موقع bleepcoder.com معلومات GitHub المرخصة بشكل عام لتزويد المطورين حول العالم بحلول لمشاكلهم. نحن لسنا تابعين لشركة GitHub، Inc. أو مع أي مطورين يستخدمون GitHub لمشاريعهم. نحن لا نستضيف أيًا من مقاطع الفيديو أو الصور على خوادمنا. جميع الحقوق تنتمي إلى أصحابها.
مصدر هذه الصفحة: مصدر

لغات البرمجة الشعبية
مشاريع GitHub الشعبية
المزيد من مشاريع GitHub

© 2024 bleepcoder.com - Contact
Made with in the Dominican Republic.
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.