Es el proceso de transformar datos crudos en representaciones que los algoritmos de Machine Learning puedan entender y aprovechar mejor.
Un modelo de ML es básicamente una función matemática. Si le das señales pobres, aprenderá relaciones pobres. Si le das señales ricas, aprenderá relaciones poderosas.
Ejemplo: Un árbol de decisión no puede "ver" que "enero" y "diciembre" están cerca en el tiempo. Pero si creas sin(2π·mes/12), sí puede.
Siempre, pero especialmente cuando:
• Los datos tienen distribuciones sesgadas (precios, salarios, clics)
• Hay variables categóricas que el modelo no puede leer directamente
• Tienes fechas o texto sin procesar
• El modelo tiene bajo rendimiento pese a muchos datos
• Hay relaciones no lineales entre variables
- IMC = peso/altura²
- Cambio de presión sanguínea
- Días desde último evento
- Ratio LDL/HDL
- Ratio deuda/ingreso
- Volatilidad 30 días
- Días sin transacciones
- Cambio % mes anterior
- Tasa de conversión histórica
- Días desde última compra
- Categorías únicas compradas
- Ticket promedio por sesión
- Variable tiene sesgo positivo fuerte (skewness > 1)
- Datos de precios, salarios, ingresos, poblaciones
- Conteos de eventos (clicks, compras)
- El modelo usa distancias o gradientes (regresión, SVM, redes neuronales)
- Residuos del modelo muestran heterocedasticidad
- Comprime la cola larga → reduce influencia de outliers
- Linealiza relaciones multiplicativas → regresión lineal las captura
- Estabiliza varianza → mejora convergencia en redes neuronales
- Hace la distribución más "normal" → mejora modelos que asumen normalidad
- Valores negativos o cero (usar log1p o Yeo-Johnson)
- Distribución ya es simétrica/normal
- Modelos basados en árboles (no lo necesitan)
- La escala original tiene significado semántico importante
- Precio de viviendas (Kaggle: House Prices)
- Ingresos en modelos crediticios
- Conteo de transacciones bancarias
- Tiempo hasta evento en survival analysis
- Variable continua con relación no-lineal al target
- Quieres capturar efectos de umbral (ej: menores de 18 años)
- Datos con outliers extremos que distorsionan
- Necesitas interpretabilidad del modelo
- Preparar datos para modelos lineales con no-linealidades
- Captura relaciones no-lineales sin transformaciones complejas
- Robustez a outliers — extremos van a un mismo bin
- Permite que el modelo trate rangos de forma diferente
- Reduce sobreajuste al suavizar variaciones locales
- Relación con target es genuinamente lineal
- Pierdes demasiada información con pocos bins
- Usas modelos tipo gradient boosting (ya capturan no-linealidades)
- Edad → [0-18], [19-35], [36-60], [60+]
- Ingresos → quintiles de riqueza
- Horas de uso → mañana/tarde/noche
- Score crediticio → bandas de riesgo
- Relación curvilínea entre feature y target (parábola, cúbica)
- Modelos lineales que no capturan no-linealidades
- Sabes que dos variables interactúan (el efecto de A depende de B)
- Ratios tienen significado físico/económico (velocidad, densidad, rentabilidad)
- Extiende el espacio de features permitiendo curvas
- Captura sinergias entre variables que por separado no predicen
- Los ratios normalizan por escala (precio/m² vs precio absoluto)
- Grado > 3: explosión combinatoria de features
- Datos insuficientes: alta varianza, overfitting
- Usar con regularización si grado alto
- área² para predecir precio (rendimientos decrecientes)
- ingreso × edad (poder adquisitivo acumulado)
- deuda/ingreso (ratio crediticio)
- velocidad² en modelos de física
| MÉTODO | CARDINALIDAD | MODELO RECOMENDADO | RIESGO LEAKAGE | PRESERVA ORDEN | NOTAS CLAVE |
|---|---|---|---|---|---|
| One-Hot (OHE) | Baja (<15) | Regresión, SVM, NN | Bajo | No | Crea columna por categoría. Curse of dimensionality si alta card. |
| Label Encoding | Cualquiera | Árboles, XGBoost | Bajo | Si hay orden | Introduce orden artificial en nominales. Solo usar en ordinales o tree-based. |
| Target Encoding | Alta (>15) | Lineal, NN, Boosting | Alto | No | Muy poderoso pero requiere cross-validation para evitar leakage. |
| Frequency Enc. | Alta | Cualquiera | Bajo | No | Simple y robusto. Pierde distinción entre categorías con igual frecuencia. |
| Binary Enc. | Media-Alta | Cualquiera | Bajo | No | Compromiso entre OHE y Label. log₂(n) columnas en vez de n. |
| Embeddings | Muy Alta | Redes Neuronales | Bajo | No | Aprende representación semántica. Requiere suficientes datos. |
Usar cuando: Categorías nominales sin orden, baja cardinalidad (<15 categorías), modelos sensibles a escala (Regresión, SVM, KNN, NN).
Por qué: No introduce ninguna relación de orden falsa entre categorías. "Rojo" no es mayor ni menor que "Azul".
Cuidado: Con 100+ categorías crea 100+ columnas → memoria y tiempo de entrenamiento explotan.
Usar cuando: Alta cardinalidad (ciudades, IDs, SKUs), el dataset es grande, modelos de boosting o regresión.
Por qué: Reemplaza cada categoría con la media del target → captura información predictiva directa.
⚠ CRÍTICO: Siempre usar con cross-validation o smoothing para evitar data leakage hacia el target.
Usar cuando: Variables ordinales con orden natural (Bajo/Medio/Alto, Malo/Regular/Bueno), o con modelos basados en árboles.
Por qué: Los árboles de decisión pueden aprender el orden real aunque sea arbitrario, sin importar el número asignado.
Cuidado: NUNCA usar en nominales con modelos lineales (introduce orden falso).
Usar cuando: Alta cardinalidad, no tienes target disponible (unsupervised), quieres simplicidad y robustez.
Por qué: La frecuencia de una categoría suele correlacionar con el target en muchos problemas reales.
Limitación: Dos categorías con la misma frecuencia se vuelven indistinguibles.
- Tienes columnas de fecha/hora en el dataset
- El comportamiento varía por hora, día, mes o temporada
- Predices demanda, ventas, tráfico, fraude
- Hay patrones estacionales o de tendencia
- El tiempo transcurrido desde un evento importa
- Los modelos no interpretan fechas directamente
- Extraer componentes revela estacionalidad oculta
- Los lags capturan inercia y autocorrelación
- Rolling stats suavizan ruido y capturan tendencia local
- Sin/cos evitan discontinuidad en variables cíclicas
- Usar timestamp bruto como feature numérico
- Lags sin verificar que no hay leakage temporal
- Rolling sobre ventanas que incluyen datos futuros
- Asumir que el patrón temporal se mantiene en producción
- Ventas retail: día_semana, es_fin_semana, semana_año
- Fraude bancario: hora_del_día, días_desde_última_transacción
- Energía eléctrica: temperatura_lag1, consumo_rolling7
- Click-through rate: hora, día_semana, días_hasta_evento
Cuándo: Primera exploración rápida, datasets grandes, antes de entrenar.
Métodos: Correlación, Chi², Mutual Information, Varianza.
Ventaja: Rápido, independiente del modelo.
Limitación: No considera interacciones entre features.
Cuándo: Dataset pequeño-mediano, quieres el subconjunto óptimo para un modelo específico.
Métodos: RFE, Forward/Backward Selection.
Ventaja: Considera el modelo completo.
Limitación: Muy costoso computacionalmente.
Cuándo: Siempre que uses Lasso, Ridge, XGBoost o Random Forest.
Métodos: Lasso (L1), Feature Importance, SelectFromModel.
Ventaja: La selección ocurre durante el entrenamiento.
Limitación: Específico al modelo usado.
| MÉTODO | FÓRMULA | RANGO RESULTADO | OUTLIERS | USAR CON |
|---|---|---|---|---|
| StandardScaler | (x - μ) / σ | ≈ [-3, 3] | Sensible | Regresión, SVM, PCA, KNN, NN |
| MinMaxScaler | (x - min) / (max - min) | [0, 1] | Muy sensible | Redes neuronales, imagen, [0,1] requerido |
| RobustScaler | (x - Q2) / (Q3 - Q1) | Variable | Robusto | Datos con outliers, antes de imputar |
| Normalizer | x / ||x|| | ||x|| = 1 | Parcial | NLP, clustering con cosine similarity |
| QuantileTransformer | Rank → Gaussiana | ≈ [-3, 3] | Robusto | Distribuciones muy no-normales |
El modelo muestra métricas artificialmente excelentes en validación (accuracy, AUC, RMSE muy buenos).
Pero al deployar en producción, el rendimiento colapsa porque la información filtrada ya no está disponible.
El equipo ha "desperdiciado" semanas optimizando un modelo que no sirve en producción.
Si tu modelo tiene métricas demasiado buenas para ser verdad (AUC > 0.99, accuracy > 98%), probablemente hay leakage.
Si al deployar el rendimiento baja drásticamente, confirma leakage.
Si una feature tiene correlación muy alta con el target (> 0.95), investiga por qué.
Ejemplo: Aplicas StandardScaler.fit() sobre todo el dataset antes de hacer el split. El scaler "conoce" la media y varianza del test set.
Por qué es leakage: En producción, el scaler fue ajustado con datos de test que "vendrán en el futuro".
Solución: Siempre hacer split primero, luego fit del scaler solo en train.
Ejemplo: Para predecir si un cliente abandonará (churn), incluyes "número de llamadas al servicio al cliente en el último mes". Pero esa info solo se sabe después de que el cliente ya está por irse.
Solución: Preguntarte: ¿Esta feature estaba disponible ANTES de hacer la predicción?
Ejemplo: En series de tiempo, calculas un rolling mean sin verificar que no incluye datos futuros. O usas datos de validación para calcular estadísticas de grupo.
Solución: TimeSeriesSplit, asegurar que lags y rolling windows sean "look-back only".
Ejemplo: Calculas target encoding usando todo el training set, incluyendo la observación misma → la categoría "conoce" su propio target.
Solución: Target encoding siempre con cross-validation o leave-one-out encoding.