01 · Punto de partida
La computadora solo sabe sortear U(0,1)
Todo random() da U(0,1). Muestrear es convertirlo en la X que pide el modelo: exponencial con −ln(1−U)/λ, discreta con acumulada, normal con Box-Muller o gauss. Si el muestreo está mal, el simulador miente aunque todo lo demás esté bien.
La verificación es obligada: histograma vs f, media vs E, colas vs teoría. Muestreo que no se verifica no se usa.
- ¿Qué U base usa mi generador y con qué semilla?
- ¿Qué transformación da mi X (inversa, acumulada, suma)?
- ¿El histograma calca f con N grande?
- ¿Media y colas cierran con la teoría?
02 · Definición
Tres recetas que cubren casi todo
Inversa continua
Exp: −ln(1−U)/λ. Uniforme: a+(b−a)U. Pareto, Weibull y triangular salen igual.
Acumulada discreta
Sortear U y buscar en qué tramo de la acumulada cae. Así salen Bernoulli, dados y tablas.
Atajos
Suma de Exp → Erlang; Box-Muller → normal; choices/gauss/expovariate ya verificados.
| X | Muestreo | En Python |
|---|---|---|
| U(a,b) | a+(b−a)U | uniform(a,b) |
| Exp(λ) | −ln(1−U)/λ | expovariate(lam) |
| Bernoulli(p) | 1 si U menor a p | random() < p |
| Tabla | Buscar en acumulada | choices(vals, weights) |
03 · Semilla y verificación
Azar repetible y auditado
Repetible
Semilla fija para depurar
Misma seed, misma corrida: se reproduce el bug. Distinta seed por réplica: se mide variabilidad (temas 40–41).
Auditado
Histograma + momentos
Con N grande: histograma calca f, x̄ pega E, colas cierran. Si no, el muestreo está mal.
- Stream
- Secuencia por variable: no reusar la misma U para dos X correlacionadas sin querer.
- Bordes
- U = 0/1 exactos rompen −ln(1−U): usar 1−U con epsilon o generador (0,1).
- Discreta
- Acumulada normalizada a 1; buscar con bisección, no con if encadenados.
- N
- Verificar con miles: con 50 todo «cierra» por ruido.
04 · Ejemplos
Muestreos que programás
- 1Espera.
Exp(λ) con −ln(1−U)/λ para llegadas y servicios.
- 2Demanda.
U(6,14) con a+(b−a)U para rango acotado.
- 3Venta.
Bernoulli con U menor a p para sí/no.
- 4Tabla.
Clientes/hora 0–4 con acumulada y
choices. - 5Medida.
Normal con
gauss(Box-Muller verificado).
05 · Representación en Python
Inversa a mano y atajos
Python en tu navegador. La inversa manual debe coincidir con el atajo.
import random, math, statistics
random.seed(391)
lam = 0.5
manual = [-math.log(1-random.random())/lam for _ in range(4000)]
random.seed(391)
# (re-seed para comparar misma base conceptual)
auto = [random.expovariate(lam) for _ in range(4000)]
print(round(statistics.mean(manual),2), round(statistics.mean(auto),2))
Consejo: comparar medias y colas de ambos: deben coincidir dentro del ruido.
Discreta por acumulada
import random
random.seed(5)
vals, probs = [0,1,2,3,4], [0.1,0.25,0.35,0.2,0.1]
acum, s = [], 0
for p in probs:
s += p; acum.append(s)
def muestrear():
u = random.random()
for v, a in zip(vals, acum):
if u < a: return v
return vals[-1]
print([muestrear() for _ in range(12)])
06 · Exploración
Laboratorio: U → Exp(λ) a mano
Generamos U(0,1) y aplicamos −ln(1−U)/λ con λ deslizable. Barras = histograma normalizado; curva = λe−λx exacta. Subí λ y la masa se pega a 0.
Muestreo inverso
X = −ln(1−U)/λ
Con N grande, las barras calcan la curva: muestreo verificado.
Eje x 0 a 12 en 12 tramos. La franja lima marca X mayor a 2/λ (cola e−2 ≈ 0,135).
Preguntas para explorar
- Con N = 200, ¿las barras calcan? ¿Y con 8000?
- Duplicá λ de 0,5 a 1. ¿La media se parte? ¿Y la cola con su propio 2/λ?
- Si truncaras en 6 (tirar lo mayor), ¿la media qué haría? ¿Por qué verificar colas?
Ver respuestas sugeridas
- Con 200 saltan ±20 %; con 8000 calcan. El muestreo se verifica con miles.
- Sí, media 2 → 1. La cola relativa se mantiene 0,135: escala, no forma.
- Bajaría: truncar poda la cola que más pesa en la media. Bug silencioso clásico.
07 · Comprensión
Confusiones frecuentes
«random() ya es mi X»
No: es U(0,1). Sin transformar, todo es uniforme aunque lo llames «demanda normal».
«Inversa vale para discretas»
Vale como búsqueda en acumulada, no como fórmula continua. Mezclarlos sesga.
«Semilla fija siempre»
Fija para depurar; variable por réplica para medir (temas 40–41). Ambas, en su momento.
«Media que cierra alcanza»
No: colas e histograma deben cerrar. Truncados pasan la media y fallan el riesgo.
08 · Práctica guiada
Ejercicios con Python
Ejercicio 1: inversa manual
Generá 4000 Exp(2) a mano y verificá media 0,5 y P(X mayor a 1) = e−2.
import random, math
random.seed(391)
xs = [-math.log(1-random.random())/2 for _ in range(4000)]
print(round(sum(xs)/len(xs),3), round(sum(1 for x in xs if x > 1)/len(xs),3))
Ver solución razonada
0,5 y 0,135: la inversa manual calca teoría. Así se testea cada muestreo nuevo.
Ejercicio 2: tabla acumulada
Muestreá 3000 de {0:0,1, 1:0,25, 2:0,35, 3:0,2, 4:0,1} y compará frecuencias.
import random
from collections import Counter
random.seed(9)
vals = [0,1,2,3,4]; probs = [0.1,0.25,0.35,0.2,0.1]
xs = random.choices(vals, weights=probs, k=3000)
f = Counter(xs)
print({v: round(f[v]/len(xs),3) for v in vals})
Ver solución
Rondan la tabla a centésimas: choices implementa la acumulada por vos.
Ejercicio 3: bug de truncado
Truncá Exp(0,5) en 6 y mirá media vs 2. ¿Cuánto sesga?
Ver una posible respuesta
import random
random.seed(4)
xs = [random.expovariate(0.5) for _ in range(8000)]
print("sin:", round(sum(xs)/len(xs),3), "| trunc:", round(sum(min(x,6) for x in xs)/len(xs),3))
2 vs ~1,9: truncar poda la cola que pesa. En riesgo (P(X mayor a T)) el sesgo es peor.
09 · Síntesis
Ideas para recordar
- Todo nace de U(0,1): X = F⁻¹(U) o búsqueda en acumulada.
- Exp: −ln(1−U)/λ; tabla:
choices; normal:gauss. - Semilla fija depura; variable mide.
- Verificar con histograma + media + colas y N grande.
- Truncar sin declarar sesga media y mata colas.
En el próximo tema mediremos lo inevitable: variabilidad entre ejecuciones.