Оптимизация рабочих процессов машинного обучения: использование возможностей конвейеров

Конвейер — это способ упростить и автоматизировать процесс создания и оценки моделей машинного обучения путем объединения нескольких шагов обработки данных и окончательной оценки (модели) в единый объект.

В scikit-learn конвейер создается с использованием класса Pipeline и состоит из последовательности шагов предварительной обработки данных, за которыми следует окончательная оценка. Каждый шаг в конвейере представлен кортежем, где первый элемент — это строковый идентификатор шага, а второй элемент — экземпляр преобразователя или оценщика.

классsklearn.pipeline.Конвейер(шаги, *, memory=None, verbose=False)

Давайте реализуем простой конвейер, используя набор данных Iris.

# load dataset
from sklearn.datasets import load_iris

data = load_iris()
X = data.data
y = data.target
print(X)
"""
[[5.1 3.5 1.4 0.2]
 [4.9 3.  1.4 0.2]
 [4.7 3.2 1.3 0.2]
 [4.6 3.1 1.5 0.2]
 [5.  3.6 1.4 0.2]
 [5.4 3.9 1.7 0....
"""

Набор данных Iris содержит только числовые характеристики, представляющие различные атрибуты цветков ириса.

# split the data
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, shuffle=True)

Мы создаем конвейер с шагом предварительной обработки (StandardScaler) для масштабирования числовых признаков и окончательной оценкой (LogisticRegression) для классификации.

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression

pipeline = Pipeline([
    ('scaler', StandardScaler()),        
    ('classifier', LogisticRegression())
])

Когда мы вызываем fit() в конвейере, он последовательно применяет предварительную обработку, а затем обучает оценщик. Точно так же, когда вы вызываете predict() или score(), данные автоматически предварительно обрабатываются перед прогнозированием или оценкой модели.

# Fit the pipeline to the training data
pipeline.fit(X_train, y_train)

# Predict using the fitted pipeline
predictions = pipeline.predict(X_test)

# Evaluate the model
accuracy = pipeline.score(X_test, y_test)
accuracy
# 1.0

В предыдущем примере мы применили идентичный метод преобразования ко всем объектам в нашем наборе данных. Однако на практике часто возникает необходимость применять разные методы к каждому признаку. Для этого мы можем эффективно использовать класс FunctionTransformer.

sklearn.preprocessing.FunctionTransformer позволяет нам создать преобразователь, который применяет указанную функцию к входным данным.

Давайте создадим два экземпляра масштабатора. Мы будем использовать StandardScaler для первых двух функций и MinMaxScaler для двух других функций.

Функция preprocessing принимает X в качестве входных данных и возвращает новую матрицу с масштабированными функциями.

import numpy as np
from sklearn.preprocessing import StandardScaler, MinMaxScaler, FunctionTransformer

s_scaler = StandardScaler()
m_scaler = MinMaxScaler()
s_scaler.fit(X_train[:,:2])
m_scaler.fit(X_train[:,2:])

def preprocessing(X):
    X_copy = np.copy(X)
    X_copy[:,:2] = s_scaler.transform(X[:,:2])
    X_copy[:,2:] = m_scaler.transform(X[:,2:])
    return X_copy

preprocessing_transfomer = FunctionTransformer(preprocessing)

FunctionTransformer создается с помощью функции preprocessing в качестве аргумента. Этот преобразователь инкапсулирует пользовательскую логику предварительной обработки.

Теперь мы можем определить новый конвейер.

pipeline = Pipeline([
    ('scaler', preprocessing_transfomer),        
    ('classifier', LogisticRegression())
])
pipeline

# Fit the pipeline to the training data
pipeline.fit(X_train, y_train)

# Predict using the fitted pipeline
predictions = pipeline.predict(X_test)

# Evaluate the model
accuracy = pipeline.score(X_test, y_test)
accuracy

Кроме того, мы можем изготовить индивидуальные трансформаторы. BaseEstimator и TransformerMixin — это два класса миксинов, предоставляемые sklearn, которые служат основой для создания пользовательских оценок и преобразователей. В конвейере последовательно применяется список преобразований и имеется окончательная оценка. Промежуточные этапы конвейера должны быть «преобразованиями», то есть они должны иметь методы fit и transform. Окончательный оценщик требует только реализации метода fit.

Класс BaseEstimator обеспечивает базовую реализацию оценщика в scikit-learn. Чтобы создать собственный оценщик, мы обычно определяем собственный класс, который наследуется от BaseEstimator и реализует необходимые методы, включая fit() и predict() (для обучения с учителем) или fit() и transform() (для обучения без учителя). Благодаря этому наш пользовательский оценщик будет хорошо интегрироваться с инфраструктурой scikit-learn.

Класс TransformerMixin предоставляет удобный способ создания пользовательских преобразователей в scikit-learn. Чтобы создать собственный преобразователь, мы можем наследоваться от TransformerMixin и реализовать методы fit() и transform(). Таким образом, мы гарантируем, что ваш пользовательский преобразователь можно будет легко интегрировать в конвейеры scikit-learn и использовать вместе с другими преобразователями и оценщиками.

from sklearn.base import BaseEstimator, TransformerMixin

class ColumnDropper(BaseEstimator, TransformerMixin):
    
    def fit(self, X, y=None):
        return self
    
    def transform(self, X):
        return X[:,1:]

dropper= ColumnDropper()

X_d = dropper.fit_transform(X)
X_d

"""
array([[3.5, 1.4, 0.2],
       [3. , 1.4, 0.2],
       [3.2, 1.3, 0.2],
       [3.1, 1.5, 0.2],
       [3.6, 1.4, 0.2],
       [3.9, 1.7, 0.4],
       ...
"""
pipeline = Pipeline([
    ('dropper', ColumnDropper()),
    ('scaler', StandardScaler()),        
    ('classifier', LogisticRegression())
])
pipeline

Мы можем получить обученные объекты масштабирования из пайплайна, используя атрибут named_steps. Этот атрибут обеспечивает доступ к отдельным компонентам (преобразователям и средствам оценки) конвейера по их именам. Затем мы можем сохранить эти обученные объекты масштабирования в файлы или папки для последующего использования в производстве.

s_scaler = pipeline.named_steps['scaler']

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

Читать далее











Источники

https://scikit-learn.org/stable/modules/generated/sklearn.pipeline.Pipeline.html#sklearn.pipeline.Pipeline

https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.FunctionTransformer.html

https://scikit-learn.org/stable/modules/generated/sklearn.base.BaseEstimator.html

https://scikit-learn.org/stable/modules/generated/sklearn.base.TransformerMixin.html#sklearn.base.TransformerMixin