❓ Почему трубопроводный и колонный трансформатор?

При работе над проектом машинного обучения наиболее утомительным этапом часто является этап очистки и предварительной обработки данных. Прежде всего, когда вы работаете в Jupyter Notebook, выполнение кода во многих ячейках может сбивать с толку.

Перед обучением модели данные должны быть помещены в обучающий набор и тестовый набор. Каждый набор данных пройдет этап очистки и предварительной обработки данных перед входом в модель машинного обучения. Неэффективно писать повторяющийся код для обучающего набора и тестового набора. Это когда трубопровод вступает в игру.

Pipeline и Column Transformer — это элегантные способы создания рабочего процесса предварительной обработки данных.

Во-первых, представьте, что вы можете создать только один конвейер, в который вы можете вводить любые данные, и эти данные будут преобразованы в соответствующий формат перед обучением или прогнозированием модели. Это сократит ваш код и облегчит его чтение и корректировку.

Приступаем к кодированию!!

💽 Набор данных

Данные, которые я использовал, взяты из



Вы можете найти мою статью об исследовании данных этого набора данных по ссылке ниже.



Короче говоря, этот набор данных содержит информацию о кандидатах на работу и их решении о том, следует ли менять работу или нет.

Цель:предсказать, изменит ли кандидат работу, на основе полученной информации (задача классификации).

🛣️ Конвейер и ColumnTransformer

Между Pipeline и ColumnTransformer есть большая разница, которую вы должны понимать.

Конвейер: используйте для нескольких преобразований одних и тех же столбцов.

ColumnTransformer: используйте для преобразования каждого набора столбцов по-разному.

⚠️ ColumnTransformer не преобразует шаг за шагом, а преобразует каждый шаг отдельно, а затем объединяется.

🗺️ План предварительной обработки данных

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

Шаг 1: Укажите, какие наборы столбцов будут преобразованы различными способами.

числовые и категориальные должны преобразовываться по-разному, поэтому я определяю num_col для числового столбца (числа) и cat_cols для категориальных столбцов.

num_cols = ['city_development_index','relevent_experience', 'experience','last_new_job', 'training_hours']
cat_cols = ['gender', 'enrolled_university', 'education_level', 'major_discipline', 'company_size', 'company_type']

Шаг 2. Разделите данные на наборы для обучения и тестирования

Разделите 20 процентов данных на тестовый набор.

from sklearn.model_selection import train_test_split
X = df[num_cols+cat_cols]
y = df['target']
# train test split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, stratify=y)

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

Шаг 3. Создайте пайплайны для числовых и категориальных функций

Синтаксис конвейера

Pipeline(steps = [(‘имя шага’, функция преобразования), …])

Для числовых функций я выполняю
1. SimpleImputer для заполнения пропущенного значения средним значением этого столбца.
2. MinMaxScaler для масштабирования значения в диапазоне от 0 до 1 (это повлияет на производительность регрессии).

Для категориальных функций я выполняю
1. SimpleImputer, чтобы заполнить пропущенное значение наиболее часто встречающимся значением этого столбца.
2. OneHotEncoder, чтобы выделить множество числовых столбцов для обучения модели. (handle_unknown='ignore' указывается для предотвращения ошибки при обнаружении невидимой категории в тестовом наборе)

from sklearn.impute import SimpleImputer
from sklearn.preprocessing import OneHotEncoder, MinMaxScaler
from sklearn.pipeline import Pipeline
num_pipeline = Pipeline(steps=[
    ('impute', SimpleImputer(strategy='mean')),
    ('scale',MinMaxScaler())
])
cat_pipeline = Pipeline(steps=[
    ('impute', SimpleImputer(strategy='most_frequent')),
    ('one-hot',OneHotEncoder(handle_unknown='ignore', sparse=False))
])

Шаг 4. Создайте ColumnTransformer, чтобы применить конвейер для каждого набора столбцов.

Синтаксис ColumnTransformer

ColumnTransformer(transformers=[(‘имя шага’, функция преобразования,столбцы), …])

Пропустите числовые столбцы через числовой конвейер и передайте категориальные столбцы через категориальный конвейер, созданный на шаге 3.

остаток='drop' указан для игнорирования других столбцов в фрейме данных.

n_job = -1 означает использование всех процессоров для параллельной работы.

from sklearn.compose import ColumnTransformer
col_trans = ColumnTransformer(transformers=[
    ('num_pipeline',num_pipeline,num_cols),
    ('cat_pipeline',cat_pipeline,cat_cols)
    ],
    remainder='drop',
    n_jobs=-1)

Шаг 5. Добавьте модель в окончательный конвейер

В этом примере я использую модель логистической регрессии.

Создайте новый конвейер для объединения ColumnTransformer на шаге 4 с моделью логистической регрессии. В этом случае я использую конвейер, потому что весь фрейм данных должен пройти этап ColumnTransformer и этап моделирования соответственно.

from sklearn.linear_model import LogisticRegression
clf = LogisticRegression(random_state=0)
clf_pipeline = Pipeline(steps=[
    ('col_trans', col_trans),
    ('model', clf)
])

Шаг 6. Отображение конвейера

дисплей (имя конвейера)

from sklearn import set_config
set_config(display='diagram')
display(clf_pipeline)

Вы можете нажать на отображаемое изображение, чтобы увидеть детали каждого шага. Какое удобство!!

Шаг 7. Передача данных через Pipeline

pipe.fit: передавать данные через конвейер. тоже подходит к модели.

pipe.predict: используйте модель, обученную, когда pipe.fit предсказывает новые данные.

pipe.score: получить оценку модели в конвейере (точность логистической регрессии в этом примере).

clf_pipeline.fit(X_train, y_train)
# preds = clf_pipeline.predict(X_test)
score = clf_pipeline.score(X_test, y_test)
print(f"Model score: {score}") # accuracy

(Необязательно) Шаг 8. Сохраните пайплайн

Используйте библиотеку joblib, чтобы сохранить конвейер для последующего использования, чтобы вам не нужно было снова создавать и настраивать конвейер. Если вы хотите использовать сохраненный конвейер, просто загрузите файл с помощью joblib.load.

import joblib
# Save pipeline to file "pipe.joblib"
joblib.dump(clf_pipeline,"pipe.joblib")
# Load pipeline when you want to use
same_pipe = joblib.load("pipe.joblib")

Заключение

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

Любая обратная связь приветствуется!