June 22, 2022

Создание пользовательских преобразователей данных

Рассмотрим, как готовить собственные преобразователи данных (трансформеры) так, чтобы они поддерживались механизмами последовательной обработки, реализованными в библиотеке Scikit-learn. Для демонстрации работы создадим обучающие датафреймы:

import pandas as pd

df_train = pd.DataFrame([['fourth_cat1', 'third_cat2', 1], 
                         ['first_cat1', 'third_cat2', 1], 
                         ['second_cat1', 'third_cat2', 2], 
                         ['second_cat1', 'second_cat2', 5]])


df_valid = pd.DataFrame([['fifth_cat1', 'third_cat2'], 
                        ['second_cat1', 'third_cat2'], 
                        ['second_cat1', 'second_cat2']])

Использование трансформатора предполагает его обучение методом fit и запуск методом transform. Они охватывают основной функционал преобразователя и требуют самостоятельной реализации. Такие имена методов нужны для поддержки в инструментах sklearn. Кроме того, для этих же целей реализуйте трансформаторы в виде классов, наследующих TransformerMixin и BaseEstimator из sklearn.base. Это откроет новому классу автоматический доступ к методам fit_transform, get_param, set_param, необходимым для поддержки в пайплайнах, функциях подбора гиперпараметров. Для примера создадим трансформатор преобразования значений категориальных колонок датасета в среднее значение по целевой переменной:

from sklearn.base import TransformerMixin, BaseEstimator

class MeanEncoding(TransformerMixin, BaseEstimator):
    mean_d = {}
    
    def __init__(self, unknown_val = 0):
        self.unknown_val = unknown_val
        
    def fit(self, X, y):
        for col in X.select_dtypes(include=['category', 'object']).columns:
            self.mean_d[col] = y.groupby(X[col]).mean().to_dict()
        return self
    
    def transform(self, X):
        X_tr = X.copy()
        for col in X_tr.select_dtypes(include=['category', 'object']).columns:
            X_tr[col] = X_tr[col].map(lambda x: self.mean_d[col].get(x, self.unknown_val))
        return X_tr

Обучим и применим новый класс к тренировочной выборке:

enc = MeanEncoding(unknown_val=-5)
enc.fit_transform(df_train.drop(columns=2), df_train[2])

Выведем созданный словарь для хранения значений категорий и применим класс к валидационной выборке:

enc.mean_d
enc.transform(df_valid)

Так как мы соблюли правила создания трансформера, его можно встраивать в пайплайны:

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import MinMaxScaler

tr = Pipeline(steps=[('mean', MeanEncoding()),('sc', MinMaxScaler())])
tr.fit_transform(df_train.drop(columns=2),df_train[2])

и применим пайплайн к валидационному набору:

tr.transform(df_valid)

Не пропустите ничего интересного и подписывайтесь на страницы канала в других социальных сетях:

Яндекс Дзен

Telegram