June 13, 2022

Порядок обучения и запуска преобразователей данных

Порядок обучения и запуска преобразователей данных (например, классов для кодирования, масштабирования) и алгоритмов машинного обучения схожи. Главное правило - действовать как в реальной ситуации, где у вас есть набор данных, которые можно использовать для обучения модели и отдельно некие объекты с неизвестной целевой переменной, которую надо предсказать (например, база с характеристиками квартир и их стоимостью для обучения, а для предсказания - новые квартиры, цену которых нужно найти по их характеристикам). Для имитации схожих условий на опыте имеющийся датасет делят на части, одну используют для обучения (предполагается, что в ней вы знаете все), а другие - для валидации и тестирования (предполагается, что о них на этапе обучения ничего не известно). Валидационную часть используют для подбора модели, гиперпараметров, пайпланов предобработки, а тестовую для получения объективной оценки качества лучшей модели (первую для этого использовать нельзя, так как по ней вы уже подбирали модель и оценка будет чересчур оптимистичной).

Соответственно, этапы настройки преобразователей (кодирование, масштабирование) следует проводить на тренировочной части без использования других выборок. В части случаев нарушение этого условия чревато утечкой информации из целевой переменной, например, в случае категориального кодирования методом "target encoding". Допустим, вы предсказываете стоимость недвижимости и категорию населенного пункта хотите заменить средней ценой. Чтобы объективно оценить качество модели с таким преобразователем, необходимо, чтобы категории валидационной и тестовой выборки ни в коем случае не формировались с учетом информации о цене входящих в нее объектов. Иначе будет выглядеть так, что вы предсказываете стоимость жилья, уже зная ее и используя эту информацию.
Продемонстрируем, как правильно делать "target encoding". Пусть у нас есть следующие выборки:

import pandas as pd

# наши 3 выборки
df_train = pd.DataFrame([['fourth_cat1', 'third_cat2', 1], 
                         ['first_cat1', 'third_cat2', 1], 
                         ['second_cat1', 'third_cat2', 2], 
                         ['second_cat1', 'second_cat2', 5]], columns=['cat1', 'cat2', 'target'])

df_valid = pd.DataFrame([['fifth_cat1', 'third_cat2', 1], 
                        ['second_cat1', 'third_cat2', 1], 
                        ['second_cat1', 'second_cat2', 3]], columns=['cat1', 'cat2', 'target'] )

df_test = pd.DataFrame([['fifth_cat1', 'third_cat2', 3], 
                        ['first_cat1', 'third_cat2', 3], 
                        ['first_cat1', 'second_cat2', 3]], columns=['cat1', 'cat2', 'target'])

Рассмотрим процесс преобразования двух категориальная колонок с TargetEncoder из библиотеки category_encoders (подробнее о принципах преобразования можно прочитать здесь):

import category_encoders as ce
enc = ce.TargetEncoder()

df_train_sc = enc.fit_transform(df_train.drop(columns='target'),df_train['target'])
df_train_sc
df_valid_sc = enc.transform(df_valid.drop(columns='target'))
df_valid_sc
df_test_sc = enc.transform(df_test.drop(columns='target'))
df_test_sc

Еще правильнее использовать энкодеры внутри пайплайнов (писал здесь). Так, вам проще не запутаться с выборками:

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

tr = Pipeline(steps=[('te', ce.TargetEncoder()),('sc', MinMaxScaler())])
tr.fit_transform(df_train.drop(columns='target') ,df_train['target'])
tr.transform(df_test.drop(columns='target'))

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

Яндекс Дзен

Telegram