Validación y Análisis · Tema 05

Validación frente al sistema real

El código ya obedece al papel. Ahora la pregunta incómoda: ¿ese papel se parece lo suficiente a la realidad como para decidir con él?

01 · Punto de partida

Cruzar el puente del laboratorio al mundo

Hasta el Tema 4 todo ocurría dentro del laboratorio: papel contra código, con oráculos exactos. Ahora el árbitro es externo y ruidoso: mediciones del tanque real, tiempos de espera reales, ventas reales. Esas mediciones tienen ruido, huecos y sesgos de medición.

  • ¿Qué salidas comparar y con qué métrica?
  • ¿Qué error es tolerable para decidir?
  • ¿Los datos alcanzan o hay que medir más?
  • ¿Quién firma que el modelo sirve para este uso?

02 · Definición

Validez operativa, no verdad absoluta

Ningún modelo «es válido» en abstracto. Un modelo de fila con error de 2 minutos puede ser excelente para dimensionar personal mensual e inútil para gestionar urgencias minuto a minuto.

🎯

Exactitud

Sesgo medio cercano a cero: el simulador no sobreestima ni subestima sistemáticamente.

🎲

Precisión

Dispersión contenida: réplicas parecidas entre sí y parecidas a la variabilidad real.

🛡

Robustez

El error se mantiene tolerable en todo el rango declarado, no solo en el punto cómodo.

La misma exactitud, distinta validez según el uso.
UsoToleranciaMAE = 1,2Veredicto
Plan mensual de stock± 3,01,2Válido
Turno de cajeros± 1,51,2Válido justo
Urgencias médicas± 0,51,2No válido

Sin tolerancia escrita antes de comparar, la validación es decoración: siempre se puede mover el umbral para que «pase».

03 · Método

El protocolo de comparación honesta

  1. 1
    Fijar métrica y tolerancia antes de mirar.

    Ej.: «MAE del nivel ≤ 1,5 litros para plan semanal». Se firma antes de correr la comparación.

  2. 2
    Separar datos de calibración y de validación.

    Si ajustaste con enero, validá con febrero. Validar con los mismos datos es mirarse al espejo (Temas 6–9).

  3. 3
    Comparar gráfico + número.

    Primero el ojo (¿sigue la forma, hay desfase, hay sesgo?), después el número (MAE, sesgo, cobertura). Nunca solo uno.

  4. 4
    Cuantificar incertidumbre de ambos lados.

    Lo real tiene error de medición; lo simulado, error de muestreo. Sin barras, la comparación es teatro.

  5. 5
    Dictaminar por escrito con alcance.

    «Válido para 0–30 clientes/hora y tolerancia 1,5. Fuera de eso, no se garantiza». (Temas 43–45)

tolerancia previa→datos frescos→gráfico + MAE→dictamen con alcance

04 · Comparación

Tres lecturas que nunca fallan

Lectura gráfica

Real vs. simulado en el tiempo

Puntos medidos contra línea simulada con banda de tolerancia. El ojo detecta sesgo (siempre arriba), desfase (curva corrida) y varianza (picos que el modelo aplana).

Lectura numérica

Sesgo, MAE y cobertura

Sesgo = media(sim − real): ¿tira para un lado? MAE = media|sim − real|: ¿cuánto erra en promedio? Cobertura = % de reales dentro de sim ± tolerancia.

Sesgo
Error sistemático. Se corrige recalibrando o remodelando, no promediando más réplicas.
MAE
Error absoluto medio. Robusto y en las unidades originales: «erramos 1,2 litros en promedio».
Cobertura
Fracción de mediciones dentro de la banda. Una cobertura de 11/12 con tolerancia 1,5 dice más que un MAE solo.

05 · Representación en Python

Comparar con tolerancia declarada

El molde es siempre el mismo: datos reales, salidas simuladas, tolerancia fijada antes, y tres números (sesgo, MAE, cobertura) más un veredicto escrito.

Python en tu navegador. Cambiá la tolerancia después de ver el MAE y preguntate: ¿vale cambiar el umbral a posteriori?

real = [11, 12, 12, 13, 14, 15, 15, 16, 17, 18, 18, 19]
sim  = [11, 12, 13, 13, 14, 15, 16, 16, 17, 17, 18, 18]

TOLERANCIA = 1.5  # declarada ANTES de mirar, para plan semanal

errores = [s - r for s, r in zip(sim, real)]
sesgo = sum(errores) / len(errores)
mae = sum(abs(e) for e in errores) / len(errores)
cobertura = sum(1 for e in errores if abs(e) <= TOLERANCIA) / len(errores)

print(f"sesgo: {sesgo:+.2f} | MAE: {mae:.2f} | cobertura: {cobertura:.0%}")
print("Válido" if mae <= TOLERANCIA else "No válido",
      f"para tolerancia {TOLERANCIA}")

Sesgo +0,08, MAE 0,42, cobertura 100%: válido con holgura para 1,5. Probá tolerancia 0,3 y observá cómo el mismo modelo pasa a no válido.

Separar calibración de validación

# Calibrar con enero, validar con febrero (datos distintos)
enero = [11, 12, 13, 13, 14, 15]
febrero = [15, 16, 17, 18, 18, 19]

def simular(inicio, balance, pasos):
    return [inicio + balance * (t + 1) for t in range(pasos)]

# Se elige balance 1 porque ajusta bien a enero...
cand = simular(10, 1, 6)
mae_ene = sum(abs(s - r) for s, r in zip(cand, enero)) / 6
# ...pero el veredicto se da con febrero, no con enero
cand_feb = simular(14, 1, 6)
mae_feb = sum(abs(s - r) for s, r in zip(cand_feb, febrero)) / 6
print(f"MAE enero (calibración): {mae_ene:.2f}")
print(f"MAE febrero (validación): {mae_feb:.2f}")

06 · Exploración

Laboratorio: ¿pasa tu modelo el umbral?

La realidad tiene ruido de medición y tu modelo puede tener sesgo. Fijá la tolerancia antes (banda lima alrededor del simulado) y observá MAE, sesgo, cobertura y veredicto. La semilla es fija para que el experimento sea repetible.

EXPERIMENTO 05

Modelo ↔ realidad con banda

cobertura = % de reales dentro de sim ± tolerancia

Los resultados numéricos aparecen debajo.
MAE0,00
Sesgo+0,00
Cobertura100%
VeredictoVálido

Sin sesgo y con tolerancia 1,5, el modelo cubre casi todas las mediciones.

Los puntos verdes son mediciones reales (tendencia 10 + t más ruido). La línea lima es el simulado (10 + t + sesgo). La banda es sim ± tolerancia: los puntos dentro cuentan para la cobertura.

Preguntas para explorar

  1. Con sesgo 0 y ruido 0,8: ¿MAE y cobertura? Ahora subí el ruido a 2,5 sin tocar el modelo. ¿El MAE sube por culpa del modelo o de la medición?
  2. Poné sesgo +2 con tolerancia 1,5. ¿Sesgo, MAE y cobertura? ¿Basta promediar más réplicas para arreglarlo?
  3. Bajá la tolerancia a 0,5 con el modelo perfecto (sesgo 0). ¿Sigue válido? ¿Qué te dice eso sobre «el mismo modelo, distintos usos»?
Ver respuestas sugeridas
  1. MAE ≈ 0,6 y cobertura alta. Con ruido 2,5 el MAE sube a ≈ 2 aunque el modelo sea perfecto: el error es de medición, no del modelo. Pedir tolerancia menor que el ruido es pedir imposibles.
  2. Sesgo ≈ +2, MAE ≈ 2, cobertura ≈ 0%: no válido. Más réplicas no corrigen un sesgo sistemático: hay que recalibrar el balance (Tema 9).
  3. No: con tolerancia 0,5 el ruido solo ya rompe la validez. El veredicto siempre lleva su uso: válido para plan semanal (1,5), no válido para control fino (0,5).

07 · Comprensión

Confusiones frecuentes

«Validar es mirar si se parecen»

«Parecerse» sin métrica ni tolerancia previa es subjetivo. Validar es comparar con número, banda y umbral firmado antes.

«Si el MAE es bajo, no hay sesgo»

Falso: errores +2 y −2 se cancelan en el sesgo pero suman en el MAE, y viceversa. Informá ambos más la cobertura.

«Más datos de calibración = validación»

Reusar los datos de ajuste para validar es circular. La validación exige datos frescos o, al menos, una partición reservada.

«Un modelo validado sirve para todo»

Sirve para el uso y rango validados. Cambia la carga, el horizonte o la tolerancia, y hay que revalidar.

08 · Práctica guiada

Ejercicios con Python

Ejercicio 1: dictaminar con tolerancia previa

Con estos datos y tolerancia 1,0 firmada antes, ¿cuál es el veredicto? ¿Qué cambiaría si la tolerancia se moviera a 0,4 después de ver el MAE?

real = [10, 12, 13, 15]
sim = [11, 12, 14, 15]
TOL = 1.0
mae = sum(abs(s - r) for s, r in zip(sim, real)) / len(real)
print("MAE:", mae, "-> Válido" if mae <= TOL else "-> No válido")
Ver solución razonada

MAE = 0,5 → Válido para 1,0. Mover a 0,4 a posteriori para hacerlo fallar (o a 2,0 para hacerlo pasar) es trampa metodológica: el umbral se fija antes, con el uso, no después con el resultado.

Ejercicio 2: sesgo que el MAE esconde a medias

Calculá sesgo y MAE. ¿El modelo sobreestima o subestima sistemáticamente?

real = [10, 10, 10, 10]
sim = [12, 12, 8, 8]
err = [s - r for s, r in zip(sim, real)]
print("sesgo:", sum(err)/len(err))
print("MAE:", sum(abs(e) for e in err)/len(err))
Ver solución

Sesgo 0 (se cancela) pero MAE 2: el modelo no tiene deriva media, pero es impreciso. Con solo el sesgo parecería perfecto; con ambos se ve la historia completa.

Ejercicio 3: cobertura como argumento

¿Qué cobertura logra este modelo con tolerancia 1,5 y qué significa para el dictamen?

Ver una posible respuesta
real = [11, 12, 12, 13, 14, 20]  # el último es un atípico
sim = [11, 12, 13, 13, 14, 15]
TOL = 1.5
cob = sum(abs(s-r) <= TOL for s, r in zip(sim, real)) / len(real)
print(f"cobertura: {cob:.0%} (5/6 dentro)")
print("Investigar el atípico antes de dictaminar")

Cobertura 83%: 5/6 dentro. El punto 20 puede ser error de medición o régimen no modelado. El dictamen honesto lo investiga y lo documenta, no lo esconde bajo el promedio.

09 · Síntesis

Ideas para recordar

  • Validar es contrastar sim vs. real con métrica y tolerancia fijadas antes y para un uso declarado.
  • Sesgo + MAE + cobertura cuentan la historia completa; ningún número solo alcanza.
  • Los datos de validación deben ser frescos: calibrar y validar con lo mismo es circular.
  • El ruido de medición pone un piso al error exigible: no pidas tolerancia menor que tu instrumento.
  • Todo veredicto lleva alcance: rango, uso y tolerancia escritos.

En el próximo tema veremos la validación histórica: cómo reproducir el pasado conocido de forma sistemática.