July 22, 2022

Корректное применение преобразований к выборкам

Рассмотрим, как правильно применять масштабирование и кодирование в условиях наличия нескольких выборок и разных типов колонок. Пусть мы работаем со следующим датафреймом:

import pandas as pd
import numpy as np
np.random.seed(0)

df = pd.DataFrame([['food', 'apple', 20], ['not_food', 'ball', 10], 
                   ['not_food', 'basket', 10],['food', 'banana', 12], 
                   ['food', 'apple', 23]], columns=['cat1', 'cat2', 'num'], 
                   index=['one', 'two', 'three', 'four', 'five'])
# мешаем
df = df.sample(frac=1)
df

Разделим набор на выборки и выделим категориальные и числовые колонки:

tr_idx, val_idx, ts_idx = np.split(np.arange(df.shape[0]), [round(0.6*df.shape[0]), round(0.8*df.shape[0])])
X_tr, X_val, X_ts = df.copy().iloc[tr_idx], df.copy().iloc[val_idx], df.copy().iloc[ts_idx] 

cat_cols = ['cat1', 'cat2']
num_cols = ['num']

Обратите внимание, что для использованного способа деления необходимо не забыть перемешать данные, если только они не должны иметь определенный порядок.

Ниже показано, как обучить OneHotEncoder и трансформировать колонки в выборках:

from sklearn.preprocessing import OneHotEncoder

oh = OneHotEncoder(sparse=False, handle_unknown='ignore')

ar_tr = oh.fit_transform(X_tr[cat_cols])
ar_val = oh.transform(X_val[cat_cols])
ar_ts = oh.transform(X_ts[cat_cols])

X_tr_new = pd.concat([X_tr[['num']], 
                pd.DataFrame(ar_tr, columns=oh.get_feature_names_out(cat_cols), index=X_tr.index)], axis= 1)
X_val_new = pd.concat([X_val[['num']],
                pd.DataFrame(ar_val, columns=oh.get_feature_names_out(cat_cols), index=X_val.index)], axis= 1)
X_ts_new = pd.concat([X_ts[['num']], 
                pd.DataFrame(ar_ts, columns=oh.get_feature_names_out(cat_cols), index=X_ts.index)], axis= 1)

display(X_tr_new)
display(X_val_new)
display(X_ts_new)

В общем случае кодирование и масштабирование правильно настраивать (обучать) на тренировочной выборке (о других предполагаем, что модель ничего не знает). А вот преобразование применяется ко всем выборкам с использованием метода transform.

Шкалирование численной колонки для всех выборок приведено ниже:

from sklearn.preprocessing import StandardScaler

sc = StandardScaler()

X_tr_new[num_cols] = sc.fit_transform(X_tr_new[num_cols])
X_val_new[num_cols] = sc.transform(X_val_new[num_cols])
X_ts_new[num_cols] = sc.transform(X_ts_new[num_cols])

display(X_tr_new)
display(X_val_new)
display(X_ts_new)

Теперь все колонки итоговых выборок преобразованы и готовы к дальнейшему использованию. Отмечу, что во избежание трудностей с использованием преобразований лучше их применять в пайплайнах.

Полезные ссылки:

  1. Композитная трансформация колонок
  2. Создание пайплайнов предобработки данных

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

Яндекс Дзен

Telegram