Transformação de Dados Categóricos usando TargetEncoder

Beginner

This tutorial is from open-source community. Access the source code

Introdução

Neste laboratório, aprenderemos a utilizar a classe TargetEncoder da biblioteca Scikit-learn. A codificação alvo (Target encoding) é uma técnica usada para transformar dados categóricos em dados numéricos que podem ser usados como entrada para algoritmos de machine learning. O TargetEncoder substitui cada categoria de um atributo categórico pela média da variável alvo para essa categoria. Este método é útil em casos onde existe uma forte relação entre o atributo categórico e a variável alvo.

Dicas da Máquina Virtual

Após o arranque da VM, clique no canto superior esquerdo para mudar para a aba Notebook para aceder ao Jupyter Notebook para a prática.

Por vezes, pode ser necessário esperar alguns segundos para o Jupyter Notebook terminar de carregar. A validação das operações não pode ser automatizada devido a limitações no Jupyter Notebook.

Se tiver problemas durante o aprendizado, não hesite em contactar o Labby. Forneça feedback após a sessão e resolveremos o problema rapidamente para si.

Instalar Bibliotecas Necessárias

Primeiro, precisamos instalar as bibliotecas necessárias. Usaremos as bibliotecas Scikit-learn, Pandas e Matplotlib. Execute o comando a seguir para instalar essas bibliotecas:

!pip install scikit-learn pandas matplotlib

Importar Bibliotecas Necessárias

Em seguida, precisamos importar as bibliotecas necessárias. Execute o código a seguir para importar as bibliotecas necessárias:

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

Criar Conjunto de Dados Sintético

Para este laboratório, criaremos um conjunto de dados sintético com três características categóricas: uma característica informativa com cardinalidade média, uma característica não informativa com cardinalidade média e uma característica não informativa com alta cardinalidade. Usaremos a classe KBinsDiscretizer do Scikit-learn para gerar a característica informativa. Execute o código a seguir para criar o conjunto de dados sintético:

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)

Treinar um Regressor Ridge em Dados Brutos

Nesta seção, treinaremos um regressor Ridge no conjunto de dados com e sem codificação e exploraremos a influência do codificador de destino com e sem a validação cruzada por intervalos. Primeiro, treinaremos um modelo Ridge nas características brutas. Execute o código a seguir para treinar o modelo 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))

Treinar um Regressor Ridge com Validação Cruzada

Em seguida, criaremos um pipeline com o modelo TargetEncoder e Ridge. O pipeline utiliza TargetEncoder.fit_transform, que usa validação cruzada. Execute o código a seguir para treinar o modelo Ridge com validação cruzada:

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))

Avaliar os Coeficientes do Modelo Linear com Validação Cruzada

Os coeficientes do modelo linear demonstram que a maior parte do peso está na característica na coluna de índice 0, que é a característica informativa. Execute o código a seguir para avaliar os coeficientes do modelo linear com validação cruzada:

coefs_cv = pd.Series(
    model_with_cv[-1].coef_, index=model_with_cv[-1].feature_names_in_
).sort_values()
_ = coefs_cv.plot(kind="barh")

Treinar um Regressor Ridge sem Validação Cruzada

Enquanto TargetEncoder.fit_transform utiliza validação cruzada por intervalos, TargetEncoder.transform em si não executa nenhuma validação cruzada. Ele utiliza a agregação de todo o conjunto de treinamento para transformar as características categóricas. Portanto, podemos usar TargetEncoder.fit seguido de TargetEncoder.transform para desabilitar a validação cruzada. Esta codificação é então passada para o modelo Ridge. Execute o código a seguir para treinar o modelo Ridge sem validação cruzada:

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)
)

Avaliar os Coeficientes do Modelo Linear sem Validação Cruzada

O modelo Ridge apresenta sobreajuste porque atribui mais peso à característica de alta cardinalidade extremamente alta em relação à característica informativa. Execute o código a seguir para avaliar os coeficientes do modelo linear sem validação cruzada:

coefs_no_cv = pd.Series(
    model_no_cv.coef_, index=model_no_cv.feature_names_in_
).sort_values()
_ = coefs_no_cv.plot(kind="barh")

Resumo

Neste laboratório, aprendemos a utilizar a classe TargetEncoder do Scikit-learn para transformar dados categóricos em dados numéricos que podem ser usados como entrada para algoritmos de machine learning. Também aprendemos a importância da validação cruzada por intervalos para prevenir o sobreajuste. Treinamos um modelo Ridge nos dados brutos e avaliamos seu desempenho. Também treinamos um modelo Ridge com validação cruzada e avaliamos os coeficientes do modelo linear. Finalmente, treinamos um modelo Ridge sem validação cruzada e avaliamos os coeficientes do modelo linear.