¿Qué pasa cuando hay muchas categorías?
Ejemplo:
One-hot encoding aquí es un desastre.
demasiadas columnas
modelo ineficiente
riesgo de sobreajuste
Target encoding
Convertir cada categoría en un número…
Convertir cada categoría en un número
basado en el target.
Categoría → promedio del target
A → 0.66
B → 0.25
Cada fila recibe ese valor.
Paso 1: calcular promedio en train
Paso 1: calcular promedio en train
Paso 2: aplicar esos valores al test
Paso 1: calcular promedio en train
Paso 2: aplicar esos valores al test
Paso 3: usar como nueva variable
Esto parece correcto…
Pero está MAL.
Estás usando el target de la misma fila.
Eso genera:
fuga de información
Usar validación por folds
Para cada fila:
NO usar su propio target
Dividir el dataset en K partes
Para cada fold:
calcular promedio con los otros folds
aplicar al fold actual
from sklearn.model_selection import KFold
import numpy as np
kf = KFold(n_splits=5, shuffle=True, random_state=123)
train["cat_enc"] = np.nan
for train_idx, val_idx in kf.split(train):
X_train, X_val = train.iloc[train_idx], train.iloc[val_idx]
means = X_train.groupby("categoria")["target"].mean()
train.loc[val_idx, "cat_enc"] = X_val["categoria"].map(means)Categorías con pocos datos
Ejemplo:
una categoría aparece 1 vez
El promedio es inestable
Suavizado
Combinar:
promedio de la categoría
promedio global
\[ \text{codificación} = \frac{\text{suma}_i + \alpha \cdot \text{media global}}{n_i + \alpha} \]
\[ \alpha \in [5, 10] \]
global_mean = train["target"].mean()
alpha = 10
stats = train.groupby("categoria")["target"].agg(["mean", "count"])
smooth = (stats["mean"] * stats["count"] + global_mean * alpha) / (stats["count"] + alpha)
train["cat_enc"] = train["categoria"].map(smooth)
test["cat_enc"] = test["categoria"].map(smooth)Categorías nuevas en test
No existen en train
La ingeniería de variables NO es automática.
Es donde realmente se gana Kaggle.