Ingeniería de características: métodos y buenas prácticas
La documentación de scikit-learn recoge un caso en el que un modelo acierta el 76 % prediciendo un objetivo completamente aleatorio, cuando lo esperable era el 50 %. El error cabe en una línea y es el más común del aprendizaje automático: la fuga de datos. Qué es la ingeniería de características, sus tres familias de selección, las dos formas de fuga que no se ven venir, y la pregunta que las detecta todas sin saber programar.
Existe un ejemplo documentado en el que un modelo alcanza un 76 % de acierto prediciendo un objetivo completamente aleatorio. Nadie falsificó nada. El objetivo era ruido puro, sin ninguna relación con los datos de entrada, y lo esperable era un 50 %, el resultado de lanzar una moneda.
El error que produce ese 76 % cabe en una línea de código, es el más común de la práctica del aprendizaje automático, y vive precisamente en la ingeniería de características. Entender cómo ocurre es más valioso que memorizar el catálogo de técnicas, porque el catálogo cambia y este fallo lleva décadas intacto.
Qué es la ingeniería de características
Es el trabajo de decidir qué se le enseña al modelo y en qué forma. Tiene dos mitades. La selección descarta variables que no aportan o que estorban; la transformación convierte los datos crudos en algo que el algoritmo pueda aprovechar: escalar magnitudes a rangos comparables, convertir categorías en números, extraer de una fecha el día de la semana o la distancia a un festivo.
Para seleccionar hay tres familias. Los métodos de filtro puntúan cada variable por sus propiedades estadísticas, sin entrenar nada; son rápidos y baratos. Los de envoltura —como la eliminación recursiva— entrenan el modelo muchas veces probando subconjuntos; son caros y suelen dar mejores resultados. Y los embebidos, como Lasso o los árboles de decisión, hacen la selección dentro del propio entrenamiento.
La razón de que este trabajo importe tanto es sencilla: un algoritmo no puede descubrir lo que no está representado en su entrada. Si el patrón real depende de la diferencia entre dos fechas y usted solo le da las dos fechas por separado, tendrá que gastar capacidad en reconstruir la resta. Dársela hecha suele valer más que cambiar de algoritmo.
La fuga: la definición y el ejemplo
La documentación de errores frecuentes de scikit-learn define el problema con una precisión que conviene copiar literalmente:
«La fuga de datos ocurre cuando se utiliza, al construir el modelo, información que no estaría disponible en el momento de la predicción. Esto produce estimaciones de rendimiento excesivamente optimistas —por ejemplo en validación cruzada— y, por tanto, un rendimiento peor cuando el modelo se usa sobre datos realmente nuevos, por ejemplo en producción.»
El ejemplo del 76 % está en esa misma página. Se generan datos con objetivos aleatorios, se hace la selección de características sobre el conjunto completo y solo después se separa en entrenamiento y prueba. El resultado, en sus palabras: «Usar todos los datos para realizar la selección de características produce una puntuación de acierto muy superior al azar, aunque nuestros objetivos son completamente aleatorios».
La explicación es que el paso de selección «ve» los datos de prueba. Al elegir, entre miles de variables de ruido, las veinticinco que mejor se correlacionan con el objetivo en todo el conjunto, esas veinticinco están escogidas para funcionar también en la parte que se iba a usar para evaluar. La evaluación deja de ser independiente. Y si en lugar de seleccionar variables uno normaliza dividiendo por la media, la misma trampa aparece con otra cara: la media debe calcularse solo con el entrenamiento, porque «si el subconjunto de prueba se incluye en el cálculo de la media, información del subconjunto de prueba está influyendo en el modelo».
Las dos formas que no se ven venir
La fuga por preprocesado se detecta con disciplina. Hay dos variantes más difíciles, porque no están en el código sino en el significado de los datos.
La fuga temporal consiste en usar información del futuro. Ocurre siempre que se predice algo que evoluciona en el tiempo y se reparten los datos al azar en lugar de por fecha: el modelo entrena con el martes y se evalúa con el lunes. Cualquier validación de una serie temporal repartida aleatoriamente está inflada, y es un error que se comete a diario en previsiones de demanda, de precios y de abandono de clientes.
La fuga por consecuencia es la más elegante y la más cara. Consiste en incluir como variable predictora algo que en realidad es un efecto de lo que se quiere predecir. El caso de manual: predecir qué clientes van a impagar usando, entre las variables, «número de llamadas del departamento de recobro». Funciona espectacularmente en validación. En producción no sirve para nada, porque cuando esa variable tiene valor el impago ya ocurrió. El modelo no predecía: recordaba.
La técnica que es una fuga con buena reputación
Hay un caso donde las dos mitades de este artículo chocan, y merece la pena porque se usa muchísimo y se hace mal casi siempre.
Cuando una variable categórica tiene cientos de valores distintos —códigos postales, referencias de producto, identificadores de vendedor—, convertirla en una columna por valor es inviable. Una alternativa popular es la codificación por objetivo: sustituir cada categoría por la media del objetivo en esa categoría. El código postal 28004 pasa a valer «0,37» porque ése es el porcentaje de impago histórico allí.
Es potente y es, literalmente, meter el objetivo dentro de una variable de entrada. Si esa media se calcula con todos los datos, cada fila lleva incorporada información sobre su propia respuesta, y el modelo lucirá magnífico hasta el día del estreno. Hecho bien —calculando la media solo dentro de cada partición de entrenamiento, excluyendo la fila que se codifica— funciona. Hecho de la manera obvia, es la fuga perfecta: no parece un error, parece ingeniería.
El remedio, que es de procedimiento
La misma documentación resume las reglas, y son tres:
Separar antes de tocar nada. «Divida siempre los datos en subconjuntos de entrenamiento y prueba primero, en particular antes de cualquier paso de preprocesado.»
No dejar que el preprocesado mire la prueba. «Nunca incluya datos de prueba al usar los métodos fit y fit_transform.» Se ajusta con el entrenamiento y se aplica a ambos, no al revés.
Encadenar los pasos en una tubería. «La pipeline de scikit-learn es una gran manera de evitar la fuga de datos, ya que garantiza que se ejecute el método apropiado sobre el subconjunto correcto.» Es el mismo principio que rige cualquier control fiable: convertir la regla en algo que la herramienta cumple por construcción, en vez de en algo que hay que recordar.
La capacidad que se lleva usted
Toda esta familia de errores se detecta con una sola pregunta, y funciona sin saber programar:
¿Habría tenido yo este valor, con este contenido, en el instante exacto en que hay que hacer la predicción?
Si la respuesta es no —porque el dato se rellena después, porque resume el periodo completo, porque lo aporta un proceso que se dispara justo por lo que queremos anticipar—, ese dato no puede estar dentro.
Y la pregunta vale mucho más allá de los modelos. Vale para el backtest de una estrategia de inversión, para el cuadro de mando que «predice» qué comerciales van a cumplir objetivo, para el estudio que encuentra el factor de riesgo de una enfermedad usando historiales completados a posteriori. Siempre que un análisis retrospectivo salga sospechosamente bien, la primera hipótesis no debe ser que se ha encontrado algo: debe ser que se ha mirado el futuro sin darse cuenta.
Por dónde seguir, sin intermediarios
La página de errores frecuentes de scikit-learn trae el ejemplo del objetivo aleatorio con el código completo: se ejecuta en un minuto y ver el 0,76 convertirse en 0,50 al reordenar dos líneas vale por cualquier explicación. La documentación de preprocesado cubre las transformaciones habituales con sus supuestos.
La capacidad que se lleva de aquí es preguntarle a cada variable si existía en el momento de predecir — porque un modelo que mira el futuro siempre acierta, y siempre en el laboratorio.
Este artículo se ha elaborado con inteligencia artificial bajo supervisión editorial humana.