Создание пайплайнов предобработки данных
Рассмотрим легкий и эффективный способ объединения преобразований в цепочки. Загрузим тренировочный датасет:
from sklearn.datasets import load_diabetes from sklearn.metrics import mean_absolute_error, mean_absolute_percentage_error import pandas as pd import numpy as np np.random.seed(0) df, y = load_diabetes(return_X_y=True, as_frame=True) df['target'] = y display(df.head()) display(df.shape)
Разобьем данные на тренировочный и тестовый наборы:
from sklearn.model_selection import train_test_split X_tr, X_ts, y_tr, y_ts = train_test_split(df.drop(columns='target').copy(), df['target'], test_size=0.2) y_tr.shape[0], y_ts.shape[0]
Теперь предскажем значения target с использованием линейной регрессии (Ridge) и посчитаем ошибки (абсолютную и процентную):
from sklearn.linear_model import Ridge model = Ridge() model.fit(X_tr, y_tr) y_p = model.predict(X_ts) print(f'{mean_absolute_error(y_ts, y_p):.2f}', f'{mean_absolute_percentage_error(y_ts, y_p):.3f}')
Так как для модели линейной регрессии желательно нормализовать признаки, применим StandardScaler, но включим его в качестве промежуточного шага в экземпляр класса Pipeline:
from sklearn.pipeline import Pipeline from sklearn.preprocessing import StandardScaler model = Pipeline(steps=[('prep', StandardScaler()), ('reg', Ridge())]) model.fit(X_tr, y_tr) y_p = model.predict(X_ts) print(f'{mean_absolute_error(y_ts, y_p):.3f}', f'{mean_absolute_percentage_error(y_ts, y_p):.3f}')
В Pipeline задается цепочка трансформаторов, после которых идет оценщик (фактически наша модель). Метод fit приводит к последовательному вызову fit, transform каждого трансформатора и только fit для оценщика. А predict - вызывает последовательность вызовов transform трансформаторов и predict оценщика.
Можно в качестве первого шага также задать композитную трансформацию колонок, например, категориальный столбец 'sex' не требует нормализации, зато его следует закодировать:
from sklearn.preprocessing import OneHotEncoder from sklearn.compose import make_column_transformer cat_cols = ['sex'] num_cols = df.drop(columns=['target', 'sex']).columns ct = make_column_transformer((OneHotEncoder(),cat_cols),(StandardScaler(), num_cols)) model = Pipeline(steps=[('prep', ct), ('reg', Ridge())]) model.fit(X_tr, y_tr) y_p = model.predict(X_ts) print(f'{mean_absolute_error(y_ts, y_p):.3f}', f'{mean_absolute_percentage_error(y_ts, y_p):.3f}')
Теперь перепишем последнюю ячейку вручную, чтобы лучше понимать, что происходит внутри:
sc = StandardScaler() X_tr[num_cols] = sc.fit_transform(X_tr[num_cols]) X_ts[num_cols]= sc.transform(X_ts[num_cols]) ohe = OneHotEncoder(sparse=False) ohe.fit(X_tr[cat_cols]) X_tr_cat = pd.DataFrame(ohe.transform(X_tr[cat_cols]), columns=ohe.get_feature_names(cat_cols), index=X_tr.index) X_ts_cat = pd.DataFrame(ohe.transform(X_ts[cat_cols]), columns=ohe.get_feature_names(cat_cols), index=X_ts.index)
X_tr = X_tr[num_cols].merge(X_tr_cat, left_index=True, right_index=True) X_ts = X_ts[num_cols].merge(X_ts_cat, left_index=True, right_index=True)
model = Ridge() model.fit(X_tr, y_tr) y_p = model.predict(X_ts) print(f'{mean_absolute_error(y_ts, y_p):.3f}',f'{mean_absolute_percentage_error(y_ts, y_p):.3f}')
Композитная трансформация колонок
Не пропустите ничего интересного и подписывайтесь на страницы канала в других социальных сетях: