Validación y Análisis · Tema 01

Diferencia entre verificación y validación

¿El programa hace lo que el modelo dice? ¿El modelo representa lo que la realidad hace? Dos preguntas distintas, dos riesgos distintos y dos cajas de herramientas distintas.

01 · Punto de partida

Todo simulador debe pasar dos exámenes

Imaginá que programás la fila de un banco: clientes que llegan, esperan y son atendidos. El programa corre sin errores y dibuja gráficos hermosos. ¿Podés recomendar contratar otro cajero basándote en esos gráficos? Todavía no. Te faltan dos exámenes independientes:

  • ¿El código implementa fielmente lo que diseñaste en papel?
  • ¿Lo que diseñaste en papel se parece lo suficiente a la sucursal real?
  • ¿Qué pasa si una falla y la otra no?
  • ¿En qué orden conviene hacerlas y con qué evidencia?

02 · Definición

Construir bien frente a construir lo correcto

La distinción clásica de la ingeniería de software (Boehm, 1981) calza perfecto en simulación:

⚙

Verificación

Compara modelo conceptual vs. programa. Pregunta: ¿el código ejecuta exactamente las reglas, ecuaciones y eventos especificados? No usa datos reales.

◎

Validación

Compara modelo vs. sistema real. Pregunta: ¿las salidas simuladas se parecen lo suficiente a las mediciones para el uso previsto? Exige datos reales.

✎

Uso previsto

Ninguna de las dos es absoluta: un modelo se verifica contra su especificación y se valida para un propósito y un rango concretos.

Cuatro combinaciones posibles y su lectura.
CasoVerificadoValidadoLectura
A. IdealSíSíCódigo fiel y modelo útil. Se puede experimentar y decidir.
B. BugNoSí / pareceEl modelo es bueno pero el programa lo traiciona. Hay que depurar.
C. Modelo ingenuoSíNoEl programa hace exactamente lo pedido, pero lo pedido no representa la realidad. Hay que remodelar o calibrar.
D. Doble fallaNoNoNada es confiable. Volver al diseño y a los datos.

El caso C es el más traicionero: todo pasa los tests unitarios, pero las decisiones son malas porque el supuesto de base era falso (llegadas constantes cuando en realidad hay hora pico, tanque sin pérdidas cuando hay evaporación, etc.).

03 · Verificación a fondo

Qué revisa la verificación

La verificación no sale del mundo del modelo: contrasta tres artefactos entre sí.

Especificación→Código→Salidas de prueba
Revisión del diseño
¿Las reglas, diagramas y ecuaciones son coherentes y completas antes de programar? (Tema 2)
Revisión del código
¿Cada evento, cola y actualización de estado hace lo especificado? Pruebas unitarias, trazas, invariantes. (Temas 3–4)
Casos con solución conocida
Si la entrada es trivial (cero llegadas, balance cero), ¿la salida es la esperada matemáticamente?

Verificación típica

Sin datos reales

Se usan valores inventados pero exigentes: bordes, ceros, máximos. Si el tanque con entrada 3 y salida 2 durante 6 pasos no da [13, …], el bug está en el código, no en el mundo.

Error típico

El programa miente

Índices corridos, eventos fuera de orden, semillas reusadas, unidades mezcladas (minutos vs. segundos). Todo verificable sin medir la realidad.

04 · Validación a fondo

Qué revisa la validación

La validación sí sale al mundo: contrasta el modelo (ya verificado) con evidencia externa.

  1. 1
    Datos.

    Mediciones del sistema real con calidad documentada: ¿quién midió, cuándo, con qué instrumento y con qué sesgo? (Tema 10)

  2. 2
    Comparación.

    Gráficos real vs. simulado, errores (absoluto, relativo, cuadrático) y tests de bondad de ajuste. (Temas 11–17, 20–22)

  3. 3
    Juicio de uso.

    ¿El error es aceptable para decidir? Un error de 5 minutos puede ser fatal en urgencias e irrelevante en logística mensual.

Estrategias de validación que verás en el curso.
EstrategiaIdeaTema
Histórica¿Reproduce el pasado conocido?6
Predictiva¿Acierta datos nuevos no usados para calibrar?7
Por expertos¿Los que conocen el sistema lo dan por razonable?8
Estadística¿Pasa chi-cuadrado, K-S, Mann-Whitney, Wilcoxon?12–17

05 · Representación en Python

Verificar con asserts, validar con datos

En Python las dos actividades se ven muy distinto. La verificación usa casos exactos y assert; la validación usa datos medidos y métricas de error.

Python en tu navegador. Estos bloques se ejecutan localmente con Pyodide. Podés editarlos y re-ejecutarlos para romper y arreglar a propósito.

Verificación: el programa respeta la regla

def simular_tanque(nivel_inicial, entrada, salida, pasos):
    nivel = nivel_inicial
    historia = []
    for t in range(pasos):
        nivel = nivel + entrada - salida
        if nivel < 0:
            nivel = 0
        historia.append(nivel)
    return historia


# Casos con solución conocida (verificación, sin datos reales)
assert simular_tanque(10, 3, 2, 3) == [11, 12, 13]
assert simular_tanque(5, 4, 4, 3) == [5, 5, 5]
assert simular_tanque(2, 1, 3, 3) == [0, 0, 0]
print("Verificación OK: el código ejecuta la regla")

Rompé a propósito la regla (por ejemplo, quitá el tope en cero) y observá qué assert falla: eso es un defecto de verificación, no de la realidad.

Validación: el modelo se parece a lo medido

real = [11, 12, 12, 13, 14, 15]  # mediciones del tanque real
sim = simular_tanque(10, 3, 2, 6)

errores = [abs(s - r) for s, r in zip(sim, real)]
mae = sum(errores) / len(errores)
print("sim:", sim)
print("errores absolutos:", errores)
print("MAE:", round(mae, 3))

tolerancia = 1.0
print("¿Válido para tolerancia 1.0?", mae <= tolerancia)

06 · Exploración

Laboratorio: bug frente a sesgo del modelo

La realidad sigue nivel = 10 + 1 × t. Tu simulador tiene dos perillas independientes: un bug de código (resta de más por paso aunque la regla diga otra cosa) y un sesgo del modelo (suponés un balance distinto del real). Mové cada una y observá cuál rompe la verificación y cuál rompe la validación.

EXPERIMENTO 01

Verificación vs. validación

real = 10 + t · simulado = 10 + (1 + sesgo + bug) · t

Los resultados numéricos aparecen debajo.
Error de verificación0,00
Error de validación (MAE)0,00
VerificaciónAprobada
Validación (tol. 1,5)Válido

Sin bug ni sesgo: el simulador está verificado y validado.

La línea verde es la realidad medida. La línea lima es lo que el modelo conceptual promete. La línea naranja es lo que el programa realmente calcula (con bug y sesgo). Cuando el bug es cero pero el sesgo no, el código es fiel pero el modelo no representa la realidad: caso C.

Preguntas para explorar

  1. Poné bug 1,5 y sesgo 0. ¿Qué se rompe: verificación, validación o ambas? ¿Por qué ambas caen si el modelo era bueno?
  2. Poné bug 0 y sesgo 2. Los asserts de verificación pasarían, ¿pero el MAE es aceptable? ¿Qué harías: depurar o recalibrar?
  3. ¿Podés lograr MAE bajo con bug y sesgo que se compensen (ej. bug 1 y sesgo −1)? ¿Es eso verificar o validar? ¿Por qué es peligroso?
Ver respuestas sugeridas
  1. Se rompe la verificación (el programa no ejecuta la regla) y, como consecuencia, también la validación. Un buen modelo mal programado decide mal igual.
  2. La verificación pasaría (el código es fiel), pero el MAE ≈ 7 supera la tolerancia: falla la validación. No hay que depurar código, hay que corregir el supuesto o calibrar el balance.
  3. Sí: los errores se cancelan y el MAE queda bajo por casualidad. Es validación aparente sin verificación: el próximo escenario lo rompe. Por eso la verificación va primero y no se negocia.

07 · Comprensión

Confusiones frecuentes

«Si pasa los tests, ya está validado»

Los tests unitarios verifican. Validar exige datos reales, tolerancia declarada y tests estadísticos. Un programa perfectamente testeado puede modelar un mundo inexistente.

«Si se parece a los datos, el código está bien»

Un bug y un sesgo pueden compensarse y dar un MAE bajo por casualidad. Sin verificación independiente, esa coincidencia es frágil y no generaliza.

«Validar una vez vale para siempre»

La validez tiene rango: horizonte, carga, parámetros y contexto. Cambia la hora pico, el público o la capacidad, y hay que revalidar.

«Calibrar es lo mismo que validar»

Calibrar ajusta parámetros para parecerse a unos datos (Tema 9). Validar comprueba con datos distintos de los usados para calibrar, o el éxito es circular.

08 · Práctica guiada

Ejercicios con Python

Ejercicio 1: clasificar la falla

Leé cada caso y decidí si es falla de verificación, de validación o de ambas. Después comprobalo ejecutando el código.

# Regla especificada: nivel(t+1) = nivel(t) + 3 - 2, con piso en 0.
def sim_rota(nivel, entrada, salida, pasos):
    # BUG: usa salida + 1 por error de tipeo
    historia = []
    for t in range(pasos):
        nivel = nivel + entrada - (salida + 1)
        if nivel < 0:
            nivel = 0
        historia.append(nivel)
    return historia


print(sim_rota(10, 3, 2, 3))  # especificación pide [11, 12, 13]
print("¿Verificado? ¿Validado?")
Ver solución razonada

Devuelve [10, 10, 10] en lugar de [11, 12, 13]: falla de verificación. Aunque el balance real fuera 1, este programa nunca lo reproduciría. Primero se corrige el +1; recién después tiene sentido validar.

Ejercicio 2: validar con tolerancia

Calculá el MAE entre estas mediciones y tu simulador verificado. ¿Es válido con tolerancia 0,8? ¿Y con 1,5?

def sim_ok(nivel, entrada, salida, pasos):
    h = []
    for t in range(pasos):
        nivel = max(0, nivel + entrada - salida)
        h.append(nivel)
    return h

real = [11, 13, 12, 14, 15, 16]
sim = sim_ok(10, 3, 2, 6)
mae = sum(abs(s - r) for s, r in zip(sim, real)) / len(real)
print(sim)
print("MAE:", round(mae, 3))
print("tol 0.8:", mae <= 0.8, "| tol 1.5:", mae <= 1.5)
Ver solución

sim = [11, 12, 13, 14, 15, 16], MAE ≈ 0,333. Es válido con ambas tolerancias. El juicio de validación siempre incluye el umbral: sin tolerancia escrita no hay veredicto.

Ejercicio 3: la compensación peligrosa

Este programa tiene un bug que resta 1 de más, pero el modelo supone un balance 1 mayor que el real. El MAE queda bajo. Explicá por qué igual debe rechazarse.

Ver una posible respuesta
# Realidad: balance 1. Modelo supuesto: balance 2. Código: balance 2 - 1 (bug).
real = [11, 12, 13, 14]
sim_con_bug = [11, 12, 13, 14]  # coincide por cancelación
print("MAE:", 0.0, "¿Verificado?", False)

El MAE es 0 por cancelación de errores, pero la verificación es falsa: el código no ejecuta el modelo supuesto. Cambiá el escenario (por ejemplo, 12 pasos o piso en cero) y la coincidencia desaparece. Verificación primero, validación después, siempre.

09 · Síntesis

Ideas para recordar

  • Verificación = modelo conceptual vs. programa (¿construimos bien?). No usa datos reales.
  • Validación = modelo vs. sistema real (¿construimos lo correcto?). Exige datos y tolerancia.
  • Verificado y no validado: código fiel a un modelo ingenuo. Validado aparente sin verificación: coincidencia frágil.
  • El orden importa: primero verificar con asserts y casos exactos, después validar con errores y tests estadísticos.
  • La validez siempre tiene alcance: propósito, rango y tolerancia escritos.

En el próximo tema veremos la verificación del modelo conceptual: cómo revisar la lógica, los supuestos y los diagramas antes de escribir una sola línea de código.