Método de Monte Carlo · Tema 33

Análisis de sensibilidad

Qué entradas mueven la aguja y cuáles son decorado: el tornado que ordena prioridades.

01 · Punto de partida

No todo lo incierto importa

La ganancia del diariero se mueve $100 si cambia el precio y $5 si cambia la tasa de falla. Sensibilidad mide cuánto cambia la salida cuando cada entrada recorre su rango, para gastar datos y N donde duele.

La herramienta reina: el tornado uno-a-la-vez con las demás fijas en base.

  • ¿Qué rango recorre cada entrada?
  • ¿Cuánto se mueve la media en ese rango?
  • ¿Qué 2 entradas mandan?
  • ¿Cuáles fijo sin culpa?

02 · Definición

Tres formas de medir

🌪️

Tornado OAT

Una a la vez en [bajo, alto]: barra = salida(alto) − salida(bajo). Simple y visual.

🔗

Correlación

ρ(entrada, salida) con todo variando junto: captura el ruido real.

📈

Scatter

Nube salida vs entrada: pendiente y ancho cuentan la historia sin números.

Tornado del diariero (Q = 100, media base ≈ 290).
EntradaRangoΔ media
Precio4 → 6±100 (manda)
Demandamala → buena±40
Costo1 → 3±100 pero fijo por contrato

03 · Método

Base→Vary one→Ordenar
  1. 1
    Fijar base.

    Valores centrales y N grande con semilla común para todo el tornado.

  2. 2
    Variar una.

    Cada entrada en [bajo, alto] realista, resto en base. Misma N y semillas.

  3. 3
    Ordenar barras.

    De mayor Δ a menor. Las 2 de arriba piden datos; las de abajo se fijan.

Rango realista
Percentiles 10–90 o contrato, no ±∞. Rangos inventados inventan prioridades.
Interacciones
OAT las ignora: precio×demanda se ve con grilla 2×2 si se sospecha.
Semilla común
Mismas U en cada barra: si no, el ruido tapa el orden.

04 · Ejemplos

  1. 1
    Diariero.

    Precio manda; falla 5% casi no mueve la media (sí el riesgo).

  2. 2
    π.

    Nada que variar: solo N. Sensibilidad trivial.

  3. 3
    Proyecto.

    Ingreso ±10 mueve ±10; σ de 10 a 20 no mueve la media (sí el riesgo).

05 · Representación en Python

Tornado en 15 líneas

Python en tu navegador. Misma semilla por barra: el orden es mérito.

import random

def media(Q=100, precio=5, costo=2, pesos=(30, 40, 30), N=8000, s=7):
    random.seed(s)
    tot = 0
    for _ in range(N):
        D = random.choices([80, 100, 120], weights=pesos)[0]
        tot += precio*min(Q, D) - costo*Q
    return tot / N

base = media()
for nombre, kwargs in [
    ("precio 4", {"precio": 4}), ("precio 6", {"precio": 6}),
    ("costo 1", {"costo": 1}), ("costo 3", {"costo": 3}),
]:
    print(nombre, round(media(**kwargs), 1), "Δ", round(media(**kwargs)-base, 1))

06 · Exploración

Laboratorio: el tornado del diariero

Mové Q y mirá el tornado exacto (sin ruido): precio 4→6, costo 1→3 y demanda mala→buena. La barra larga manda.

EXPERIMENTO 33

Barras que priorizan

Δ = media(alto) − media(bajo)

Los resultados numéricos aparecen debajo.
Media base—
Manda—
Δ top—
Lectura—

Mové Q para reordenar el tornado.

Verde a derecha = sube la media; rojo a izquierda = la baja. Base amarilla = media con todo central.

Preguntas para explorar

  1. Con Q = 100, ¿precio y costo empatan? ¿Por qué?
  2. Con Q = 80, ¿la demanda pesa menos? ¿Por qué?
  3. ¿Qué entrada medirías mejor primero?
Ver respuestas sugeridas
  1. Sí: ±100 cada uno (precio×100 vs costo×100). Simetría del modelo.
  2. Sí: con Q chico casi siempre vendés todo y la demanda no limita.
  3. Precio (o costo si es negociable): lo que más mueve la media.

07 · Comprensión

Confusiones frecuentes

«Sensibilidad = correlación siempre»

Correlación mezcla rangos y ruido; el tornado OAT aísla el efecto causal en rango realista.

«Rangos ±10% para todo»

Cada entrada tiene su rango real: contrato, percentiles o física. ±10% parejo miente.

«OAT ve interacciones»

No: precio×demanda pide grilla. OAT es el primer mapa, no el territorio.

«Lo poco sensible se borra»

Se fija, no se borra: documentado como supuesto con su rango.

08 · Práctica guiada

Ejercicios con Python

Ejercicio 1: tornado a mano

Calculá Δ de precio 4→6 con Q = 100 y N = 10 000.

import random

def media(precio, N=10000, s=7):
    random.seed(s)
    return sum(precio*min(100, random.choices([80,100,120], weights=[30,40,30])[0])-200 for _ in range(N))/N

print(round(media(6)-media(4), 1))
Ver solución razonada

~200: cada $1 de precio mueve ~$100 de media (Q = 100 vendidos casi siempre).

Ejercicio 2: correlación conjunta

Variá precio U(4,6) y correlacioná con la ganancia.

import random

N = 5000
ps = [random.uniform(4, 6) for _ in range(N)]
gs = [p*100-200 for p in ps]
mp, mg = sum(ps)/N, sum(gs)/N
cov = sum((p-mp)*(g-mg) for p, g in zip(ps, gs))/N
import statistics
print(round(cov/(statistics.pstdev(ps)*statistics.pstdev(gs)), 3))
Ver solución

≈ 1,0: relación lineal perfecta cuando lo demás está fijo.

Ejercicio 3: fijar sin culpa

Mostrá que p_falla 0,03→0,07 mueve poco la media con Q = 100.

Ver una posible respuesta
print("Δ ≈ 200*0.04 = 8 $ frente a 200 $ del precio: 25× menos.")

Para la media se fija; para el riesgo se estudia aparte.

09 · Síntesis

Ideas para recordar

  • Tornado OAT con rangos realistas y semilla común.
  • Ordenar Δ: las 2 de arriba piden datos y N.
  • Correlación y scatter complementan, no reemplazan.
  • OAT ignora interacciones: grilla si se sospechan.
  • Lo poco sensible se fija documentado, no se borra.

En el próximo tema veremos cómo el azar se traslada: la propagación de incertidumbre.