И почему вам стоит начать их использовать.
Вы когда-нибудь обучали модель машинного обучения, и ваши прогнозы выглядели слишком хорошо, чтобы быть правдой? Но потом вы поняли, что между данными обучения и тестирования произошла некоторая утечка данных?
Или у вас было много этапов предварительной обработки для подготовки данных, поэтому было трудно перенести этапы предварительной обработки из обучения модели в производство для получения реальных прогнозов?
Или ваша предварительная обработка становится беспорядочной, и вам трудно поделиться кодом в читаемой и понятной форме?
Тогда вам, возможно, захочется попробовать Pipeline scikit-learn
. Pipeline — это элегантное решение для настройки рабочего процесса обучения, тестирования и производства машинного обучения, которое делает вашу жизнь проще, а результаты — более воспроизводимыми.
Но что такое конвейер, каковы его преимущества и как его настроить? Я рассмотрю эти вопросы и приведу несколько примеров кода строительных блоков. Комбинируя эти строительные блоки, вы можете создавать более сложные конвейеры, адаптированные к вашим потребностям.
Что такое трубопровод?
Конвейер позволяет объединить несколько шагов в рабочем процессе машинного обучения, которые последовательно преобразуют ваши данные перед их передачей в оценщик. Следовательно, конвейер может состоять из этапов предварительной обработки, проектирования признаков и выбора признаков перед передачей данных в средство окончательной оценки для задач классификации или регрессии.
Почему мне следует использовать конвейер?
В целом использование конвейера упрощает вашу жизнь и ускоряет разработку моделей машинного обучения. Это потому, что трубопровод
- приводит к более чистому и понятному коду
- легко воспроизводить и понимать рабочие процессы с данными
- легче читать и корректировать
- ускоряет подготовку данных, поскольку конвейер автоматизирует подготовку данных
- помогает избежать утечки данных
- позволяет одновременно выполнять оптимизацию гиперпараметров для всех оценщиков и параметров в конвейере
- это удобно, поскольку вам нужно всего лишь один раз вызвать
fit()
иpredict()
, чтобы запустить весь конвейер данных.
После того как вы обучили и оптимизировали свою модель и остались довольны результатами, вы можете легко сохранить обученный конвейер. Затем, когда вы захотите запустить свою модель, просто загрузите предварительно обученный конвейер, и вы будете готовы сделать некоторые выводы. Благодаря этому вы можете легко поделиться своей моделью в очень чистом виде, который легко воспроизвести и понять.
Как настроить конвейер?
Настроить конвейер с помощью scikit-learn
очень просто и понятно.
Pipeline
из scikit-learn
использует список пар ключ-значение, который содержит преобразователи, которые вы хотите применить к своим данным в качестве значений. Ключи вы можете выбирать произвольно. Ключи можно использовать для доступа к параметрам преобразователей, например, при запуске поиска по сетке во время оптимизации гиперпараметров. Поскольку преобразователи хранятся в списке, вы также можете получить доступ к преобразователям путем индексации.
Чтобы разместить данные в вашем конвейере и сделать прогнозы, вы можете запустить fit()
и predict()
так же, как и с любым преобразователем или регрессором в scikit-learn
.
Очень простой конвейер может выглядеть так:
from sklearn.impute import SimpleImputer from sklearn.pipeline import Pipeline from sklearn.preprocessing import MinMaxScaler from sklearn.linear_model import LinearRegression pipeline = 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 SimpleImputer from sklearn.pipeline import make_pipeline from sklearn.preprocessing import MinMaxScaler from sklearn.linear_model import LinearRegression pipeline = make_pipeline(steps=[ SimpleImputer(), MinMaxScaler(), LinearRegression() ] )
Вот и все. Благодаря этому вы быстро создали простой конвейер, который можно начать использовать для обучения модели и выполнения прогнозов. Если вы хотите посмотреть, как выглядит ваш конвейер, вы можете просто распечатать его, и scikit-learn
покажет вам его интерактивное представление.
Но что, если вы хотите создать что-то более сложное и настраиваемое? Например, по-разному обрабатывайте категориальные и числовые значения, добавляйте функции или преобразуйте целевое значение.
Не беспокойтесь, scikit-learn
предоставляет дополнительные функции, с помощью которых вы можете создавать больше пользовательских конвейеров и вывести свои конвейеры на новый уровень. Эти функции:
ColumnTransformer
FeatureUnion
TransformedTargetRegressor
Я пройдусь по ним и покажу вам примеры того, как их использовать.
Преобразование выбранных объектов
Если у вас есть разные функции, например. например, непрерывные и категоричные, вы, вероятно, захотите преобразовать эти функции по-другому. Например, масштабируйте непрерывные признаки, одновременно кодируя категориальные признаки.
Вы можете выполнить эти шаги предварительной обработки перед передачей функций в конвейер. Но в этом случае вы не сможете позже включить эти шаги и параметры предварительной обработки в поиск гиперпараметров. Кроме того, включение их в конвейер значительно упрощает работу с вашей моделью машинного обучения.
Чтобы применить преобразование или даже последовательность преобразований только к выбранным столбцам, вы можете использовать ColumnTransformer
. Использование очень похоже на Pipeline
, поскольку вместо передачи пары ключ-значение в steps
мы просто передаем те же пары в transformers
. Затем мы можем включить созданный преобразователь в качестве одного из этапов нашего конвейера.
from sklearn.compose import ColumnTransformer from sklearn.pipeline import Pipeline from sklearn.preprocessing import OneHotEncoder categorical_transformer = ColumnTransformer( transformers=[("encode", OneHotEncoder())] ) pipeline = Pipeline(steps=[ ("categorical", categorical_transformer, ["col_name"]) ] )
Поскольку мы хотим запустить преобразование только для определенных столбцов, нам нужно передать эти столбцы в конвейер. Более того, мы можем сообщить ColumnTransformer
, что мы хотим делать с оставшимися столбцами. Например, если вы хотите сохранить столбцы, которые не были изменены преобразователем, вам необходимо установить remainder
на passthrough
. В противном случае столбцы удаляются. Вместо того, чтобы ничего не делать или удалять столбцы, вы также можете преобразовать оставшиеся столбцы, передав преобразователь.
from sklearn.compose import ColumnTransformer from sklearn.preprocessing import MinMaxScaler, OneHotEncoder categorical_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 ColumnTransformer from sklearn.impute import SimpleImputer from sklearn.pipeline import Pipeline from sklearn.preprocessing import MinMaxScaler, OneHotEncoder categorical_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 FeatureUnion from sklearn.pipeline import Pipeline preprocessor = ( FeatureUnion( [ ("moving_Average", MovingAverage(window=30)), ("numerical", numerical_pipeline), ] ), ) pipeline = Pipeline(steps=["preprocesssing", preprocessor])
Преобразование целевого значения
Если у вас есть проблема с регрессией, иногда это может помочь преобразовать цель перед подгонкой регрессии.
Вы можете включить такое преобразование, используя класс TransformedTargetRegressor
. С помощью этого класса вы можете либо использовать преобразователи, предоставляемые scikit-learn
, например масштабатор MinMax, либо писать свои собственные функции преобразования.
Одним из огромных преимуществ TransformedTargetRegressor
является то, что он автоматически отображает прогнозы обратно в исходное пространство с помощью обратного преобразования. Таким образом, вам не нужно беспокоиться об этом позже, когда вы перейдете от обучения модели к прогнозированию в производстве.
from sklearn.compose import TransformedTargetRegressor from sklearn.impute import SimpleImputer from sklearn.pipeline import Pipeline from sklearn.preprocessing import MinMaxScaler regressor = 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
. Однако это не должно сдерживать вас при использовании Pipelines. Вы можете легко создавать свои собственные функции, которые затем включать в конвейер.
Для этого вам необходимо создать класс, содержащий методы fit()
и transform()
, поскольку они вызываются при запуске конвейера. Однако эти методы не обязательно должны что-либо делать. Более того, мы можем позволить классу наследовать классы scikit-learn
BaseEstimator
и TransformerMixin
, чтобы предоставить нам некоторые базовые функции, необходимые нашему конвейеру.
Например, предположим, что мы хотим сделать прогноз для временного ряда и сгладить все функции с помощью скользящего среднего. Для этого мы просто создали класс с методом transform
, который содержит часть сглаживания.
from sklearn.base import BaseEstimator, TransformerMixin from sklearn.impute import SimpleImputer from sklearn.pipeline import Pipeline from sklearn.preprocessing import MinMaxScaler class 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
возвращают пустой массив. Это может привести к проблемам в вашем конвейере, если вы хотите применить преобразование только к определенным функциям на втором этапе конвейера, например, только к категориальным функциям.
Однако, чтобы предотвратить поломку вашего конвейера, вы можете изменить возвращаемое значение по умолчанию для всех преобразователей на кадр данных, указав
from sklearn import set_config set_config(transform_output = "pandas")
При оптимизации гиперпараметров или при проверке отдельных параметров конвейера может оказаться полезным прямой доступ к параметрам. Для доступа к параметрам вы можете использовать синтаксис <estimator>__<parameter>
syntax. Например, в приведенном выше примере скользящего среднего мы могли бы получить доступ к ширине окна преобразователя MovingAverage, вызвав pipeline.set_params(pipeline__ma_window=7)
.
Заключение
Использование Pipeline scikit-learn
может значительно облегчить вашу жизнь при разработке новых моделей машинного обучения и настройке этапов предварительной обработки. Помимо множества преимуществ, настройка Pipeline также проста и понятна. Тем не менее, вы можете создавать сложные и настраиваемые конвейеры предварительной обработки, границы которых устанавливает только ваше творчество.
Если вам понравилась эта статья или у вас есть вопросы, оставьте комментарий или свяжитесь со мной. Мне также интересен ваш опыт работы с Pipeline scikit-learn
.
Хотите узнать больше о Pipelines, перейдите по следующей ссылке: