lección 3
Tu primer modelo supervisado
Entrenar tu primer clasificador con fit y predict, medir cómo de bien lo hace, y plantar la primera semilla de la duda del oficio.
⏱ 50 min
Hay un instante, la primera vez que entrenas un modelo y le pides que prediga algo que nunca le dijiste, en que parece magia. Le das una tabla de solicitudes de crédito pasadas, le dices "aprende", y luego le pones delante a un solicitante nuevo y responde "este devuelve, este no". No le has escrito ninguna regla sobre quién devuelve un préstamo: la ha sacado él de los ejemplos. Esa sensación de magia es real y es bonita, y no voy a quitártela. Pero sí voy a hacer una cosa, al final de esta lección, que es sembrar una pequeña duda honesta sobre lo que significa que el modelo "funcione". Porque entre creer que un modelo funciona y saber que funciona hay un abismo, y ese abismo es lo que separa a quien usa modelos con criterio de quien los usa como una caja mágica.
Ya sabes que la herramienta del oficio de predecir trabaja con dos verbos, aprender y predecir, y que todos sus modelos se usan igual. Ya sabes que estás en el territorio supervisado, que necesitas ejemplos con su etiqueta, y que esa etiqueta es la respuesta que quieres adivinar. Toca juntarlo todo y ponerlo a funcionar. Vamos a entrenar un clasificador: un modelo cuya etiqueta es una categoría, en este caso si un solicitante devolverá un préstamo o no. Y vas a verlo sin magia: qué recibe el modelo, qué guarda cuando aprende, y qué hace cuando predice.
## Separar lo que sé de lo que quiero adivinar
El primer gesto, antes de tocar ningún modelo, es partir tus datos en dos cosas que ya conoces de nombre: las entradas y la etiqueta. Las entradas son todo lo que sabes de cada caso y que también sabrás de un caso nuevo: en nuestro ejemplo, los ingresos del solicitante y su deuda actual. La etiqueta es lo que quieres predecir y que solo conoces en los casos pasados: si devolvió el préstamo o no. En el código de la herramienta, las entradas se guardan en una tabla que por convención se llama X, en mayúscula, y la etiqueta en una lista que se llama y, en minúscula. Esa X mayúscula y esa y minúscula las vas a ver en todo el código de predicción que leas en tu vida.
La convención no es un capricho tipográfico. La mayúscula de X señala que es una tabla de dos dimensiones: filas que son casos, columnas que son variables de entrada. Aunque solo tuvieras una variable, iría como una tabla de una columna, porque el modelo está preparado para aceptar muchas. La minúscula de y señala que es una sola columna: la respuesta, una por caso. Cuando leas ese código, traduce X como "todo lo que sé de cada caso" e y como "lo que quiero adivinar". Separar bien esas dos cosas es el gesto que convierte una tabla cualquiera en material para un modelo supervisado, y hacerlo mal es una de las primeras formas de que todo salga torcido sin que nada dé un aviso.
## El contrato uniforme: fit y predict
Una vez partidos los datos, entrenar es sorprendentemente breve, y esa brevedad es la que engaña a los principiantes haciéndoles creer que ya está el trabajo hecho. Construyes el modelo, le dices aprender pasándole las entradas y la etiqueta, y ya está entrenado. Después le pasas casos nuevos y le dices predecir, y responde. Esos dos verbos (en el código, los métodos que vas a escribir sin parar) son el contrato que todos los modelos de la herramienta cumplen por igual. Un árbol de decisión, una regresión, el modelo más sofisticado que exista: todos se construyen, se les dice aprender con las entradas y la etiqueta, y se les pide predecir. Cambiar de modelo es cambiar una palabra, el nombre de la clase, y nada más del resto del código.
Qué pasa por dentro cuando el modelo aprende depende del modelo, y lo iremos viendo, pero la idea común a todos es la misma: el modelo mira los ejemplos (las entradas junto a su etiqueta) y se queda con una forma de ir de las unas a la otra. En el caso del árbol que vas a usar, lo que aprende es una cadena de preguntas sobre las entradas que separa los casos de una etiqueta de los de la otra. Cuando aprende, no guarda los ejemplos: guarda esa forma, ese resumen de lo que ha visto. Y cuando predice, aplica ese resumen a un caso nuevo. Por eso no es magia: es un resumen de los ejemplos pasados, aplicado a lo que todavía no ha pasado.
Esa uniformidad entre modelos tiene un valor práctico enorme que conviene apreciar desde el principio. Significa que todo lo que aprendas hoy sobre cómo se trabaja con la herramienta (cómo se pasan las entradas, cómo se separa aprender de predecir, cómo se mide el acierto) te va a servir para cualquier modelo que uses en el futuro, por sofisticado que sea. No estás aprendiendo "el árbol de decisión": estás aprendiendo la forma de trabajar de toda la herramienta, usando el árbol como primer ejemplo amable. El día que quieras probar un modelo distinto, cambiarás el nombre de la clase en una línea y el resto del código seguirá igual. Pocas disciplinas te regalan una regularidad así, y conviene no desaprovecharla pensando que cada modelo es un mundo aparte.
1import numpy as np2import pandas as pd3from sklearn.tree import DecisionTreeClassifier45# Solicitudes de credito pasadas, con su desenlace conocido6rng = np.random.default_rng(42)7n = 3008ingresos = rng.uniform(1000, 5000, n) # euros al mes9deuda = rng.uniform(0, 3000, n) # euros de deuda actual10score = (ingresos / 1000) - (deuda / 1500) + rng.normal(0, 0.6, n)11devolvio = (score > 1.5).astype(int) # 1 = devolvio, 0 = no12df = pd.DataFrame({"ingresos": ingresos, "deuda": deuda, "devolvio": devolvio})1314# Separar entradas (X) de etiqueta (y)15X = df[["ingresos", "deuda"]].values16y = df["devolvio"].values1718# Construir el modelo y entrenarlo con los ejemplos pasados19modelo = DecisionTreeClassifier(max_depth=3, random_state=42)20modelo.fit(X, y)2122# Predecir el desenlace de dos solicitantes nuevos23nuevos = pd.DataFrame({"ingresos": [4000, 1500], "deuda": [500, 2500]})24pred = modelo.predict(nuevos[["ingresos", "deuda"]].values)25etiqueta = {1: "devuelve", 0: "no devuelve"}26for i, p in enumerate(pred):27 print(f"Solicitante {i+1}: {etiqueta[p]}")
Entrenar un clasificador y predecir el desenlace de dos casos nuevos
El resultado es intuitivo: el solicitante con ingresos altos y poca deuda sale como "devuelve", y el de ingresos bajos y mucha deuda como "no devuelve". El modelo no sabe nada de bancos ni de préstamos; solo ha visto que, en los ejemplos pasados, los casos parecidos al primero solían tener etiqueta 1 y los parecidos al segundo, etiqueta 0. Ha resumido eso en una cadena de preguntas y la ha aplicado. Que el resultado coincida con tu intuición no es casualidad: es que la relación estaba en los datos, y el modelo la ha encontrado. Cuando el resultado no coincide con tu intuición, por cierto, es cuando empieza lo interesante, pero esa es otra lección.
Fíjate en un detalle del código que es fácil pasar por alto y que importa: a los casos nuevos les has pasado exactamente las mismas columnas, en el mismo orden, que usaste para entrenar. El modelo aprendió a mirar primero los ingresos y después la deuda; si al predecir le pasas la deuda donde esperaba los ingresos, no se queja (los dos son números), pero te da una predicción basura, porque está leyendo "deuda" como si fuera "ingresos". Es uno de esos errores que no saltan en rojo: el programa corre, da un resultado, y el resultado está mal. La regla práctica es simple: las entradas de la predicción tienen que tener la misma forma y el mismo orden que las entradas del entrenamiento. Un caso nuevo es una fila con las mismas columnas que las de la tabla con la que aprendiste.
Y una observación sobre la brevedad del código, porque es engañosa. Entrenar un modelo cabe en tres líneas: construir, aprender, predecir. Esa economía es una de las grandes virtudes de la herramienta, pero también es la fuente del error más común entre quienes empiezan: confundir "el código es corto" con "el trabajo está hecho". El trabajo de verdad está antes (conseguir y entender los datos, decidir qué es la etiqueta, separar bien las entradas) y después (medir el acierto de forma honesta, que es justo adonde vamos). Las tres líneas del medio son la parte fácil. Si alguien te dice que entrenó un modelo en diez minutos, lo que te está contando es que la parte fácil le llevó diez minutos; la pregunta interesante es cuánto le llevó todo lo demás.
Antes de medir nada, conviene nombrar qué clase de modelo acabas de entrenar, porque le pone apellido a lo que has hecho. Como la etiqueta era una categoría (devuelve o no devuelve, dos valores posibles), has entrenado lo que se llama un clasificador: un modelo que asigna a cada caso una de un conjunto de categorías. Si la etiqueta hubiera sido un número en lugar de una categoría (cuántos euros, cuántos días), habrías entrenado otra cosa, con otra forma de medir el acierto. Esa división entre predecir una categoría y predecir un número es importante y tendrá su propio espacio; por ahora quédate con que lo tuyo ha sido clasificar, y que clasificar se mide contando cuántas veces se acierta la categoría.
## Medir el acierto: el momento de la verdad y de la trampa
Un modelo que predice está muy bien, pero la pregunta que todo el mundo hace a continuación es la correcta: ¿acierta? Para responderla hace falta comparar lo que el modelo predice con la respuesta verdadera, y por suerte, en los datos de entrenamiento, la respuesta verdadera la tenemos: es la etiqueta. Así que podemos pedirle al modelo que prediga la etiqueta de los mismos casos con los que aprendió, comparar sus predicciones con las etiquetas reales, y contar cuántas acierta. Eso nos da una medida, el acierto: la proporción de casos en los que el modelo dio la respuesta correcta. Es la medida más intuitiva que existe, y la vas a calcular ahora.
1import numpy as np2import pandas as pd3from sklearn.tree import DecisionTreeClassifier45rng = np.random.default_rng(42)6n = 3007ingresos = rng.uniform(1000, 5000, n)8deuda = rng.uniform(0, 3000, n)9score = (ingresos / 1000) - (deuda / 1500) + rng.normal(0, 0.6, n)10devolvio = (score > 1.5).astype(int)11df = pd.DataFrame({"ingresos": ingresos, "deuda": deuda, "devolvio": devolvio})1213X = df[["ingresos", "deuda"]].values14y = df["devolvio"].values1516modelo = DecisionTreeClassifier(max_depth=3, random_state=42)17modelo.fit(X, y)1819# Medir el acierto sobre los MISMOS datos de entrenamiento20predicciones = modelo.predict(X)21aciertos = (predicciones == y).sum()22acierto = aciertos / len(y)2324print(f"Ejemplos de entrenamiento: {len(y)}")25print(f"Aciertos sobre esos mismos datos: {aciertos} de {len(y)}")26print(f"Acierto (provisional): {acierto:.2f}")
El acierto sobre los datos de entrenamiento: una medida provisional
Noventa por ciento de acierto. Es un resultado estupendo, y aquí es donde tengo que ser honesto contigo, porque lo honesto es sembrar una duda, no celebrar. Ese noventa por ciento está medido sobre los mismos datos con los que el modelo aprendió. El modelo ya había visto esos 300 casos; de hecho, los estudió para construir sus preguntas. Pedirle ahora que los prediga es como darle a un estudiante el mismo examen que ya corrigió con las soluciones delante: claro que acierta, los ha visto. El noventa por ciento no mide si el modelo acertará con solicitantes nuevos, de verdad desconocidos. Mide si recuerda bien los que ya le enseñaste, que es una pregunta mucho menos interesante.
Esto es provisional y conviene que lo tengas marcado en rojo desde el primer día: medir el acierto sobre los mismos datos con los que el modelo aprendió casi siempre da un número demasiado bonito, porque el modelo ya conocía esos casos. No es la medida final del acierto, ni se le parece. Es una medida de cuánto recuerda, no de cuánto acertará con lo que no ha visto. Más adelante aprenderás a medirlo de forma honesta, apartando datos que el modelo no tocará al aprender, y verás que el número suele bajar. Por ahora, quédate con la desconfianza: un acierto medido sobre los datos de entrenamiento es una promesa, no una prueba.
No voy a desarrollar aquí cómo se mide de forma honesta, porque es un tema que merece su propio espacio y lo tendrá muy pronto. Lo que sí quiero es que salgas de esta lección con dos cosas aparentemente contradictorias en la cabeza, y que aprendas a sostenerlas a la vez. La primera: has entrenado un modelo de verdad, que aprende de ejemplos y predice casos nuevos, y eso es un logro real que funciona. La segunda: el número de acierto que acabas de ver no te dice todavía si el modelo es bueno, porque está medido sobre lo que el modelo ya conocía. Las dos son verdad al mismo tiempo. Saber celebrar lo primero sin tragarte lo segundo es, en una frase, el oficio entero.
Consejo de senior: desconfía siempre, por reflejo, de un acierto que te presentan sin decirte sobre qué datos se midió. Es la primera pregunta que debes hacer ante cualquier número de rendimiento, tuyo o de otro: "¿esto está medido sobre los datos de entrenamiento o sobre datos que el modelo no vio?". Si la respuesta es "sobre los de entrenamiento" o, peor, "no lo sé", el número no vale para decidir nada. Un acierto sin su contexto de medición es como un precio sin moneda: un número suelto que puede significar cualquier cosa.
## Lo que has hecho, y la puerta que queda abierta
Resumamos el logro, que es grande, y la grieta, que es importante. Has partido una tabla en entradas y etiqueta, has entendido la convención de la X mayúscula y la y minúscula, has construido un modelo y lo has entrenado con dos verbos, y le has pedido que prediga el desenlace de casos que no había visto. Has visto que no hay magia: el modelo guarda un resumen de los ejemplos y lo aplica. Y has medido su acierto, descubriendo de paso que esa medida, hecha sobre los datos de entrenamiento, es demasiado optimista para fiarse de ella.
La puerta que queda abierta es la más importante de todo el camino, y la cruzarás pronto: ¿cómo se mide de verdad si un modelo acertará con lo que no ha visto? Esa pregunta tiene respuesta, tiene técnica, y tiene trampas por todas partes, y aprenderla cambia por completo la forma de confiar en un modelo. Pero antes de llegar ahí vas a conocer modelos distintos y a entender mejor qué tipo de pregunta responde cada uno. El siguiente es especial, porque es el único que puedes dibujar y leer como una conversación de preguntas y respuestas. Has entrenado tu primer modelo; ahora toca abrirlo y ver qué tiene dentro.
## 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.