Краткое введение в SciKit Pipelines
SciKit Pipelines Brief Introduction
И почему вам следует начать использовать их.
Вы когда-нибудь обучали модель машинного обучения, и ваши прогнозы выглядели слишком хорошо, чтобы быть правдой? Но потом вы поняли, что у вас была утечка данных между обучением и тестированием?
Или у вас было много предварительных обработок данных, чтобы подготовить их так, чтобы было сложно передать предварительные обработки из обучения модели в производство для фактических прогнозов?
Или ваша предварительная обработка становится беспорядочной, и трудно делиться вашим кодом в читаемой и понятной форме?
Тогда вам может захотеться попробовать scikit-learn
Pipeline. Pipeline – это элегантное решение для настройки вашего рабочего процесса для обучения, тестирования и производства МО, что делает вашу жизнь проще и ваши результаты более воспроизводимыми.
- Архетипы роли специалиста по обработке данных
- Начните изучать искусственный интеллект с серии обучающих материалов ODSC West Data Primer
- Databricks ❤️ Hugging Face ускорение обучения и настройки больших языковых моделей на 40%
Но что такое пайплайн, каковы его преимущества и как настроить пайплайн? Я рассмотрю эти вопросы и дам вам несколько примеров кода строительных блоков. Комбинируя эти строительные блоки, вы можете создавать более сложные пайплайны, которые соответствуют вашим потребностям.
Что такое пайплайн?
Пайплайн позволяет вам собирать несколько этапов в вашем рабочем процессе МО, которые последовательно преобразуют ваши данные перед передачей данных оценщику. Таким образом, пайплайн может состоять из этапов предварительной обработки, инженерии признаков и выбора признаков перед передачей данных финальному оценщику для задач классификации или регрессии.
Почему я должен использовать пайплайн?
В целом, использование пайплайна делает вашу жизнь проще и ускоряет разработку моделей МО. Это потому, что пайплайн
- приводит к более чистому и понятному коду
- легко воспроизводит и понимает рабочие процессы с данными
- легче читать и настраивать
- ускоряет подготовку данных, так как пайплайн автоматизирует подготовку данных
- помогает избежать утечки данных
- позволяет запускать оптимизацию гиперпараметров по всем оценщикам и параметрам в пайплайне одновременно
- удобен, так как вам нужно вызывать только
fit()
иpredict()
один раз для выполнения всего рабочего процесса с данными
После того, как вы обучили и оптимизировали свою модель и довольны результатами, вы можете легко сохранить обученный пайплайн. Затем, когда вы хотите запустить свою модель, просто загрузите предварительно обученный пайплайн, и вы готовы к некоторым выводам. Таким образом, вы можете легко делиться своей моделью очень чистым способом, который легко воспроизводится и понимается.
Как настроить пайплайн?
Настройка пайплайна с использованием scikit-learn
очень проста и прямолинейна.
scikit-learn
Pipeline
использует список пар ключ-значение, который содержит преобразователи, которые вы хотите применить к вашим данным в качестве значений. Ключи можно выбирать произвольно. Ключи могут использоваться для доступа к параметрам преобразователей, например, при выполнении поиска по сетке во время оптимизации гиперпараметров. Поскольку преобразователи хранятся в списке, вы также можете получить доступ к преобразователям по индексу.
Чтобы соответствовать данным в вашем пайплайне и делать прогнозы, вы можете запустить fit()
и predict()
, как вы это делаете с любым преобразователем или регрессором в scikit-learn
.
Очень простой пайплайн может выглядеть так:
from sklearn.impute import SimpleImputerfrom sklearn.pipeline import Pipelinefrom sklearn.preprocessing import MinMaxScalerfrom sklearn.linear_model import LinearRegressionpipeline = Pipeline( steps=[("imputer", SimpleImputer()), ("scaler", MinMaxScaler()), ("regression", LinearRegression()) ])pipeline.fit(X_train, y_train)y_pred = pipeline.predict(X_test)
scikit-learn
, однако, еще больше упрощает вашу жизнь, если вы не хотите вводить ключевые значения для ваших преобразователей. Вместо этого вы можете просто использовать функцию make_pipeline()
, и scikit-learn
устанавливает имена на основе класса преобразователя.
from sklearn.impute import SimpleImputerfrom sklearn.pipeline import make_pipelinefrom sklearn.preprocessing import MinMaxScalerfrom sklearn.linear_model import LinearRegressionpipeline = make_pipeline(steps=[ SimpleImputer(), MinMaxScaler(), LinearRegression() ])
Вот и все. Теперь у вас есть быстро настроенная простая конвейерная линия, которую вы можете использовать для обучения модели и выполнения предсказаний. Если вы хотите посмотреть, как выглядит ваша конвейерная линия, вы можете просто распечатать конвейер, и scikit-learn
покажет вам интерактивное представление конвейера.
Но что, если вы хотите создать что-то более сложное и настраиваемое? Например, обрабатывать категориальные и числовые значения по-разному, добавлять функции или преобразовывать целевое значение.
Не волнуйтесь, scikit-learn
предоставляет дополнительные функции, с помощью которых вы можете создавать более настраиваемые конвейеры и повышать их уровень. Эти функции:
ColumnTransformer
FeatureUnion
TransformedTargetRegressor
Я рассмотрю их и покажу вам примеры использования.
Преобразование выбранных признаков
Если у вас есть разные типы признаков, например, непрерывные и категориальные, вам, вероятно, захочется преобразовывать эти признаки по-разному. Например, масштабировать непрерывные признаки, в то время как категориальные признаки кодировать с помощью one-hot-кодирования.
Вы можете выполнить эти предварительные обработки перед передачей признаков в конвейер. Но, сделав это, вы не сможете включить эти предварительные обработки и параметры в ваш поиск гиперпараметров позже. Кроме того, включение их в конвейер упрощает работу с вашей моделью машинного обучения.
Чтобы применить преобразование или даже последовательность преобразований только к выбранным столбцам, вы можете использовать ColumnTransformer
. Использование очень похоже на использование Pipeline
: вместо передачи пары ключ-значение в steps
мы просто передаем те же пары в transformers
. Затем мы можем включить созданный преобразователь как один шаг в наш конвейер.
from sklearn.compose import ColumnTransformerfrom sklearn.pipeline import Pipelinefrom sklearn.preprocessing import OneHotEncodercategorical_transformer = ColumnTransformer( transformers=[("encode", OneHotEncoder())])pipeline = Pipeline(steps=[ ("categorical", categorical_transformer, ["col_name"]) ])
Поскольку мы хотим выполнить преобразование только для определенных столбцов, нам нужно передать эти столбцы в конвейер. Кроме того, мы можем сообщить ColumnTransformer
, что мы хотим сделать с оставшимися столбцами. Например, если вы хотите сохранить столбцы, которые не изменяются преобразователем, необходимо установить remainder
в значение passthrough
. В противном случае столбцы удаляются. Вместо того, чтобы ничего не делать или удалять столбцы, вы также можете преобразовать оставшиеся столбцы, передав преобразователь.
from sklearn.compose import ColumnTransformerfrom sklearn.preprocessing import MinMaxScaler, OneHotEncodercategorical_transformer = ColumnTransformer( transformers=[("encode", OneHotEncoder(), ["col_name"])], remainder="passthrough")categorical_transformer = ColumnTransformer( transformers=[("encode", OneHotEncoder(), ["col_name"])], remainder=MinMaxScaler())```
Поскольку scikit-learn
позволяет стекировать конвейеры, мы можем даже передать конвейер в ColumnTransformer
вместо указания каждого преобразования, которое мы хотим выполнить, в самом ColumnTransformer
.
from sklearn.compose import ColumnTransformerfrom sklearn.impute import SimpleImputerfrom sklearn.pipeline import Pipelinefrom sklearn.preprocessing import MinMaxScaler, OneHotEncodercategorical_transformer = Pipeline(steps=[("encode", OneHotEncoder())])numerical_transformer = Pipeline( steps=[("imputation", SimpleImputer()), ("scaling", MinMaxScaler())])preprocessor = ColumnTransformer( transfomers=[ ("numeric", numerical_transformer), ("categoric", categorical_transformer, ["col_name"]), ])pipeline = Pipeline(steps=["preprocesssing", preprocessor])
Комбинирование признаков
Теперь у вас есть возможность выполнять различные предварительные обработки для разных столбцов, но что, если вы хотите создать новые признаки из данных и добавить их в ваш набор признаков?
Для этого вы можете использовать FeatureUnion
, который объединяет объекты преобразователей в новый преобразователь с объединенными объектами. Запуск конвейера с FeatureUnion
независимо обучает каждый преобразователь, а затем объединяет их результаты.
Например, предположим, что мы хотим добавить скользящее среднее в качестве признака, мы можем сделать это следующим образом:
from sklearn.compose import FeatureUnionfrom sklearn.pipeline import Pipelinepreprocessor = ( FeatureUnion( [ ("moving_Average", MovingAverage(window=30)), ("numerical", numerical_pipeline), ] ),)pipeline = Pipeline(steps=["preprocesssing", preprocessor])
Преобразование целевого значения
Если у вас есть задача регрессии, иногда может помочь преобразование целевого значения перед подгонкой регрессии.
Вы можете включить такое преобразование с использованием класса TransformedTargetRegressor
. С помощью этого класса вы можете использовать как предоставленные scikit-learn
трансформаторы, такие как MinMaxScaler, так и написать свои собственные функции преобразования.
Одним из главных преимуществ TransformedTargetRegressor
является то, что он автоматически отображает прогнозы обратно в исходное пространство с помощью обратного преобразования. Таким образом, вам не нужно беспокоиться об этом позже, когда вы переходите от обучения модели к созданию прогнозов в производстве.
from sklearn.compose import TransformedTargetRegressorfrom sklearn.impute import SimpleImputerfrom sklearn.pipeline import Pipelinefrom sklearn.preprocessing import MinMaxScalerregressor = TransformedTargetRegressor( regressor=model, func=np.log1p, inverse_func=np.expm1)pipeline = Pipeline( steps=[ ("imputer", SimpleImputer()), ("scaler", MinMaxScaler()), ("regressor", regressor) ])pipeline.fit(X_train, y_train)y_pred = pipeline.predict(X_test)
Создание собственных пользовательских функций
Иногда недостаточно использовать предоставляемые scikit-learn
методы предварительной обработки. Однако это не должно останавливать вас при использовании конвейеров. Вы можете легко создать собственные функции, которые затем можно включить в конвейер.
Для этого вам нужно создать класс, который содержит методы fit()
и transform()
, так как они вызываются при выполнении конвейера. Однако эти методы не обязательно должны выполнять какие-либо действия. Кроме того, мы можем наследовать класс от классов BaseEstimator
и TransformerMixin
из scikit-learn
, чтобы получить некоторую базовую функциональность, которая нам нужна для конвейера.
Например, предположим, что мы хотим делать прогнозы по временным рядам и мы хотим сгладить все признаки с помощью скользящего среднего. Для этого мы просто создаем класс с методом transform
, который содержит часть сглаживания.
from sklearn.base import BaseEstimator, TransformerMixinfrom sklearn.impute import SimpleImputerfrom sklearn.pipeline import Pipelinefrom sklearn.preprocessing import MinMaxScalerclass MovingAverage(BaseEstimator, TransformerMixin): def __init__(self, window=30): self.window = window def fit(self, X, y=None): return self def transform(self, X, y=None): return X.rolling(window=self.window, min_periods=1, center=False).mean()pipeline = Pipeline( steps=[ ("ma", MovingAverage(window=30)), ("imputer", SimpleImputer()), ("scaler", MinMaxScaler()), ("regressor", model), ])pipeline.fit(X_train, y_train)y_pred = pipeline.predict(X_test)
Что еще нужно знать?
По умолчанию трансформаторы в scikit-learn
возвращают массив numpy. Это может привести к проблемам в вашем конвейере, если вы хотите применить преобразование только к определенным признакам на втором шаге конвейера, например, только категориальным признакам.
Однако, чтобы предотвратить поломку конвейера, вы можете изменить значение возврата по умолчанию всех трансформаторов на dataframe, указав
from sklearn import set_configset_config(transform_output = "pandas")
При выполнении гиперпараметрической оптимизации или при проверке отдельных параметров вашего конвейера может быть полезным получить доступ к параметрам непосредственно. Для доступа к параметрам вы можете использовать синтаксис <estimator>__<parameter>
. Например, в приведенном выше примере скользящего среднего мы могли бы получить доступ к ширине окна трансформатора MovingAverage, вызвав pipeline.set_params(pipeline__ma_window=7)
.
Вывод
Использование конвейера в scikit-learn
может существенно упростить вашу жизнь при разработке новых моделей машинного обучения и настройке предварительной обработки данных. Кроме множества преимуществ, настройка конвейера также проста и непринужденна. Однако вы можете создавать сложные и настраиваемые конвейеры предварительной обработки, в которых только ваша креативность ставит границы.
Если вам понравилась эта статья или у вас есть вопросы, не стесняйтесь оставить комментарий или обратиться ко мне. Меня также интересуют ваши опыт с использованием конвейера в scikit-learn
.
Вы хотите узнать больше о конвейерах, ознакомьтесь с следующей ссылкой:
- https://scikit-learn.org/stable/modules/compose.html#pipeline