Saltar al contenido

lección 5

Jueves: la accuracy miente con una clase rara

El descubrimiento: «renueva todo el mundo» también acierta el 89%, y tu modelo caza a 3 de 329. La accuracy alta era un espejismo del desbalanceo.

⏱ 55 min

## Jueves, 10:05. La pregunta que lo cambia todo

Llegas con la lista preparada y ganas de mandarla. Álvaro te para con un mensaje que no esperabas: «Antes de mirar nada: si tu modelo dijera "renueva TODO el mundo, siempre", ¿qué accuracy tendría?». Te quedas pensando. Si el 89,05% de los socios renueva, un modelo que diga «renueva» a todos acertaría justo ese 89,05%. Lo escribes, y en cuanto lo escribes se te cae el alma a los pies, porque tu modelo saca 0,89. Lo mismo. «Exacto», responde Álvaro. «Así que tu 90% puede ser lo mismo que no hacer nada. La accuracy global no vale cuando lo que importa es la clase rara. Mídelo donde duele: ¿a cuántos de los que NO renuevan los coges?»

Esta es la idea central de toda la semana, y conviene entenderla despacio. La accuracy suma todos los aciertos por igual. Cuando una clase es el 89%, acertar a esa clase es casi gratis —basta con decir siempre lo mismo— y arrastra el número arriba. Los fallos en la clase rara, el 11%, apenas mueven la aguja. Por eso un modelo puede tener una accuracy altísima y a la vez ser inútil para lo único que importa: encontrar a los pocos que se van. El 90% no medía que tu modelo fuera listo. Medía que casi todo el mundo renueva. Y eso ya lo sabías antes de entrenar nada.

El golpe del jueves. Tu modelo entrenado y el que dice «renueva a todos» tienen la misma accuracy, y los dos se dejan fuera a casi todos los que se van. La accuracy no sabe cuál es mejor.

## La métrica que sí duele: el recall

Entonces, ¿qué se mide? La matriz de confusión de ayer tenía la respuesta, solo que no la miraste bien. De los 329 socios de la prueba que de verdad no renuevan, tu modelo coge exactamente 3. Tres. Los otros 326 se le escapan: el modelo dice que renuevan, y no van a renovar. Esa cifra —de los que de verdad caen en la clase que importa, qué fracción coge el modelo— se llama recall o exhaustividad, y aquí vale 3 entre 329, es decir, 0,0091. Menos del uno por ciento. Tu modelo del 90% de acierto es, para lo único que le importa a Donare, prácticamente inservible: deja fuera de la lista a 326 de los 329 socios que había que llamar.

No es que el modelo sea tonto. Es que ha aprendido el atajo racional: como acertar a los que se quedan le sale gratis y hay nueve veces más de ellos, decir «renueva» casi siempre maximiza la accuracy. El modelo optimiza lo que le pediste —aciertos totales— y lo que le pediste no era lo que necesitabas. Pediste acertar mucho; necesitabas cazar a los pocos que se van. La accuracy premiaba el silencio sobre la clase rara, y el modelo aprendió a callar.

La matriz de ayer, leída donde duele. La fila de abajo son los 329 que no renuevan: 326 se escapan, solo 3 se cazan. El recall de 0,0091 es la cifra que la accuracy del 0,89 tapaba.

## Precisión, F1 y una métrica que resume mejor: el PR-AUC

El recall no viene solo. Su compañera es la precisión: de los socios que el modelo marca como «no renueva», cuántos lo son de verdad. Las dos miran la clase rara, pero desde lados opuestos: el recall pregunta «¿cuántos de los que se van cojo?» y la precisión «¿cuántos de los que señalo aciertan?». El F1 las combina en un solo número. Y para resumir el modelo entero en un problema desbalanceado, mucho mejor que la accuracy, está el PR-AUC: el área bajo la curva precision-recall, que calcula `average_precision_score`. Es la métrica honesta de este tipo de problemas, porque no se deja engañar por la clase mayoritaria. Vas a calcular las tres sobre tu modelo, para tener la foto completa de lo poco que sirve tal como está.

La diferencia de fondo entre las métricas: la accuracy mira el reparto entero, donde manda la clase grande. Las otras cuatro apuntan directas a la clase rara, que es la que decide si el modelo sirve.

Sigues con datos/tabla_modelo.csv (15.000 filas, canal_cod y no_renovo). El reparto es siempre el mismo: train_test_split con test_size=0.2, random_state=42 y stratify=y, que deja 329 socios con no_renovo=1 en la prueba. Trabajas en el fichero src/04_evaluar.py.

volver a la visión del caso y descargar los datasets

Regístrate para guardar tu progreso.