01 · Punto de partida
Simular en streaming, no en planilla
Una simulación larga escupe miles de observaciones por segundo. Guardarlas todas para promediar al final gasta memoria, impide ver en vivo y rompe con el primer overflow. La salida profesional: actualizar (n, media, M2) con cada dato y tirar el dato.
- ¿Cómo actualizar la media sin la suma total?
- ¿Cómo llevar la varianza sin el historial?
- ¿Por qué la fórmula ingenua explota en flotantes?
- ¿Cómo combinar dos bloques ya resumidos?
02 · Definición
Estado mínimo y exacto
Conteo
Cuántos datos entraron. Sin n no hay promedio ni grados (n−1).
Media viva
El promedio de lo visto hasta ahora. Cada dato la tira un 1/n hacia él.
Suma centrada
Σ(x−m)² acumulada sin guardar x. Dividida entre n−1 da s² (Tema 24).
| Aspecto | Ingenuo Σx, Σx² | Welford |
|---|---|---|
| Memoria | O(1) pero sumas gigantes | O(1): n, m, M2 |
| Estabilidad | Catástrofe por cancelación | Estable (diferencias pequeñas) |
| En vivo | Sí, pero riesgoso | Sí: media + s + EE por paso |
03 · Método
Algoritmo en 4 líneas
- 1Inicializar (0, 0, 0).
n = 0, media = 0, M2 = 0. Sin datos no hay estadístico.
- 2Por cada x: actualizar.
n += 1; δ = x − media; media += δ/n; M2 += δ·(x − media). Notar los dos «media» distintos.
- 3Leer s² = M2/(n−1).
Con n = 1, s² indefinida (un punto no dispersa). Con n ≥ 2, insesgada.
- 4Combinar bloques (Chan).
Dos resúmenes (n₁,m₁,M2₁) + (n₂,m₂,M2₂) se fusionan sin los datos: ideal para paralelo y réplicas.
04 · Estabilidad
Por qué lo ingenuo explota
Ingenuo
Σx² − (Σx)²/n
Resta dos gigantes casi iguales: con datos ~10⁶ la cancelación devora los decimales y hasta da varianza negativa.
Welford
Diferencias pequeñas
Opera con (x − media), números chicos y centrados. El error no crece con la magnitud de x.
- Fusión de Chan
- δ = m₂−m₁; m = (n₁m₁+n₂m₂)/N; M2 = M2₁+M2₂+δ²n₁n₂/N. Réplicas en paralelo sin juntar datos.
- Ventana y calentamiento
- Welford puro recuerda todo. Para estado estacionario (Temas 30–33) reiniciar tras el transitorio o usar ventana móvil.
- s vs. EE en vivo
- Por paso: s = √(M2/(n−1)), EE = s/√n. Parar cuando EE ≤ precisión (Tema 27).
05 · Representación en Python
Welford en 12 líneas, exacto
Python en tu navegador. Compara contra el cálculo por lotes: idéntico hasta el decimal 12.
xs = [11, 13, 12, 14, 12, 13]
n, media, M2 = 0, 0.0, 0.0
for x in xs:
n += 1
delta = x - media
media += delta / n
M2 += delta * (x - media)
s2 = M2 / (n - 1)
import math
print(f"recursivo: media={media:.4f} s²={s2:.4f} s={math.sqrt(s2):.4f}")
m2 = sum(xs)/len(xs)
print(f"lotes: media={m2:.4f} s²={sum((v-m2)**2 for v in xs)/(len(xs)-1):.4f}")
Idénticos. La diferencia está en memoria O(1) y estabilidad, no en el resultado.
Clase reutilizable + fusión
class RunningStats:
def __init__(self):
self.n, self.m, self.M2 = 0, 0.0, 0.0
def add(self, x):
self.n += 1
d = x - self.m
self.m += d / self.n
self.M2 += d * (x - self.m)
@property
def var(self):
return self.M2 / (self.n - 1) if self.n > 1 else float("nan")
a, b = RunningStats(), RunningStats()
for x in [11, 13, 12]:
a.add(x)
for x in [14, 12, 13]:
b.add(x)
print(f"A:{a.m:.2f} B:{b.m:.2f} (fusionables por Chan sin los datos)")
06 · Exploración
Laboratorio: la media aprende en vivo
Flujo Normal(12, ruido). La curva lima es tu media recursiva paso a paso; la banda, ±2·EE en vivo (se angosta con √n). Mové el n (hasta dónde mirar) y el ruido. Los puntos son los datos que nunca guardás.
Welford en streaming
mₙ += (xₙ−m)/n · EE = s/√n en vivo
Con n=80, la media recursiva coincide con lotes y la banda es angosta.
Verde punteada: μ=12. Lima: media viva. La banda se cierra como 1/√n: el aprendizaje es rápido al inicio y lento después.
Preguntas para explorar
- Con n=80 y ruido 2: ¿media, s y EE finales? ¿Dif. contra lotes?
- Bajá a n=12: ¿ancho de la banda al final? ¿Qué enseña sobre parar temprano (Tema 27)?
- Subí el ruido a 4 con n=80: ¿la media converge igual? ¿Qué precio paga en EE?
Ver respuestas sugeridas
- Media ≈ 12 ± 0,2, s ≈ 2, dif ≈ 0,000000: idéntica a lotes. La banda ±2·EE ≈ ±0,45.
- Banda ≈ ±1,2: ancha e inútil para decidir. Parar con EE grande es dictaminar a ciegas.
- Converge igual (insesgada) pero EE ≈ 0,45 (doble): mismo centro, mitad de confianza. El ruido se paga en n.
07 · Comprensión
Confusiones frecuentes
«Recursivo es aproximado»
No: es algebraicamente idéntico a lotes (salvo redondeo, donde es mejor). La diferencia es memoria y estabilidad, no exactitud.
«Guardo todo por si acaso»
Guardar millones de flotantes «por si» impide el en vivo y revienta memoria. Guardar (n, m, M2) + muestras de auditoría alcanza.
«M2/(n) o /(n−1) da igual»
Para s² inferencial es /(n−1) (Tema 24). En streaming el error se arrastra millones de pasos: hacerlo bien desde el inicio.
«Welford olvida el pasado»
No olvida nada: lo resume exactamente. Para olvidar (ventanas, calentamiento) usar variantes con decaimiento, declaradas.
08 · Práctica guiada
Ejercicios con Python
Ejercicio 1: un paso a mano
Con m=12, n=4 llega x=16. ¿m′ y aporte a M2?
m, n, x = 12.0, 4, 16
mp = m + (x-m)/(n+1)
print(f"m'={mp:.2f} aporte={(x-m)*(x-mp):.2f}")
Ver solución razonada
m′ = 12,80, aporte = 12,80 a M2. El dato tira la media 0,8 hacia él y suma su «sorpresa» bilateral.
Ejercicio 2: ingenuo que explota
¿Qué le pasa a Σx² − (Σx)²/n con datos ~10⁶?
xs = [1_000_001, 1_000_002, 1_000_003]
s1, s2 = sum(xs), sum(x*x for x in xs)
print("ingenuo:", s2 - s1*s1/len(xs), "(redondeo peligroso)")
print("Welford: 2.0 exacto y estable")
Ver solución
El ingenuo resta ~3×10¹² − ~3×10¹² y el redondeo devora; puede dar hasta negativo. Welford opera con ±1: exacto.
Ejercicio 3: EE en vivo para parar
¿Cuándo parar si se exige EE ≤ 0,2 con s ≈ 2?
Ver una posible respuesta
import math
print("n ≈ (2/0.2)² =", int((2/0.2)**2), "(Tema 27: parar por precisión)")
n ≈ 100: el monitor en vivo con Welford detiene la simulación al alcanzar la precisión, sin desperdiciar réplicas.
09 · Síntesis
Ideas para recordar
- Estado (n, m, M2): memoria O(1), exactitud de lotes, estabilidad superior.
- m += δ/n, M2 += δ·(x−m′), s² = M2/(n−1), EE = s/√n en vivo.
- Fusión de Chan para paralelo sin juntar datos.
- Parar por EE (Tema 27), reiniciar tras calentamiento (Temas 30–31).
- Nunca Σx² − (Σx)²/n en producción.
En el próximo tema usaremos ese EE vivo para los intervalos de confianza.