Введение
В этом лабораторном занятии мы научимся использовать класс TargetEncoder из библиотеки Scikit-learn. Целевое кодирование (target encoding) — это техника, используемая для преобразования категориальных данных в числовые, которые могут быть использованы в качестве входных данных для алгоритмов машинного обучения. Класс TargetEncoder заменяет каждую категорию категориального признака средним значением целевой переменной для этой категории. Этот метод полезен в случаях, когда между категориальным признаком и целевой переменной существует сильная связь.
Советы по виртуальной машине
После запуска виртуальной машины (VM) нажмите в левом верхнем углу, чтобы переключиться на вкладку Notebook и получить доступ к Jupyter Notebook для практики.
Иногда вам может потребоваться подождать несколько секунд, пока Jupyter Notebook загрузится. Валидация операций не может быть автоматизирована из-за ограничений Jupyter Notebook.
Если у вас возникнут проблемы во время обучения, не стесняйтесь обращаться к Labby. После занятия дайте обратную связь, и мы оперативно решим проблему для вас.
Установка необходимых библиотек
Сначала нам нужно установить необходимые библиотеки. Мы будем использовать библиотеки Scikit-learn, Pandas и Matplotlib. Выполните следующую команду для установки этих библиотек:
!pip install scikit-learn pandas matplotlib
Импорт необходимых библиотек
Далее нам нужно импортировать необходимые библиотеки. Выполните следующий код для импорта требуемых библиотек:
import numpy as np
import pandas as pd
from sklearn.preprocessing import KBinsDiscretizer, TargetEncoder
from sklearn.linear_model import Ridge
from sklearn.pipeline import make_pipeline
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
Создание синтетического набора данных
В этом лабораторном занятии мы создадим синтетический набор данных с тремя категориальными признаками: информативным признаком со средней мощностью (cardinality), неинформативным признаком со средней мощностью и неинформативным признаком с высокой мощностью. Мы будем использовать класс KBinsDiscretizer из библиотеки Scikit-learn для генерации информативного признака. Выполните следующий код для создания синтетического набора данных:
n_samples = 50_000
rng = np.random.RandomState(42)
y = rng.randn(n_samples)
noise = 0.5 * rng.randn(n_samples)
n_categories = 100
kbins = KBinsDiscretizer(
n_bins=n_categories, encode="ordinal", strategy="uniform", random_state=rng
)
X_informative = kbins.fit_transform((y + noise).reshape(-1, 1))
permuted_categories = rng.permutation(n_categories)
X_informative = permuted_categories[X_informative.astype(np.int32)]
X_shuffled = rng.permutation(X_informative)
X_near_unique_categories = rng.choice(
int(0.9 * n_samples), size=n_samples, replace=True
).reshape(-1, 1)
X = pd.DataFrame(
np.concatenate(
[X_informative, X_shuffled, X_near_unique_categories],
axis=1,
),
columns=["informative", "shuffled", "near_unique"],
)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
Обучение регрессора Ridge на исходных данных
В этом разделе мы обучим регрессор Ridge на наборе данных с и без кодирования и исследуем влияние целевого кодировщика (target encoder) с и без интервального кросс-валидации. Сначала мы обучим модель Ridge на исходных признаках. Выполните следующий код для обучения модели Ridge:
ridge = Ridge(alpha=1e-6, solver="lsqr", fit_intercept=False)
raw_model = ridge.fit(X_train, y_train)
print("Raw Model score on training set: ", raw_model.score(X_train, y_train))
print("Raw Model score on test set: ", raw_model.score(X_test, y_test))
Обучение регрессора Ridge с кросс-валидацией
Далее мы создадим конвейер (pipeline) с TargetEncoder и моделью Ridge. Конвейер использует TargetEncoder.fit_transform, который применяет кросс-валидацию. Выполните следующий код для обучения модели Ridge с кросс-валидацией:
model_with_cv = make_pipeline(TargetEncoder(random_state=0), ridge)
model_with_cv.fit(X_train, y_train)
print("Model with CV on training set: ", model_with_cv.score(X_train, y_train))
print("Model with CV on test set: ", model_with_cv.score(X_test, y_test))
Оценка коэффициентов линейной модели с кросс-валидацией
Коэффициенты линейной модели показывают, что основная часть веса приходится на признак с индексом столбца 0, который является информативным признаком. Выполните следующий код для оценки коэффициентов линейной модели с кросс-валидацией:
coefs_cv = pd.Series(
model_with_cv[-1].coef_, index=model_with_cv[-1].feature_names_in_
).sort_values()
_ = coefs_cv.plot(kind="barh")
Обучение регрессора Ridge без кросс-валидации
В то время как TargetEncoder.fit_transform использует интервальную кросс-валидацию, сам метод TargetEncoder.transform не выполняет никакой кросс-валидации. Он использует агрегацию всего обучающего набора данных для преобразования категориальных признаков. Таким образом, мы можем использовать TargetEncoder.fit с последующим вызовом TargetEncoder.transform для отключения кросс-валидации. Затем это закодированное представление передается модели Ridge. Выполните следующий код для обучения модели Ridge без кросс-валидации:
target_encoder = TargetEncoder(random_state=0)
target_encoder.fit(X_train, y_train)
X_train_no_cv_encoding = target_encoder.transform(X_train)
X_test_no_cv_encoding = target_encoder.transform(X_test)
model_no_cv = ridge.fit(X_train_no_cv_encoding, y_train)
print(
"Model without CV on training set: ",
model_no_cv.score(X_train_no_cv_encoding, y_train),
)
print(
"Model without CV on test set: ", model_no_cv.score(X_test_no_cv_encoding, y_test)
)
Оценка коэффициентов линейной модели без кросс-валидации
Модель Ridge переобучается, так как она придает больший вес признаку с чрезвычайно высокой мощностью (cardinality) по сравнению с информативным признаком. Выполните следующий код для оценки коэффициентов линейной модели без кросс-валидации:
coefs_no_cv = pd.Series(
model_no_cv.coef_, index=model_no_cv.feature_names_in_
).sort_values()
_ = coefs_no_cv.plot(kind="barh")
Резюме
В этом практическом занятии (lab) мы научились использовать класс TargetEncoder из библиотеки Scikit-learn для преобразования категориальных данных в числовые данные, которые могут быть использованы в качестве входных данных для алгоритмов машинного обучения. Мы также узнали о важности интервальной кросс-валидации для предотвращения переобучения. Мы обучили модель Ridge на исходных данных и оценили ее производительность. Мы также обучили модель Ridge с использованием кросс-валидации и оценили коэффициенты линейной модели. Наконец, мы обучили модель Ridge без кросс-валидации и оценили коэффициенты линейной модели.