01 · Punto de partida
Uniforme no es independiente
La secuencia 0,1 · 0,9 · 0,1 · 0,9 … pasa chi-cuadrado (Tema 27) con nota perfecta y es una calamidad: sabiendo un valor sabés el siguiente. La uniformidad mira cuántos caen en cada caja; la independencia mira en qué orden llegan. Sin la segunda pata, tu “azar” es un disco rayado con buena distribución.
Este tema trae las dos pruebas baratas que ningún auditor perdona: autocorrelación (¿el pasado lineal predice?) y rachas (¿sube y baja como debe?).
- ¿Qué mide la correlación lag-h y cuánto vale en un sano?
- ¿Qué es una racha y cuántas debe haber en N valores?
- ¿Por qué mirar varios lags y no solo el 1?
- ¿Corr ≈ 0 certifica independencia?
02 · Definición
Dos lentes para el orden
Autocorrelación
corr(h) entre uₙ y uₙ₊ₕ: en un sano ≈ 0 con banda ±1,96/√N. El correlograma grafica h = 1…10.
Rachas
Racha = tramo monótono (+/− entre vecinos). En N valores sanos: media (2N−1)/3, var (16N−29)/90, Z normal.
Lags varios
Un LCG malo esconde corr 0 en lag-1 y explota en lag-3; RANDU duerme en 1D y despierta en 3D. Mirar 1…10, no uno.
| Prueba | Detecta | No ve |
|---|---|---|
| Autocorrelación | Dependencia lineal por lag | Dependencia no lineal (uₙ₊₁ ≈ 4uₙ(1−uₙ)) |
| Rachas sube/baja | Alternancia o pegoteo excesivo | Sesgo de media (pasa con media corrida) |
| Ambas + χ² | Lo lineal y lo marginal | Estructuras en pares/ternas (Temas 30, 32) |
03 · Procedimiento correcto
Bandas, Z y réplicas
Con N = 2000 la banda del correlograma es ±1,96/√2000 ≈ ±0,044: barras dentro = ruido; barras que la cruzan sistemáticamente = dependencia. Para rachas, Z = (R − media)/√var se compara con ±1,96 al 5 %: |Z| > 1,96 rechaza.
- N previo
- Fijar N y lags (1…10) antes de mirar. Con N = 50 las bandas son ±0,28: todo “pasa” por falta de potencia, no por calidad.
- Z en ambas colas
- Pocas rachas (pegoteo, Z ≪ 0) y muchas rachas (zigzag, Z ≫ 0) rechazan: el test es a dos colas, no solo “pocas”.
- Corr 0 ≠ independencia
- Corr solo ve lo lineal: la parábola logística
xₙ₊₁ = 4xₙ(1−xₙ)da corr ≈ 0 y es totalmente determinista. Para lo no lineal van series y gráficos (Temas 30–31).
Bien testeado
Correlograma + rachas
Lags 1…10 dentro de bandas, |Z| < 1,96, réplica con otra semilla. Informe con N, lags, corr(1) y Z.
Mal testeado
Solo lag-1
Un generador con período 3 da corr(1) ≈ −0,5 pero corr(3) ≈ 1: mirar un lag es cerrar un ojo.
04 · Ejemplos
Tres firmas típicas
- 1Sano, N = 2000.
corr(1…10) dentro de ±0,044, rachas ≈ 1333 con |Z| < 2: pasa.
- 2Alternada 0,1/0,9.
corr(1) ≈ −1, rachas = N−1 = 1999 con Z ≈ +25: rechazo estrepitoso en ambas.
- 3Juguete m = 16.
corr(1) positiva estable (~0,2) y rachas escasas: el ciclo corto se delata en el orden.
05 · Implementación en Python
corr + rachas a mano
Dos funciones puras, sin librerías: autocorrelación por lag y test de rachas sube/baja con Z. Probalas con random y con la alternada.
Python en tu navegador. Cambiá N a 200 y mirá cómo se ensanchan las bandas: la potencia vive en N.
import math
import random
def corr_lag(us, h=1):
n = len(us)
m = sum(us) / n
var = sum((u - m) ** 2 for u in us) / n
cov = sum((us[i] - m) * (us[i + h] - m) for i in range(n - h)) / (n - h)
return cov / var if var else 0.0
def test_rachas(us):
n = len(us)
signos = [1 if us[i + 1] > us[i] else -1 for i in range(n - 1)]
rachas = 1 + sum(1 for i in range(len(signos) - 1) if signos[i] != signos[i + 1])
media = (2 * n - 1) / 3
var = (16 * n - 29) / 90
z = (rachas - media) / math.sqrt(var)
return rachas, round(z, 2)
rng = random.Random(28)
us = [rng.random() for _ in range(2000)]
print("corr1:", round(corr_lag(us), 4), "banda:", round(1.96 / math.sqrt(2000), 4))
print("rachas:", test_rachas(us))
corr ≈ 0 dentro de ±0,044 y Z chico: pasa ambas. La alternada da corr −1 y Z ≈ +25.
La alternada se delata
import math
def corr_lag(us, h=1):
n = len(us)
m = sum(us) / n
var = sum((u - m) ** 2 for u in us) / n
cov = sum((us[i] - m) * (us[i + h] - m) for i in range(n - h)) / (n - h)
return cov / var if var else 0.0
alt = [0.1, 0.9] * 1000
print("corr1:", round(corr_lag(alt), 4), "corr2:", round(corr_lag(alt, 2), 4))
06 · Exploración
Laboratorio: correlograma en vivo
Tres fuentes, lags 1…8 con bandas del 95 %. El panel trae corr(1), rachas con Z y veredicto. Subí N: el sano se mete en bandas, los enfermos no.
Barras dentro o fuera
bandas ±1,96/√N
Sano con N = 500: barras dentro de bandas.
Barras naranjas cruzan las bandas: dependencia. La alternada alterna −1/+1 por construcción.
Preguntas para explorar
- Con sano y N = 100: ¿alguna barra cruza? ¿Y con N = 2000?
- Con alternada: ¿qué vale corr(1) y corr(2)? ¿Qué Z de rachas sale?
- Con juguete y N = 2000: ¿las barras se meten en bandas o persisten fuera?
Ver respuestas sugeridas
- Con N = 100 las bandas son ±0,196: casi todo “pasa” por falta de potencia. Con N = 2000 (±0,044) el sano sigue dentro.
- corr(1) ≈ −1, corr(2) ≈ +1, Z ≈ +25: zigzag perfecto, rechazo total.
- Persisten: la dependencia es estructural del ciclo, no ruido que se diluye.
07 · Comprensión
Confusiones frecuentes
«corr ≈ 0, es independiente»
Solo descarta lo lineal: la parábola logística es determinista con corr ≈ 0. Independencia exige batería (series, gráficos).
«Con lag-1 alcanza»
Dependencias de período 3 o 5 duermen en lag-1 y despiertan en su lag. El correlograma es 1…10 o no es.
«Muchas rachas es bueno (más mezcla)»
No: demasiadas rachas (Z ≫ 0) es zigzag artificial; demasiadas pocas (Z ≪ 0), pegoteo. Lo sano es el medio, |Z| < 1,96.
«Un lag fuera condena»
Con 10 lags al 5 % lo esperado por azar es 0,5 cruces: uno aislado se confirma con otra semilla, no se condena.
08 · Práctica guiada
Ejercicios con Python
Ejercicio 1: correlograma sano
Calculá corr(1…5) de random con N = 2000 y verificá que todas caen en ±0,044.
import math
import random
def corr_lag(us, h):
n = len(us)
m = sum(us) / n
var = sum((u - m) ** 2 for u in us) / n
cov = sum((us[i] - m) * (us[i + h] - m) for i in range(n - h)) / (n - h)
return cov / var
rng = random.Random(9)
us = [rng.random() for _ in range(2000)]
print([round(corr_lag(us, h), 4) for h in range(1, 6)])
Ver solución razonada
Cinco valores ≈ ±0,03 dentro de bandas: pasa. Si uno roza 0,05 aislado, repetir con otra semilla antes de sospechar.
Ejercicio 2: rachas del pegoteo
La secuencia de 2000 valores con bloques de 100 iguales (100×0,2, 100×0,8…) debe dar poquísimas rachas. Calculá Z.
import math
us = [0.2] * 100 + [0.8] * 100
us = us * 10
signos = [1 if us[i + 1] > us[i] else (-1 if us[i + 1] < us[i] else 0) for i in range(len(us) - 1)]
rachas = 1 + sum(1 for i in range(len(signos) - 1) if signos[i] != signos[i + 1] and 0 not in (signos[i], signos[i + 1]))
n = len(us)
z = (rachas - (2 * n - 1) / 3) / math.sqrt((16 * n - 29) / 90)
print(rachas, round(z, 2))
Ver solución
Z ≈ −40: poquísimas rachas, pegoteo total. El test a dos colas lo rechaza por la cola izquierda.
Ejercicio 3: período 3 escondido
La secuencia 0,2/0,5/0,8 repetida tiene corr(1) moderado pero corr(3) ≈ 1. Mostralo.
Ver una posible respuesta
def corr_lag(us, h):
n = len(us)
m = sum(us) / n
var = sum((u - m) ** 2 for u in us) / n
cov = sum((us[i] - m) * (us[i + h] - m) for i in range(n - h)) / (n - h)
return round(cov / var, 4)
us = [0.2, 0.5, 0.8] * 700
print("corr1:", corr_lag(us, 1), "corr3:", corr_lag(us, 3))
corr(1) ≈ −0,5 pero corr(3) ≈ 1,0: el lag-1 solo “ve” la mitad del truco. Moraleja del correlograma completo.
09 · Síntesis
Ideas para recordar
- Uniformidad mira cajas; independencia mira orden: hacen falta ambas.
- Correlograma 1…10 con bandas ±1,96/√N; un cruce aislado se confirma.
- Rachas: media (2N−1)/3, Z a dos colas, |Z| < 1,96.
- corr ≈ 0 no certifica: solo descarta lo lineal.
- N manda: con N chico todo pasa por falta de potencia.
En el próximo tema contamos lo más simple: pruebas de frecuencia por intervalos.