Saltar al contenido

lección 4

Miércoles: el primer modelo y la euforia

Entrenar una regresión logística con stratify y medir la accuracy: 0,89, un triunfo aparente. Álvaro te pide que no mandes nada todavía.

⏱ 55 min

## Miércoles, 10:00. Por fin se entrena

Dos días preparando y hoy, por fin, un modelo. La tabla de modelado está lista: una fila por socio, con sus features y el target al lado. A partir de hoy no vuelves a limpiar; cargas la tabla ya hecha —te la damos como `datos/tabla_modelo.csv` para que todos partamos del mismo punto— y te concentras en entrenar y medir. Hoy escribes el fichero `src/03_modelo.py`. Y antes de que acabe el día vas a tener un número que te va a poner muy contento. Disfrútalo, porque mañana lo vas a mirar con otros ojos.

## Partir en entrenamiento y prueba, sin romper el 10%

Un modelo se entrena con una parte de los datos y se mide con otra que no ha visto, para saber si de verdad aprende o solo memoriza. En scikit-learn eso lo hace `train_test_split`, y se usa con `test_size=0.2` (un 20% para prueba) y `random_state=42`, un número fijo que hace que el reparto sea siempre el mismo. Pero aquí hay un cuidado extra que no tenías en tus trabajos anteriores: como solo el 10,95% de los socios no renueva, si partes al azar puedes acabar con una proporción distinta de esa clase rara en el entrenamiento y en la prueba, y en el peor caso casi vaciar la clase minoritaria de uno de los dos lados. La solución es `stratify=y`: le dice al reparto que mantenga la misma proporción de cada clase en los dos trozos. Con una clase rara, estratificar no es opcional.

El reparto estratificado: el 80% para entrenar y el 20% para probar, pero conservando el 10,95% de no-renovación en los dos lados. La prueba se queda con 329 socios que no renuevan, los que de verdad importa cazar.

## La regresión logística, y la accuracy que ilusiona

El clasificador que vas a usar se llama regresión logística (`LogisticRegression`). A pesar del nombre, no predice un número: estima la probabilidad de que un socio caiga en la clase «no renueva», y a partir de un corte (por defecto 0,5) decide la casilla. Es el clasificador de referencia en problemas como este porque es rápido, estable y, sobre todo, explicable: puedes mirar qué peso le da a cada feature y entenderlo, lo que importa cuando tienes que justificar una decisión ante alguien. Lo entrenas con `.fit()` sobre el entrenamiento, predices sobre la prueba, y mides la accuracy: el porcentaje de aciertos. Sale 0,89. Casi nueve de cada diez.

Y aquí llega la euforia. Un 89% a la primera, sin apenas tocar nada. Se lo cuentas a Marisol y responde al instante: «¡BIEN! Lo sabía, ¿me pasas la lista hoy?». Y Álvaro, que estaba en el hilo, escribe: «Enhorabuena por el primer modelo. Pero no mandes nada todavía. Mañana a primera hora quiero que miremos ese 90% juntos. Tengo una pregunta para ti.» No le haces mucho caso; estás convencido de que el trabajo está casi hecho. Guarda ese 0,89. Y guarda también la frasecita de Jon del lunes, aunque ahora mismo no la recuerdes.

La euforia del miércoles. Un 89% de acierto parece un triunfo redondo, y todos lo celebran menos Álvaro, que pide esperar. Mañana entenderás por qué.

## La lista aparente, y la corazonada de Marisol

Con el modelo entrenado, haces lo que te pide Marisol: ordenas a los socios por la probabilidad de no renovar que les da el modelo, de mayor a menor, y sacas un top de los de más riesgo. A primera vista parece una lista perfecta: los primeros tienen probabilidades altas, el orden tiene sentido. La guardas, convencido de que el trabajo está hecho. (Por dentro, el modelo apenas está marcando a casi nadie como «no renueva», pero eso no se ve en un ranking de probabilidades: se destapará mañana.)

Y de paso, confirmas la corazonada de Marisol con una consulta SQL. ¿De verdad la calle no renueva más? Agrupas los socios por canal de captación y calculas la tasa de no-renovación de cada uno. Y sí: la calle no renueva más del doble que los demás canales. Marisol tenía parte de razón. Pero solo parte: el canal es una señal legítima de contexto, no la explicación completa de quién se va. Esa diferencia —darle la razón en parte sin reducir el modelo a su prejuicio— es justo lo que Álvaro quiere que entiendas antes de entregar nada.

Lo que la lista ordenada no deja ver: el modelo normal amontona a casi todos los socios por debajo de 0,5. Por eso solo marca a 7 como «no renueva», aunque la lista parezca perfecta.

A partir de hoy los ejercicios de modelado leen datos/tabla_modelo.csv, la tabla de modelado ya limpia (15.000 filas, una por socio) con el canal codificado en número (canal_cod: calle=0, web=1, boca a boca=2, evento=3) y el target no_renovo. Es la misma que construiste ayer; te la damos hecha para que todos entrenéis sobre exactamente los mismos datos y los números salgan reproducibles. Para el SQL, DuckDB lee las tablas por su nombre de fichero: tabla_modelo.

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

Regístrate para guardar tu progreso.