Generación de Variables Aleatorias · Tema 11

Método de composición

Cómo generar mezclas y modelos por partes en dos etapas: primero elegir el componente, después muestrear de él.

01 · Punto de partida

Lo complejo se arma con piezas simples

Muchas distribuciones reales son mezclas: dos picos (clientes día/noche), cola pesada por subpoblaciones, ceros inflados, tramos con reglas distintas. Intentar una Q única o una envolvente global es doloroso; componer piezas con inversa directa es trivial.

La receta: U₁ elige el componente con prob. wᵢ, U₂ genera dentro de él. Cada pieza usa su mejor método; el conjunto es exacto.

  • ¿Qué forma tiene una densidad mezcla?
  • ¿Por qué dos uniformes (y no uno) para las dos etapas?
  • ¿Cuánto cuesta componer frente a rechazar global?
  • ¿Qué pasa si los pesos dependen de x (mixtura continua)?

02 · Definición

Teorema de composición en 2 líneas

P(X ≤ x) = Σᵢ P(I=i)·P(X ≤ x|I=i) = Σᵢ wᵢ·Fᵢ(x). Al sortear I y luego X|I, cada rama aporta exactamente su peso.

①

Elegir I

Discreta finita con masa wᵢ (Tema 2): bisect o alias. Un U₁ por muestra, O(log m) o O(1).

②

Muestrear X|I

Cada componente con su Q o rechazo dedicado. U₂ independiente de U₁ para no acoplar elección y valor.

∑

Costo suma

E[costo] = costo(I) + Σ wᵢ·costo(X|I=i). Sin rechazos globales: cada par (U₁,U₂) da una muestra.

Tres composiciones que aparecen en todo simulador.
ModeloI ~X|I ~
HiperexponencialBernoulli(w)Exp(λ₁) o Exp(λ₂)
Ceros infladosBernoulli(p₀)0 o Poisson(λ)
Bimodal día/nocheBernoulli(w)U(0,1) o U(3,4)

03 · Anatomía

Pesos, soportes y jerarquías

Pesos que suman 1
wᵢ ≥ 0, Σwᵢ = 1. Si vienen de conteos, normalizar. Si cambian por muestra (covariables), van a composición condicional.
Soportes que pueden solaparse
Los componentes pueden vivir en el mismo rango (dos normales) o en rangos disjuntos (dos uniformes). Solapados ⇒ histograma con hombros; disjuntos ⇒ bloques separados.
Dos uniformes independientes
U₁ para I, U₂ para X|I. Reutilizar el mismo U correlaciona componente y cuantil interno (sesgo sutil en colas).
Versión continua
f(x) = ∫ f(x|θ)·dH(θ): sortear θ ~ H y luego X|θ. Ej. Gamma-Poisson ⇒ binomial negativa. Mismo algoritmo, θ continua.

Composición

Determinista por muestra

Dos uniformes ⇒ una muestra, sin rechazos. Ideal si cada componente tiene Q barata.

Rechazo global

Una envolvente para todo

Con dos modos alejados, c se dispara para cubrir el valle. Componer con una g por modo gana por lejos.

04 · Dónde aparece

Del valle al modelo jerárquico

U₁ → I→U₂ → X|I→X ~ ΣwF
  1. 1
    Bimodales.

    Día/noche, dos máquinas, dos perfiles. Mezcla de uniformes/normales con w = fracción. (Tema 12)

  2. 2
    Colas por mezcla.

    Hiperexponencial: exponenciales rápidas + lentas dan cola más pesada que cada una. Riesgo y colas.

  3. 3
    Ceros y conteos.

    Cero-inflado: masa extra en 0 + Poisson/binomial. Demanda y fallas intermitentes.

  4. 4
    Jerárquicos.

    θ ~ H luego X|θ: el puente a Bayes y a NB vía Gamma-Poisson. (Temas 26, 28–29)

05 · Representación en Python

Dos uniformes, tres líneas por rama

Guía: w·Exp(1) + (1−w)·Exp(0,2): rápida para lo cotidiano, lenta para la cola. Cada rama por inversa directa.

Python en tu navegador. Cambiá w y verificá que la media tiende a w·1 + (1−w)·5.

import random
import math

random.seed(80)
w, N = 0.4, 6000

def compuesta(w):
    u1 = random.random()
    u2 = random.random()
    lam = 1.0 if u1 < w else 0.2
    return -math.log(1 - u2) / lam

m = [compuesta(w) for _ in range(N)]
print("media muestral:", round(sum(m) / N, 3),
      "teórica:", round(w * 1 + (1 - w) * 5, 3))
print("P(X>5):", round(sum(1 for x in m if x > 5) / N, 3))

Media teórica 3,4 y cola P(X>5) ≈ 0,22 (casi toda de la rama lenta). Con w = 1 colapsa a Exp(1).

06 · Exploración

Laboratorio: dos bloques que se balancean con w

Mezcla w·U(0,1) + (1−w)·U(3,4). Movete w: el bloque izquierdo mide w, el derecho 1−w. Con w = 0,5 pesan igual; con w = 0,8 domina la izquierda.

EXPERIMENTO 11

Composición bimodal

I ~ Bern(w) · X|I ~ U según bloque

Los resultados numéricos aparecen debajo.
Fracción en [0,1]0,500
Teórica w0,500
Media muestral2,000
Media teórica2,000

Con w 0,5, mitad en cada bloque y media 2.

Histograma en densidad sobre [−0,5 · 4,5]. Las líneas amarillas son las densidades teóricas w y 1−w por bloque.

Preguntas para explorar

  1. Con w = 0,8, ¿qué altura esperás en cada bloque? Leela en el panel.
  2. ¿La media teórica con w genérico es w·0,5 + (1−w)·3,5? Verificá con w = 0,2.
  3. Si usaras un solo U para I y para X|I, ¿qué correlación espuria crearías?
Ver respuestas sugeridas
  1. 0,8 en [0,1] y 0,2 en [3,4] (densidad = peso/ancho, ancho 1).
  2. Sí: 0,2·0,5 + 0,8·3,5 = 2,9.
  3. U₁ chico elegiría bloque A y a la vez cuantil chico dentro de él: sobremuestrearías bordes izquierdos de cada bloque.

07 · Comprensión

Confusiones frecuentes

«Mezclar es promediar valores»

Promediar una muestra de cada rama da el punto medio, no la mezcla. Mezclar es sortear la rama por muestra, no combinar valores.

«Un solo uniforme alcanza para las dos etapas»

Partir U en bits o reutilizarlo acopla I y X|I. Dos etapas, dos uniformes independientes (o un vector aleatorio).

«Los pesos no hace falta normalizarlos»

Pesos 2 y 3 no son probabilidades hasta dividir por 5. Sin normalizar, la discreta de I está mal y toda la mezcla se sesga.

«Si los soportes se solapan, no es mezcla»

Sí lo es: el solapamiento solo oculta los modos en el histograma. La generación es idéntica; la validación pide más N y la CDF.

08 · Práctica guiada

Ejercicios con Python

Ejercicio 1: hiperexponencial a mano

Con w = 0,4, λ₁ = 1, λ₂ = 0,2 y N = 6000 (semilla 81), estimá la media y compará con 3,4.

import random
import math

random.seed(81)
w, N = 0.4, 6000
m = []
for _ in range(N):
    lam = 1.0 if random.random() < w else 0.2
    m.append(-math.log(1 - random.random()) / lam)
print(round(sum(m) / N, 3), "vs 3.4")
Ver solución razonada

Debe dar ≈ 3,3–3,5. Si da ≈ 1, confundiste las ramas (usaste λ = 1 siempre).

Ejercicio 2: cero-inflado

Con prob. 0,3 devolver 0, si no Poisson(2) por acumulación simple. Estimá P(X = 0) teórica 0,3 + 0,7·e^(−2) ≈ 0,395.

import random
import math

random.seed(82)
p0, lam, N = 0.3, 2.0, 8000

def poisson(lam):
    # Acumulación simple (Tema 20 anticipado).
    L = math.exp(-lam)
    k, p, u = 0, 1.0, random.random()
    while True:
        p *= random.random()
        if p <= L:
            return k
        k += 1

m = [0 if random.random() < p0 else poisson(lam) for _ in range(N)]
print(round(m.count(0) / N, 3), "vs 0.395")
Ver solución

Debe dar ≈ 0,39–0,40. Es composición discreta + continua de conteo en una línea.

Ejercicio 3: romperla con un solo U

Generá la mezcla w = 0,5 de U(0,1)/U(3,4) reutilizando el mismo U para rama y valor. Compará la media contra 2,0 y explicá el sesgo.

Ver una posible respuesta
import random

random.seed(83)
N = 6000
bien, mal = [], []
for _ in range(N):
    u1, u2 = random.random(), random.random()
    bien.append(u1 if u1 < 0.5 else 3 + u2)  # dos U
for _ in range(N):
    u = random.random()
    mal.append(u if u < 0.5 else 3 + u)      # un U reutilizado
print("bien:", round(sum(bien) / N, 3))
print("mal: ", round(sum(mal) / N, 3), "(sesgada hacia arriba)")

Bien ≈ 2,0; mal ≈ 2,4: al reutilizar, la rama B solo recibe U ≥ 0,5 y su cuantil interno nunca visita [3 · 3,5). Sesgo visible.

09 · Síntesis

Ideas para recordar

  • Mezcla f = Σwᵢfᵢ se genera en 2 etapas: I ~ w con U₁, X|I con U₂.
  • Cada rama usa su mejor método; el conjunto es exacto sin rechazos.
  • Pesos normalizados y dos uniformes independientes, siempre.
  • Vale para bimodales, ceros inflados, hiperexponenciales y jerárquicos.
  • Testear ramas aisladas antes de validar la mezcla global.

En el próximo tema formalizaremos esas mezclas: distribuciones mezcla.