Для тех, кто работает в Python. Пост показывает ответы на два вопроса:
Код
Загружаем пакеты
- Препроцессинг категориальных переменных с помощью sklearn pipeline;
- Использование LabelEncoder в sklearn pipeline
Код
Загружаем пакеты
import pandas as pd import numpy as np from sklearn import preprocessing from sklearn.preprocessing import LabelEncoder import sklearn from sklearn.pipeline import Pipeline from sklearn.pipeline import FeatureUnion from sklearn import linear_model df= pd.DataFrame({ 'y': [10,2,3,4,5,6,7,8], 'a': ['a', 'b','a', 'b','a', 'b','a', 'b' ], 'b': ['a', 'b','a', 'b','a', 'b','b', 'b' ], 'c': ['a', 'b','a', 'a','a', 'b','b', 'b' ]}) dfОпределяем объект типа class для отбора категориальных переменных из датасета.
class MultiColumn(): def __init__(self,columns = None): self.columns = columns # array of column names to encode def fit(self,X,y=None): return self def transform(self, X): return X[self.columns]
Теперь собственно определяю class для препроцессинга категориальных переменных с применением LabelEncoder.
lb = df[['a', 'c']] class MyLEncoder(): def transform(self, X, **fit_params): enc = preprocessing.LabelEncoder() enc_data = [] for i in list(lb.columns): encc = enc.fit(lb[i]) enc_data.append(encc.transform(X[i])) return np.asarray(enc_data).T def fit_transform(self, X,y=None, **fit_params): self.fit(X,y, **fit_params) return self.transform(X) def fit(self, X, y, **fit_params): return self
lb - это набор категориальных переменных, на которых мы делаем препроцессинг. Такой код необходим для решения двух проблем:
- количество уровней категориальной переменной тренировочного набора данных и нового набора данных могу различаться;
- LabelEncoder работает только на единичном векторе данных, но в нашем наборе данных может быть несколько переменных, поэтому, чтобы не делать под каждую переменную свой class, я зашил цикл.
Ниже собственно Pipeline (я беру три категориальные переменные в датасете, но использую две просто потому, что показать, что мы можем работать с любым числом категориальных переменных)
X = df[['a', 'b', 'c']] y = df['y'] regressor = linear_model.SGDRegressor() pipeline = Pipeline([ # Use FeatureUnion to combine the features ('union', FeatureUnion( transformer_list=[ # categorical ('categorical', Pipeline([ ('selector', MultiColumn(columns=['a', 'c'])), ('one_hot', MyLEncoder()) ])), # year ])), # Use a regression ('model_fitting', linear_model.SGDRegressor()), ]) pipeline.fit(X, y) pipeline.predict(X) array([1.00799316, 1.95769819, 1.00799316, 1.44773543, 1.00799316, 1.95769819, 1.51795593, 1.95769819])И проверим, работает ли Pipeline на новых данных
new= pd.DataFrame({ 'y': [3, 8], 'a': ['a', 'b' ],'c': ['b', 'a' ], 'b': [3, 6],}) pipeline.predict(new) array([1.51795593, 1.44773543])На этом все. Не уверен, что это самый простой способ препроцессинга категориальных переменных с помощью LabelEncoder в sklearn pipeline, буду благодарен, если выскажете свои замечания.
Комментариев нет:
Отправить комментарий