Unidad 4 - Práctica: el juez de modelos
Aplicación guiada en clase · Semana 10 · 06278-ECO
1 Reglas de juego
Hoy eres el juez, no el ingeniero
Esta práctica asume que ya escuchaste el podcast, viste los dos videos de métricas y presentaste el quiz. Aquí no se re-explica nada: se usa. Si un término se te escapa, el glosario de la teoría está a un clic.
Trabajarás como el analista al que le entregan modelos ya entrenados y debe responder la única pregunta que le importa al negocio: ¿le confiamos la decisión? Nada de entrenar todavía — eso empieza la próxima semana.
- 👥 Trabaja en parejas: uno escribe, el otro audita las cifras (rotan en el Encargo 2).
- 🖥️ Herramientas: RStudio con tu proyecto del curso. Solo necesitas
dplyr. - 📥 Los datos de hoy (guárdalos en la carpeta
data/de tu proyecto):- credito_evaluacion.csv — 60 solicitudes de crédito con la decisión real y la del modelo.
- notas_evaluacion.csv — 60 estudiantes con su nota real y la pronosticada.
- 🤖 ¿IA? Al estilo del curso desde la semana 8: puede ayudarte a escribir código, pero toda cifra que reportes debe salir de código que tú ejecutaste — y los veredictos los escribes tú.
2 El setup ≈ 5 min
Abre tu proyecto del curso en RStudio, crea el script scripts/10_juez_modelos.R y arranca con el encabezado de siempre:
## ============================================
## Práctica semana 10 — El juez de modelos
## Nombre(s): _______________
## Fecha: _______________
## ============================================
## Librerías / Libraries
library(dplyr)
## Cargar el primer encargo / Load first dataset
credito <- read.csv("data/credito_evaluacion.csv")
## Radiografía (reflejo desde la semana 3) / First look
dim(credito)
head(credito)
str(credito)Checkpoint 🎯: dim() debe decir 60 filas y 7 columnas. Las primeras cinco columnas describen al solicitante; las dos últimas son el duelo del día: decision_real (lo que de verdad pasó con el crédito) y decision_modelo (lo que el modelo predijo).
¿Por qué solo 60 filas?
Porque esto es el examen. BancoAndes entrenó su modelo con 240 solicitudes históricas (el 80% de train) y apartó estas 60 (el 20% de test) que el modelo nunca vio. Todo lo que calcules hoy es desempeño en datos nuevos — la única nota que cuenta. Si esta frase no te suena, la teoría de esta semana te espera.
3 Encargo 1 — El modelo de crédito de BancoAndes ≈ 25 min
El contexto: BancoAndes construyó un modelo que decide solicitudes de crédito en segundos. Antes de dejarlo operar, la gerencia de riesgo te contrata para el veredicto. Te entregan las 60 solicitudes de prueba. Positivo = Aprobado (igual que en el video 1).
3.1 Momento 1 — La vara: el baseline
Antes de mirar al modelo, calcula qué lograría la regla tonta — aprobar (o rechazar) a todo el mundo según la clase mayoritaria:
## ¿Cómo se reparte la realidad? / Target distribution
table(credito$decision_real)
## El baseline: acertar siempre a la clase mayoritaria
## Baseline: always predict the majority class
round(max(table(credito$decision_real)) / nrow(credito), 3)Checkpoint 🎯: 34 Aprobados y 26 Rechazados → la regla “apruebe a todo el mundo” acierta el 0.567 (56.7%). Anótalo grande: un modelo solo aporta lo que le gane a 56.7%.
3.2 Momento 2 — La matriz de confusión
La misma operación del video 1, ahora con una línea de R:
## La matriz: realidad en filas, modelo en columnas
## Confusion matrix: truth in rows, model in columns
table(Real = credito$decision_real, Modelo = credito$decision_modelo)Checkpoint 🎯: tu consola debe mostrar exactamente:
Modelo
Real Aprobado Rechazado
Aprobado 31 3
Rechazado 4 22Tradúcela con tu pareja antes de seguir (regla de memoria del video: primera palabra = ¿acertó?, segunda = ¿qué predijo?):
- TP = 31 — aprobó a quienes había que aprobar.
- FN = 3 — rechazó a 3 buenos clientes (negocio perdido).
- FP = 4 — aprobó a 4 que no pagaron (plata perdida).
- TN = 22 — rechazó a quienes había que rechazar.
Control de lectura (30 segundos): ¿cuál de las cuatro celdas le quita el sueño al gerente de riesgo? ¿Y cuál al gerente comercial? Escríbanlo como comentario en el script — lo van a necesitar en el Momento 4.
3.3 Momento 3 — Las tres métricas, con código
Regla de oro del curso: las cifras salen de código ejecutado, no de la calculadora del celular ni de la “memoria” de una IA. Guarda las celdas y calcula:
## Las cuatro celdas / The four cells
tp <- sum(credito$decision_real == "Aprobado" & credito$decision_modelo == "Aprobado")
fn <- sum(credito$decision_real == "Aprobado" & credito$decision_modelo == "Rechazado")
fp <- sum(credito$decision_real == "Rechazado" & credito$decision_modelo == "Aprobado")
tn <- sum(credito$decision_real == "Rechazado" & credito$decision_modelo == "Rechazado")
## Accuracy: ¿qué fracción del total clasificó bien?
round((tp + tn) / (tp + tn + fp + fn), 3)
## Precisión: de los que aprobó, ¿cuántos eran de aprobar?
round(tp / (tp + fp), 3)Y el recall lo escribes tú (la fórmula está en la teoría — de los buenos clientes reales, ¿cuántos detectó?):
## Recall: TU CÓDIGO AQUÍCheckpoint 🎯: accuracy 0.883 · precisión 0.886 · recall 0.912. Si el recall no te dio, revisa: su denominador es la primera fila de la matriz (los Aprobados reales), no la primera columna.
3.4 Momento 4 — El interrogatorio
Con las cifras sobre la mesa, el juicio. Respondan como comentarios en el script, en sus palabras:
## a) ¿Supera al baseline? ¿Por cuánto?
## b) De cada 35 créditos que el modelo aprueba, ¿cuántos no pagan?
## ¿Ese riesgo es aceptable? ¿Qué información adicional pedirías?
## c) El equipo de BancoAndes reporta que el modelo acierta el 93.3%
## en las 240 solicitudes de ENTRENAMIENTO. Aquí dio 88.3%.
## ¿Esa brecha es un escándalo o es lo esperable? ¿Cómo se llamaría
## el cuadro si fuera 99% contra 62%?Checkpoint 🎯: (a) 88.3% contra 56.7%: el modelo le saca +31.6 puntos a la regla tonta — aporta, y mucho. (b) Aprobó 35 (31+4); 4 no pagaron — el 11.4% de la cartera aprobada. Si un impago cuesta más de lo que dejan 8 buenos créditos, esa cifra manda sobre la accuracy. (c) Una brecha de 5 puntos (93.3 → 88.3) es sobreajuste leve y esperable; 99 → 62 sería el memorizador de la teoría.
4 Encargo 2 — Las alertas tempranas de la universidad ≈ 20 min
El contexto: una universidad quiere pronosticar la nota final (escala 0–5) de cada estudiante a mitad de semestre, para disparar alertas tempranas. Su modelo se entrenó con 240 estudiantes históricos, cuyo promedio de nota final fue 3.34 — ese dato viene del entrenamiento y es tu baseline (¿ves por qué no se calcula con las filas de hoy? Pista: rima con leakage). Te entregan los 60 estudiantes de prueba. Roten los roles de la pareja.
4.1 Momento 1 — La vara: predecir el promedio
## Cargar el segundo encargo / Load second dataset
notas <- read.csv("data/notas_evaluacion.csv")
head(notas)
## Baseline: predecirle 3.34 a todo el mundo
## Baseline: predict the training mean for everyone
notas <- notas %>% mutate(pred_baseline = 3.34)
## MAE y RMSE del baseline (fórmulas del video 2)
round(mean(abs(notas$nota_real - notas$pred_baseline)), 3)
round(sqrt(mean((notas$nota_real - notas$pred_baseline)^2)), 3)Checkpoint 🎯: MAE 0.376 y RMSE 0.466. Lee el MAE como en el video: la regla tonta se equivoca, en promedio, por 0.38 puntos de nota. Esa es la vara.
4.2 Momento 2 — El modelo
Ahora las mismas dos métricas para nota_modelo. El MAE va de muestra; el RMSE es tuyo:
## MAE del modelo / Model MAE
round(mean(abs(notas$nota_real - notas$nota_modelo)), 3)
## RMSE del modelo: TU CÓDIGO AQUÍCheckpoint 🎯: MAE 0.31 y RMSE 0.371. Dos lecturas antes de seguir: (1) el modelo mejora al baseline en las dos métricas; (2) su RMSE queda cerca de su MAE — señal de que no comete embarradas ocasionales gigantes (¿recuerdas el modelo B de las preguntas de comprensión?).
4.3 Momento 3 — El veredicto con números
## ¿Cuánto mejora el modelo a la regla tonta? (en %)
## How much does the model improve on the baseline?
mae_b <- mean(abs(notas$nota_real - notas$pred_baseline))
mae_m <- mean(abs(notas$nota_real - notas$nota_modelo))
round(100 * (mae_b - mae_m) / mae_b, 1)Checkpoint 🎯: el modelo reduce el error promedio en 17.3% (y el RMSE en 20.4%, si lo calculas). ¿Es mucho o poco? Esa pregunta no la responde R:
## d) La universidad quiere ALERTAR a estudiantes en riesgo de perder
## (nota final < 3.0). Con un error promedio de ±0.31, ¿te sirve
## este modelo para esa decisión? ¿O la pregunta de negocio era
## de otro tipo (pista: semana 5 — ¿"cuánto sacará" o "¿está en
## riesgo?")? Escriban su postura en 3-4 líneas.La moraleja del encargo 2
“¿Qué nota sacará?” es regresión; “¿está en riesgo de perder?” es clasificación. La universidad pidió una y tal vez necesitaba la otra — traducir bien la pregunta de negocio (semana 5) decide qué métrica es la correcta (semana 10). En tu proyecto final, esa traducción es lo primero que evalúa el jurado.
5 El informe del juez ≈ 10 min
Todo veredicto profesional termina en una tabla que un gerente pueda leer en 20 segundos. Constrúyela con código:
## La tabla final del informe / Final summary table
informe <- data.frame(
encargo = c("Crédito (clasificación)", "Crédito (clasificación)",
"Notas (regresión)", "Notas (regresión)"),
metrica = c("Accuracy", "Precisión", "MAE", "RMSE"),
baseline = c(0.567, NA, 0.376, 0.466),
modelo = c(0.883, 0.886, 0.310, 0.371)
)
informe
## Guardar la evidencia / Save the output
write.csv(informe, "output/informe_semana10.csv", row.names = FALSE)Y ciérrenlo con los dos riesgos que le reportarían a la gerencia (comentarios, 2 líneas cada uno). Ideas para discutir en pareja: ¿qué pasa si el perfil de los solicitantes cambia el próximo año? ¿la métrica se midió una sola vez en el test o alguien la “consultó” muchas veces? ¿los 4 FP comparten algún patrón que el modelo no ve?
Checkpoint final 🎯: script corre completo de arriba a abajo sin errores (pruébalo con Source), output/informe_semana10.csv existe, y las preguntas a), b), c) y d) tienen respuesta escrita. Eso es exactamente el “producto mínimo” del analista: métrica en test + baseline + riesgos.
El giro de la próxima semana 🔮
Hoy calificaste modelos que otros entrenaron. El de crédito, por cierto, era un árbol de clasificación — el mismo tipo de modelo que tú vas a construir, podar y calificar la próxima semana. Ya sabes exactamente con qué vara te van a medir: la dejaste escrita en informe_semana10.csv.
6 ¿Terminaste antes? El reto del auditor
Para las parejas veloces: la gerencia de BancoAndes sospecha que el modelo trata distinto a los solicitantes jóvenes. Divide el test en dos grupos — edad < 35 y edad >= 35 — y calcula la accuracy de cada grupo. ¿El modelo es igual de confiable en ambos? (Pista: filter() dos veces, o group_by(edad < 35).) Dos líneas de conclusión: ¿le cambiarías algo al informe final?
Checkpoint 🎯: ambos grupos rondan el 0.88 (0.886 los de 35 o más, 0.88 los menores). En estos datos no hay señal de trato desigual — y ojo: un “auditamos y no encontramos nada” bien documentado también es un resultado, y de los que más tranquilizan a una gerencia.
7 Cierre
En una sola clase pasaste de “el modelo da 88%” a un informe con matriz de confusión, tres métricas, dos baselines vencidos (uno por knockout, otro por decisión) y riesgos documentados. Esa es la diferencia entre reportar números y juzgar modelos.
El Taller 10 te espera con dos proveedores que quieren venderle sus modelos a tus clientes. Al menos uno esconde algo que la accuracy no muestra. Ya tienes el olfato — ahora sin guía.