01 · Punto de partida
Más datos no arreglan mal azar
Todo el curso desemboca acá: la simulación come uniformes U(0,1) y devuelve promedios, colas y decisiones. Si el generador es bueno (Temas 12–17) y pasó las pruebas (Temas 26–32), el error cae con 1/√N y más réplicas ayudan. Si es malo —período corto (Tema 33), correlación (Tema 32), enteros con % sesgado (Tema 35)—, el resultado converge… al valor equivocado. Y converge con confianza: el intervalo se achica alrededor del sesgo.
El caso famoso es RANDU (IBM, años 60): parecía rápido e inofensivo hasta que los puntos 3D cayeron en 15 planos. Tu Monte Carlo puede tener su RANDU casero si improvisás parámetros.
- ¿Cómo distingo sesgo (sistemático) de ruido (estadístico)?
- ¿Qué defectos del generador sesgan la media, la varianza y las colas?
- ¿Por qué N grande no compensa un período corto?
- ¿Qué chequeo mínimo hago antes de creer un resultado?
02 · Definición
Sesgo que no se promedia
Sesgo
Desvío sistemático del valor real: media corrida, colas flacas, planos. Crece o se queda; nunca se promedia a cero.
Ruido √N
Dispersión honesta que cae ÷√10 cada ×10 réplicas. Es el error “bueno” que el intervalo cuantifica.
Período y lattice
Con período P solo existen P tuplas: pasado P, repetís azar. Y los LCG viven en hiperplanos (RANDU = 15 planos en 3D).
| Síntoma | Causa típica | Test que lo delata |
|---|---|---|
| π o media clavada fuera del real | Período corto / lattice gruesa | Series y gráfico 2D/3D (Temas 30–31) |
| Colas que no aparecen nunca | Bits bajos débiles / % sesgado | Frecuencia y χ² (Temas 27, 29) |
| Rachas o alternancia rara | Correlación lag-1 | Independencia y runs (Tema 28) |
03 · Anatomía
Los tres saboteadores
Todo sesgo de generador es uno de estos tres, o mezcla:
- Período corto (hambre de tuplas)
- Con módulo m solo hay m pares/triplas posibles: un Monte Carlo 3D con m = 2048 no explora el cubo, lo “pinta” con 2048 puntos. Más N solo repinta. (Tema 33.)
- Correlación (memoria fantasma)
- Sucesivos atados por la fórmula (
x(n+1) = a·x(n)+c): el lag-1 ≠ 0 tuerce promedios de pares, caminatas y colas. Se mide con autocorrelación (Tema 32). - Mapeo sesgado (el % tramposo)
int(u*n)con%sobre rango no divisor de m, ou = x/mcon redondeo al borde, carga unos valores más que otros. El histograma nace torcido (Tema 35).
Bien alimentado
Moderno + testeado
PCG/MT/Philox con período ≫ N, mapeo sin % (int(u*n) con tope), semilla registrada y χ² + runs en verde.
Mal alimentado
Casero improvisado
LCG con parámetros “lindos” (a=13, m=256), % n directo y sin tests: π clavado 0,1 fuera y colas que no existen.
04 · Ejemplos
Tres sesgos famosos
- 1RANDU y los 15 planos.
x(n+1) = 65539·x(n) mod 2³¹: en 3D todos los puntos caen en 15 planos. Integrar un volumen con eso es medir los huecos, no el volumen. - 2π con juguete m = 256.
Solo 256 pares posibles: el π estimado se clava en un valor fijo (sesgado ~0,1) por más que subas N a 100 000. Laboratorio de abajo.
- 3Dado con
% 6sesgado.Con
m = 2³²no divisible por 6, dos caras salen un tick más: en 1 M de tiros el χ² explota aunque “parezca” parejo a ojo.
05 · Demostración en Python
π bueno frente a π de juguete
El mismo Monte Carlo, dos fuentes: random (moderno) y un LCG de juguete m = 256. Uno converge a π; el otro a su lattice.
Python en tu navegador. Subí N a 20 000: el bueno se pega a 3,14 y el juguete ni se mueve de su sesgo.
import math
import random
def lcg_juguete(n, semilla=1, a=13, c=7, m=256):
x = semilla % m
for _ in range(n):
x = (a * x + c) % m
yield x / m
def pi_con(gen, n):
dentro = 0
it = iter(gen)
for _ in range(n):
x, y = next(it), next(it)
dentro += x * x + y * y < 1
return 4 * dentro / n
N = 5000
random.seed(44)
bueno = pi_con((random.random() for _ in range(2 * N)), N)
malo = pi_con(lcg_juguete(2 * N), N)
print("bueno:", round(bueno, 4), "malo:", round(malo, 4), "real:", round(math.pi, 4))
Bueno ≈ 3,14 ± 0,03; juguete clavado lejos (típico ~2,9–3,3 según semilla): el sesgo no baja con N.
El test de 2 líneas que lo hubiera delatado
vals = list(lcg_juguete(2000))
print("únicos:", len(set(vals)), "de 2000")
print("media:", round(sum(vals) / len(vals), 4))
06 · Exploración
Laboratorio: π con buen y mal generador
El mismo cuarto de círculo, dos lluvias de puntos: la verde usa un LCG serio (1664525/2³²) y la naranja el juguete (m = 256). Movete en N: la verde se pega a π; la naranja se clava en su lattice y deja de aprender.
π(N): converge o se clava
π ≈ 4 · dentro / N
Con N = 2000 el bueno roza π y el malo sigue en su lattice.
El eje x es N (pares); el eje y es el π estimado. La punteada es π real. La naranja se aplana lejos: más N no la mueve.
Preguntas para explorar
- Con N = 200: ¿se distinguen? ¿Y con N = 8000?
- Con N = 8000 (≫ período 256 del malo): ¿por qué la naranja no mejora aunque cuadrupliques N?
- Si dos semillas del generador bueno dan π distintos pero cercanos, ¿sesgo o ruido? ¿Y si el malo repite idéntico?
Ver respuestas sugeridas
- Con N chico ambas botan (ruido domina); con N grande la verde se pega a π y la naranja queda clavada: el sesgo sobrevive al ruido.
- Porque solo existen 256 pares: pasado 256 repite puntos. N grande repinta la misma lattice: el error es sistemático, no muestral.
- Dispersión entre semillas buenas = ruido √N (sano); repetición idéntica del malo = período agotado. El test de “otra semilla” separa ambos.
07 · Comprensión
Confusiones frecuentes
«Con N = 10 M todo generador sirve»
Al revés: N gigante exige período ≫ N. Si N supera al período, el “azar” es un loop: más réplicas solo confirman el sesgo con más decimales.
«Si la media da 0,5, el generador está bien»
Media 0,5 es necesaria pero no suficiente: RANDU daba media perfecta y fallaba en 3D. Faltan χ², runs y pares/ternas (Temas 27–31).
«El intervalo de confianza me protege del sesgo»
El intervalo cuantifica ruido, no sesgo: con mal generador se achica alrededor del valor equivocado. Falsa precisión.
«Cambiar la semilla arregla un mal generador»
Cambia el dibujo del sesgo, no el sesgo: otra ventana del mismo lattice. Se arregla cambiando de familia/parámetros, no de semilla.
08 · Práctica guiada
Ejercicios con Python
Ejercicio 1: contar el período
Mostrá que el juguete tiene 256 valores únicos aunque le pidas 2000.
def lcg(n, semilla=1, a=13, c=7, m=256):
x = semilla % m
for _ in range(n):
x = (a * x + c) % m
yield x / m
vals = list(lcg(2000))
print(len(set(vals)), "únicos de 2000")
Ver solución razonada
256 únicos: el ciclo se cierra y todo lo demás es repetición. Un π con N = 8000 usa cada par ~30 veces: no estima, recita.
Ejercicio 2: el sesgo no baja con N
Compará el error |π − real| del bueno y del malo con N = 1000 y N = 8000.
import math
import random
def pi_pares(pares):
dentro = sum(1 for x, y in pares if x * x + y * y < 1)
return 4 * dentro / len(pares)
random.seed(44)
for n in [1000, 8000]:
buenos = [(random.random(), random.random()) for _ in range(n)]
print(n, abs(pi_pares(buenos) - math.pi))
Ver solución
El bueno achica su error ~÷√8 al ×8 N; el malo mantiene su sesgo (~0,05–0,2) intacto. Esa es la firma: el error que no escala con 1/√N es sesgo.
Ejercicio 3: otra semilla, mismo sesgo
Repetí el π de juguete con semillas 1 y 2: ¿cambia el veredicto “lejos de π”?
Ver una posible respuesta
def pi_juguete(n, semilla):
x = semilla % 256
dentro = 0
for _ in range(n):
x = (13 * x + 7) % 256
px = x / 256
x = (13 * x + 7) % 256
py = x / 256
dentro += px * px + py * py < 1
return 4 * dentro / n
print(pi_juguete(5000, 1), pi_juguete(5000, 2))
Ambos lejos de π (distinto dibujo, mismo sesgo): cambiar semilla mueve la lattice, no la rompe. La cura es otra familia (Tema 17).
09 · Síntesis
Ideas para recordar
- Error = sesgo (no baja con N) + ruido/√N (sí baja).
- Nunca N > período: el azar se vuelve loop.
- Media 0,5 no alcanza: χ² + runs + pares/ternas.
- El intervalo mide ruido, no sesgo: puede ser falsamente preciso.
- Otra semilla ≠ otro generador: el sesgo se cambia de familia, no de semilla.
En el próximo y último tema ponemos todo a trabajar: un proyecto evaluador completo de un generador en Python.