lección 3
Martes: limpiar y definir el target
Limpiar el core, construir el target se_fue cruzando con las bajas, descartar los predictores imposibles y ver el desbalanceo: solo el 5% se va.
⏱ 50 min
## Martes, 10:00. Antes de modelar, poner orden
Ayer viste la suciedad; hoy la limpias. No es el trabajo más glamuroso del oficio, pero es donde se gana o se pierde la fiabilidad de todo lo que venga después. Un modelo entrenado sobre datos sucios no da error: da un resultado, y el resultado está mal de una manera silenciosa que no notarás hasta que alguien tome una decisión equivocada con él. Hoy tienes tres tareas encadenadas: limpiar las columnas que vienen rotas, construir el target `se_fue` cruzando clientes con bajas, y mirar cuántos clientes se van de verdad. Esa última cifra parece un dato de contexto sin importancia y es, en realidad, la que te va a volar la cabeza el jueves. Lo de hoy va al segundo fichero del proyecto, `src/02_limpiar.py`, que deja los datos listos para el modelo.
Hay una frase que se repite en el oficio y que al principio suena a exageración: un científico de datos pasa buena parte del tiempo preparando datos y bastante menos modelando. No es una queja, es la descripción del trabajo, y tiene una explicación sencilla. Los datos no se generaron para que tú los analices, se generaron para que la empresa funcione: al sistema de facturación le da igual que la cuota lleve el euro pegado, porque él solo tiene que cobrar. El problema de que sume bien es tuyo, no suyo. Hoy vas a sentir esa realidad en las manos, y conviene abrazarla en vez de pelearla: cada mancha que limpias nació de una decisión razonable de otro sistema, y entenderla te dice algo de dónde viene el dato.
La mise en place del cocinero es la mejor imagen para esto. En una cocina profesional nadie empieza a cocinar en cuanto entra: primero lava, pela, corta y ordena cada ingrediente. Parece tiempo perdido, pero es lo que hace que el plato salga bien y a la vez. Con los datos es idéntico. Ayer abriste las cajas y viste qué había; hoy toca la mise en place, porque los ingredientes que te pasó Lola vienen sin lavar. Si empezaras a modelar ahora mismo, entrenarías sobre texto con euros pegados y fechas que pandas no entiende, y el modelo que le enseñaras a Ignacio el viernes sería basura con decimales.
Hay una idea que conviene tener clara antes de tocar una sola celda, porque te ahorra el enfado y la mala conciencia: limpiar no es maquillar. No estás inventando datos ni «arreglando» la realidad para que salga más bonita. Estás traduciendo lo que ya hay a un formato en el que se pueda operar, sin cambiar lo que significa. «29,90 €» y `29.90` son la misma cuota; «dos años» y `dos_anios` son el mismo contrato. Cuando conviertes uno en otro, no mientes: haces legible para la máquina lo que ya era verdad. La frontera se cruza el día que borras una fila que no te gusta o cambias un valor porque «seguro que es un error»; eso ya no es limpiar, es falsear, y se hace con muchísimo cuidado y dejando constancia.
Y por qué llegan los datos así, en vez de limpios: porque no se generaron para que tú los analices, se generaron para que la empresa funcione. Al sistema de facturación le da igual que la cuota lleve el euro pegado, porque él solo tiene que cobrar; a quien dio de alta un contrato le daba igual escribir «mensual» o «MENSUAL», porque para una persona es lo mismo. Cada mancha que vas a limpiar hoy nació de una decisión razonable de otro sistema o de otra persona, y a ti te llega como un obstáculo. Aceptar eso te quita el enfado y te deja la curiosidad: ¿por qué está sucio esto, y qué me dice de dónde viene? La suciedad, además, casi siempre cae en un puñado de tipos conocidos. Míralos juntos antes de arreglarlos uno a uno:
## Limpiar un número que viene disfrazado de texto
La cuota mensual llega como `"29,90 €"`: texto, con el símbolo del euro, un espacio y la coma decimal española. Para convertirlo en un número que se pueda sumar y promediar hay que hacer tres cosas en orden: quitar el símbolo del euro y los espacios, cambiar la coma por un punto (porque Python escribe los decimales con punto), y entonces convertir el texto limpio a número con `.astype(float)`. En pandas, las operaciones de texto sobre una columna se hacen con el accesorio `.str`: `.str.replace()` para sustituir, encadenado tantas veces como haga falta. Es un patrón que vas a repetir mil veces en tu carrera, porque el euro, el porcentaje y el separador de miles disfrazan números de texto en casi todos los extractos del mundo.
El tipo de contrato tiene el otro problema clásico: el mismo valor escrito de muchas maneras. `mensual`, `Mensual` y `MENSUAL` son lo mismo para una persona, pero para el ordenador son tres categorías distintas, y si no las unificas acabarás contando tres grupos donde hay uno. La receta estándar es normalizar: `.str.strip()` quita los espacios de los extremos, `.str.lower()` lo pasa todo a minúsculas, y luego un mapeo lleva cada variante a un valor canónico (`"2 años"` y `"dos años"` → `"dos_anios"`). El mismo tratamiento vale para la forma de pago y la provincia. Normalizar no es cosmética: es lo que hace que un `GROUP BY` o un conteo digan la verdad.
Las fechas en varios formatos (2024-03-14, 14/03/2024, 14 mar 2024) se parsean con pd.to_datetime(..., format="mixed", dayfirst=True). El dayfirst=True es crítico en España: sin él, pandas lee 03/04/2024 como 4 de marzo a la americana en vez de 3 de abril. Un error de parseo de fechas no suele dar error: da fechas plausibles pero equivocadas, y esos son los bugs que más tardan en encontrarse.
Un detalle de método que te ahorra pisarte: hay un orden para limpiar, y conviene respetarlo. Primero los tipos (precio y fecha, de texto a número y a fecha de verdad), luego los valores imposibles (una antigüedad negativa, un consumo absurdo), y al final el texto categórico (contrato, forma de pago, provincia). Si lo haces al revés —normalizar categorías antes de arreglar los números— acabas repitiendo trabajo, porque algunas limpiezas dependen de otras. Y una regla que vale más que el orden: limpia lo que vas a USAR, no «todo por si acaso». Si vas a agrupar por tipo de contrato, limpia el contrato; si vas a promediar la cuota, limpia la cuota. Pulir una columna que el análisis no toca es la trampa del perfeccionista que no entrega.
1Bea 11:242te veo limpiando, bien3el orden que a mi me funciona: primero los tipos (cuota y fecha a4numero y fecha de verdad), luego los valores raros (antiguedades5imposibles, duplicados), y al final lo de texto (contrato, provincia)6si limpias en ese orden no te pisas7y guarda SIEMPRE cuantas filas tiras y por que. te lo van a preguntar
El orden de limpieza que evita pisarte, de quien ya ha sufrido estos extractos.
El apunte final de Bea esconde una idea de oficio que vale la pena subrayar: deja constancia de lo que tiras. Si descartas 15 clientes con una antigüedad imposible o 40 filas duplicadas, cuéntalas antes de tirarlas. ¿Por qué? Porque el jueves, cuando tu cuenta de clientes no cuadre con la de otro, la respuesta «excluí 15 antigüedades imposibles y 40 duplicados exactos, aquí están» es la diferencia entre un científico de datos fiable y uno que «perdió filas por el camino». Limpiar en silencio es cómo se pierde la confianza en un análisis; limpiar dejando el rastro es cómo se gana.
Y un aviso sobre los huecos, porque es donde más se nota si tienes criterio o si aplicas recetas. Un valor que falta no se trata siempre igual: depende de lo que signifique. La `antiguedad_meses` viene como decimal en vez de entero, y eso delata que tiene algún hueco (pandas convierte a decimal una columna de enteros en cuanto aparece un nulo). ¿Qué haces con esos huecos? No los rellenes con la media «para que no molesten»: te inventarías clientes con una antigüedad que no tuvieron, y cualquier análisis por antigüedad quedaría contaminado. Como esa columna no es crítica para el modelo de esta semana, lo honesto es dejarla marcada como desconocida y seguir, sin rellenar. Rellenar un hueco es una decisión legítima a veces, pero nunca por defecto y nunca sin dejar dicho que lo hiciste.
## Construir el target: qué significa «se fue»
Aquí es donde el encargo se vuelve concreto. «Ordena por riesgo de baja» no se puede calcular hasta que no decidas qué cuenta como una baja. La definición en FibraNova es simple y la fija Raúl: un cliente tiene `se_fue = 1` si aparece en el fichero de bajas, y `se_fue = 0` si no. Construir esa columna es cruzar `clientes` con `bajas` por `cliente_id` y marcar con un 1 a los que casan. En pandas, la forma limpia es comprobar si cada `cliente_id` de la tabla de clientes está en el conjunto de id de bajas: `clientes["cliente_id"].isin(ids_de_baja).astype(int)`. El resultado es tu target, la columna que el modelo intentará predecir.
Y aquí Raúl marca una línea roja que no vas a olvidar. El fichero de bajas trae, además del id, dos columnas: `fecha_baja` y `motivo_baja`. Sirven para construir el target y para describir por qué se fue la gente, pero nunca jamás pueden entrar como predictores del modelo. ¿Por qué? Porque solo existen DESPUÉS de la baja. Para un cliente activo de hoy —uno de los que quieres ordenar por riesgo— esas dos casillas estarían vacías, porque todavía no se ha ido. Un modelo que las usara estaría «prediciendo» la baja a partir de información que solo aparece cuando la baja ya ocurrió. Es la fuga de datos en su forma más obvia, la que cualquiera ve. Raúl la señala pronto y en voz alta precisamente porque hay otra que no se ve, y a esa llegaréis el jueves.
## El desbalanceo: 5% contra 95%
Con el target construido, calculas lo más básico: ¿qué proporción de clientes se fue? Y sale un 5%. De 12.000 clientes, 600 se dieron de baja y 11.400 se quedaron. Lo apuntas como dato de contexto y sigues, sin darle todavía la importancia que tiene. Pero graba el número, porque es el protagonista escondido del caso. Cuando una de las dos clases que quieres distinguir es tan rara —solo 1 de cada 20—, el problema cambia de naturaleza, y la mayoría de las métricas que te enseñan primero dejan de significar lo que crees. A eso se le llama un problema «desbalanceado», y es tan común en el mundo real (fraude, enfermedades raras, averías) que saber lidiar con él separa a un científico de datos de alguien que solo sabe entrenar modelos. El jueves verás por qué.
Ya que has normalizado el tipo de contrato, puedes comprobar de pasada la corazonada de Lola —«los que se van son los de contrato mensual»— cruzando el contrato con el target recién construido. Y resulta que lleva razón, y de qué manera: los clientes de contrato mensual se dan de baja a una tasa mucho más alta que los de permanencia. No es un capricho: quien no tiene permanencia puede irse sin penalización, así que se va más. Esto no desmonta nada —es una señal legítima y potente, porque el tipo de contrato se conoce antes de la baja—, pero sí deja una lección: a veces el stakeholder tiene razón, y confirmársela con datos (no de palabra) es lo que te gana el derecho a contradecirle cuando no la tenga. Míralo:
Consejo de senior: en cuanto construyas un target, calcula su reparto de clases ANTES de entrenar nada. Si una clase es el 5% y la otra el 95%, apúntalo con mayúsculas en tu cuaderno, porque va a condicionar todo: qué métrica miras, cómo partes los datos, y cómo interpretas cualquier «acierto» que te dé el modelo. El reparto de clases es el contexto sin el cual ninguna métrica significa nada.
Antes de cerrar el martes, Lola te escribe con la impaciencia de quien tiene a su equipo esperando. Es la primera de las muchas veces esta semana en que la urgencia del negocio va a chocar con el método, y conviene que veas cómo se sostiene esa tensión sin romperla:
1Lola 17:402que tal va? necesito la lista cuanto antes, el equipo esta parado3te confirmo que son los de contrato mensual verdad? dame esos y ya45Tú 17:446El contrato mensual es la mayor senal, confirmado con datos. Pero7antes de darte la lista quiero entrenar el modelo y comprobarlo bien.8Manana entreno y te digo algo.910Lola 17:4511vale pero manana sin falta eh que me corre prisa
La urgencia de Lola empieza a apretar. Darle lo que sabes con seguridad y poner fecha a lo demás es la salida.
Fíjate en lo que has hecho sin darte cuenta: le has dado a Lola lo que ya sabes con seguridad (el contrato mensual es una señal real, con datos detrás) y has puesto fecha a lo que todavía tienes que comprobar (la lista completa). No le has dicho ni «ahí va» —entregar deprisa algo en lo que no confías— ni un silencio de tres días. Esa frase, «lo cierto hoy, lo dudoso con fecha», es la que mantiene contenta a la urgencia sin traicionar al método, y la vas a usar toda la semana. Mañana por fin tocas scikit-learn, entrenas tu primer modelo y te llevas una alegría de 99%. Guarda esa alegría con cuidado: el jueves vas a entender por qué era demasiado bonita para ser verdad.
## comentarios
Reporta erratas, ayuda a otros o comparte tu opinión. Sé constructivo.
Inicia sesión para comentar y responder.
cargando comentarios...
Regístrate para guardar tu progreso.