Как отменить Label Encoder от sklearn для нескольких столбцов? - PullRequest
0 голосов
/ 03 октября 2019

Я хотел бы использовать функцию inverse_transform для LabelEncoder для нескольких столбцов.

Этот код я использую для нескольких столбцов при применении LabelEncoder на фрейме данных:

class MultiColumnLabelEncoder:
    def __init__(self,columns = None):
        self.columns = columns # array of column names to encode

    def fit(self,X,y=None):
        return self # not relevant here

    def transform(self,X):
        '''
        Transforms columns of X specified in self.columns using
        LabelEncoder(). If no columns specified, transforms all
        columns in X.
        '''
        output = X.copy()
        if self.columns is not None:
            for col in self.columns:
                output[col] = LabelEncoder().fit_transform(output[col])
        else:
            for colname,col in output.iteritems():
                output[colname] = LabelEncoder().fit_transform(col)
        return output

    def fit_transform(self,X,y=None):
        return self.fit(X,y).transform(X)

Есть ли способ изменить код и изменить его так, чтобы он использовался для инвертирования меток из кодировщика?

Спасибо

Ответы [ 2 ]

1 голос
/ 04 октября 2019

Вам не нужно изменять его таким образом. Он уже реализован как метод inverse_transform.

Пример:

from sklearn import preprocessing

le = preprocessing.LabelEncoder()
df = ["paris", "paris", "tokyo", "amsterdam"]

le_fitted = le.fit_transform(df)

inverted = le.inverse_transform(le_fitted)

print(inverted)
# array(['paris', 'paris', 'tokyo', 'amsterdam'], dtype='|S9')
0 голосов
/ 04 октября 2019

Для обратного преобразования данных вам необходимо запомнить кодировщики, которые использовались для преобразования каждого столбца. Возможный способ сделать это - сохранить LabelEncoder в поле внутри вашего объекта. Как это будет работать:

  • при вызове fit кодеры для каждого столбца подгоняются и сохраняются
  • при вызове transform они используются для преобразования данных
  • когда вы звоните inverse_transform, они привыкли делать обратное преобразование

Пример кода:

class MultiColumnLabelEncoder:

    def __init__(self, columns=None):
        self.columns = columns # array of column names to encode


    def fit(self, X, y=None):
        self.encoders = {}
        columns = X.columns if self.columns is None else self.columns
        for col in columns:
            self.encoders[col] = LabelEncoder().fit(X[col])
        return self


    def transform(self, X):
        output = X.copy()
        columns = X.columns if self.columns is None else self.columns
        for col in columns:
            output[col] = self.encoders[col].transform(X[col])
        return output


    def fit_transform(self, X, y=None):
        return self.fit(X,y).transform(X)


    def inverse_transform(self, X):
        output = X.copy()
        columns = X.columns if self.columns is None else self.columns
        for col in columns:
            output[col] = self.encoders[col].inverse_transform(X[col])
        return output

Затем вы можете использовать его так:

multi = MultiColumnLabelEncoder(columns=['city','size'])
df = pd.DataFrame({'city':    ['London','Paris','Moscow'],
                   'size':    ['M',     'M',    'L'],
                   'quantity':[12,       1,      4]})
X = multi.fit_transform(df)
print(X)
#    city  size  quantity
# 0     0     1        12
# 1     2     1         1
# 2     1     0         4
inv = multi.inverse_transform(X)
print(inv)
#      city size  quantity
# 0  London    M        12
# 1   Paris    M         1
# 2  Moscow    L         4

Может существовать отдельная реализация fit_transform, которая будет вызывать тот же метод LabelEncoder s. Просто убедитесь, что кодировщики всегда рядом, когда вам нужно обратное преобразование.

...