Generación de Variables Aleatorias · Tema 01

De números uniformes a variables aleatorias

Por qué todo el azar simulado nace de U ~ U(0,1), cómo un umbral crea una Bernoulli y qué significa “generar” una distribución con código reproducible.

01 · Punto de partida

La computadora solo sabe hacer uniformes

Cuando simulamos una fila, una epidemia o un servidor necesitamos tiempos exponenciales, llegadas Poisson, decisiones Bernoulli, errores normales. Pero si mirás la librería estándar de casi cualquier lenguaje, la única fuente de azar es una función que devuelve uniformes en [0,1): random(), Math.random(), runif().

Este tema responde la pregunta fundacional del curso: ¿cómo se convierte ese chorro plano de uniformes en cualquier variable aleatoria X con distribución F? La respuesta corta es: con un método de transformación determinista. La respuesta larga es todo este curso.

  • ¿Qué significa exactamente “X ~ Bernoulli(0,3)” cuando la escribimos en código?
  • ¿Por qué comparar un uniforme con un umbral ya genera azar no uniforme?
  • ¿Cómo sabemos que el generador respeta la distribución pedida?
  • ¿Cómo lo hacemos reproducible con una semilla?

02 · Definición

Qué es generar una variable aleatoria

Una variable aleatoria queda definida por su distribución: en el caso discreto por su masa P(X = k), en el continuo por su densidad f(x) y su acumulada F(x) = P(X ≤ x). Generarla es producir valores x₁, x₂, … cuya frecuencia a largo plazo reproduzca esa distribución.

▭

Uniforme base

U ~ U(0,1) cumple P(U ≤ u) = u. Es “plano”: cualquier subintervalo de igual largo tiene igual probabilidad. Es lo que entrega el generador base.

⇝

Método

Función g tal que X = g(U₁, U₂, …) tiene distribución F. Ejemplos: umbral, F⁻¹, aceptación-rechazo, alias, Box-Muller.

◉

Muestra

Los valores xᵢ generados. No son “la distribución”: son evidencia finita que debe parecerse a F y que validaremos con histogramas y pruebas.

El ejemplo mínimo es la Bernoulli(p): vale 1 con probabilidad p y 0 con probabilidad 1 − p. Basta una regla:

Como P(U < p) = p, la salida es exactamente Bernoulli(p). Acabás de transformar un azar plano en un azar sesgado. Todos los métodos del curso son generalizaciones de esta idea.

La misma fuente uniforme, distintas variables según el método.
Quiero X ~Método más simpleIdea en una línea
Bernoulli(p)Umbral1 si U < p, si no 0
Uniforme discreta {1,…,6}Escala y piso1 + piso(6·U)
Exponencial(λ)Inversa−ln(1−U)/λ
Normal(0,1)Box-MullerDos uniformes → dos normales

03 · Anatomía

Los cuatro ingredientes de todo generador

Fuente uniforme
Generador pseudoaleatorio que produce U₁, U₂, … en [0,1). Es determinista dada una semilla: misma semilla, misma secuencia. Eso permite reproducir experimentos. (Temas 21 y 41)
Distribución objetivo F
Lo que queremos imitar, descripta por su masa, densidad o acumulada F. Sin F escrita no hay forma de saber si el método es correcto. (Tema 4)
Método de transformación
La receta g: inversa, rechazo, composición, alias, urnas, Box-Muller, Fisher-Yates. Cada uno tiene supuestos, costo y rango de uso. (Temas 5–15)
Validación
Histograma, CDF empírica y pruebas (chi-cuadrado, Kolmogorov-Smirnov) que comparan la muestra con F. Generar sin validar es adivinar. (Temas 36–38)

Generador correcto

Respeta F por construcción

Hay un argumento probabilístico (P(U < p) = p, cambio de variable, etc.) y la muestra lo confirma al crecer N.

Imitación ingenua

Parece aleatorio pero sesga

Usar U directamente como si fuera normal, o round() donde va floor(), deforma bordes y colas aunque “se vea azaroso”.

04 · Mapa del curso

A dónde lleva esta idea

El umbral Bernoulli es el caso n = 1. El resto del curso escala la misma arquitectura U → g → X:

Uniforme→Método general→Distribución→Validación
  1. 1
    Fundamentos (Temas 2–7).

    Discretas y continuas, función F y transformada inversa analítica y numérica.

  2. 2
    Métodos generales (Temas 8–15).

    Rechazo, envolvente y eficiencia, composición, mezclas, alias y urnas.

  3. 3
    Catálogo (Temas 16–27).

    Bernoulli, uniforme discreta, geométrica, binomial, Poisson, uniforme continua, exponencial, normal, Box-Muller, polar, gamma y otras continuas.

  4. 4
    Muestreo y calidad (Temas 28–41).

    Correlación, vectores, con/sin reemplazo, permutaciones, Fisher-Yates, empíricas, histogramas, pruebas, eficiencia y biblioteca final.

  5. 5
    Regla de oro.

    Elegí el método más simple que respete F con el costo que tu N permite. La sofisticación sin validación es deuda técnica.

05 · Representación en Python

Del uniforme al primer generador

En Python, random.random() es nuestra U ~ U(0,1). Todo lo demás es transformación pura. Fijar seed vuelve el experimento repetible.

Python en tu navegador. Estos bloques se ejecutan localmente con Pyodide, sin instalar nada. Podés editar p, N o la semilla y volver a ejecutar.

import random

random.seed(7)
p = 0.3
N = 10

def bernoulli(p):
    return 1 if random.random() < p else 0

muestra = [bernoulli(p) for _ in range(N)]
print(muestra)
print("proporción de unos:", sum(muestra) / N)

Cambiá p a 0,8 y reejecutá: la proporción de unos debe subir cerca de 0,8. Con N = 10 hay ruido; con N = 10 000 se estabiliza.

El mismo patrón sirve para otras distribuciones

Una vez entendido el umbral, el resto es cambiar g. Dos adelantos que desarrollaremos a fondo:

import random
import math

random.seed(11)

def uniforme_discreta(a, b):
    # Enteros equiprobables {a, ..., b} con U ~ U(0,1).
    return a + int((b - a + 1) * random.random())

def exponencial(lam):
    # Inversa de la exponencial: F(x) = 1 - exp(-lam*x).
    u = random.random()
    return -math.log(1 - u) / lam

print([uniforme_discreta(1, 6) for _ in range(8)])
print([round(exponencial(0.5), 2) for _ in range(5)])

06 · Exploración

Laboratorio: el umbral U < p

Movete la probabilidad p y el tamaño N y observá la ley de los grandes números en acción: con N chico la proporción salta; con N grande se pega a la línea teórica p. La semilla es fija para que el experimento sea repetible.

EXPERIMENTO 01

Bernoulli por umbral

X = 1 si U < p, si no 0

Los resultados numéricos aparecen debajo.
Proporción observada0,300
Teórica p0,300
Error absoluto0,000
Unos / N300 / 1000

Con p 0,3 y N 1000, la proporción ronda 0,3.

La barra naranja es la frecuencia de unos; la línea punteada es p. Al subir N, la barra se acerca a la línea para cualquier p.

Preguntas para explorar

  1. Con p = 0,5 y N = 100, mové p a 0,9. ¿Qué barra crece y por qué P(U < p) = p lo explica?
  2. Dejá p = 0,3 y subí N de 100 a 5000. ¿Qué le pasa al error absoluto?
  3. Si olvidás la semilla y repetís el experimento, ¿cambia la proporción? ¿Sigue siendo válido el generador?
Ver respuestas sugeridas
  1. Crece la barra de unos: un intervalo más largo [0,p) captura más uniformes, exactamente con probabilidad p.
  2. Tiende a achicarse (con fluctuaciones): es la convergencia de la frecuencia a la probabilidad.
  3. Cambia la muestra concreta pero no la distribución: con N grande cualquier semilla da proporción ≈ p. La semilla solo fija qué réplica ves.

07 · Comprensión

Confusiones frecuentes

«random() ya me da normales si pido muchos»

No: muchos uniformes siguen siendo planos. Promediarlos o sumarlos cambia la distribución (teorema central del límite), pero eso ya es otro método con otra F, no “usar uniformes directamente”.

«Si sale 0,72, 0,73, 0,71, el generador anda mal»

Rachas y cercanías son normales en el azar. La calidad se juzga con N grande, histogramas y pruebas, no con 3 valores consecutivos.

«Con N = 50 ya valido»

Con N chico el ruido tapa el sesgo. Un error de método (por ejemplo, usar round en vez de floor) solo se ve claro con miles de réplicas y comparando contra F.

«La semilla hace más aleatorio»

La semilla no mejora ni empeora el azar: solo fija la secuencia para reproducirla. Lo que importa es el algoritmo base y el método g.

08 · Práctica guiada

Ejercicios con Python

Ejercicio 1: calibrar el umbral

Generá 5000 Bernoulli(0,2) con semilla 1 y calculá la proporción. Debe dar ≈ 0,2 con error menor a 0,02.

import random

random.seed(1)
p, N = 0.2, 5000
muestra = [1 if random.random() < p else 0 for _ in range(N)]
prop = sum(muestra) / N
print(prop)
print(abs(prop - p) < 0.02)
Ver solución razonada

Da ≈ 0,20 (típicamente 0,19–0,21) y True. Si cambiás la semilla, el valor exacto cambia pero sigue cumpliendo la tolerancia con N = 5000.

Ejercicio 2: dado justo con uniformes

Sin ejecutar primero: ¿qué valores produce 1 + int(6 * random.random())? ¿Por qué int() (piso) y no round()? Comprobalo generando 6000 tiros.

import random

random.seed(2)
tiros = [1 + int(6 * random.random()) for _ in range(6000)]
for cara in range(1, 7):
    print(cara, tiros.count(cara) / len(tiros))
Ver solución

Produce {1,…,6} cada uno con ≈ 1/6. int(6U) parte [0,6) en 6 intervalos iguales de largo 1; round(6U) daría 7 valores con los bordes a mitad de probabilidad.

Ejercicio 3: primer vistazo a la exponencial

Generá 5000 exponenciales con λ = 0,5 y compará la media muestral con la teórica 1/λ = 2. Es el adelanto del Tema 22.

Ver una posible respuesta
import random
import math

random.seed(3)
lam, N = 0.5, 5000
muestra = [-math.log(1 - random.random()) / lam for _ in range(N)]
media = sum(muestra) / N
print(round(media, 3))
print("teórica:", 1 / lam)

La media muestral cae cerca de 2 (típicamente 1,95–2,05). Si da muy lejos, revisá la fórmula: es -ln(1-U)/λ, no -ln(U·λ).

09 · Síntesis

Ideas para recordar

  • Generar X ~ F es transformar U ~ U(0,1) con un método g determinista.
  • El umbral U < p ya es un generador exacto de Bernoulli(p) porque P(U < p) = p.
  • Todo generador combina fuente uniforme, objetivo F, método y validación.
  • La semilla fija la secuencia para reproducir; la calidad la dan el algoritmo base y el método.
  • Ningún generador se acepta sin comparar muestra vs. F con N grande.

En el próximo tema generalizaremos el umbral a cualquier variable discreta: inversión de la CDF por acumuladas y búsqueda por intervalos.