Python & Data Science
Estadística En revisión

El Bootstrap: Cómo medir la incertidumbre sin asumir la normalidad

El problema: ¿Qué tan seguros estamos de este número?

Imagina que eres gerente de producto en una startup en crecimiento. Acabas de lanzar un nuevo botón de pago. Ahora monitoreas cuánto tarda la página en cargar y el panel muestra un promedio de 250 milisegundos.

Se siente bien, ¿no? Pero entonces se cuela un pensamiento más sutil: ¿ese 250ms refleja de verdad el sitio, o simplemente coincidiste con algunos usuarios rápidos esta hora?

Todo tomador de decisiones basado en datos conoce este temor. Hacemos grandes apuestas en un solo número: un promedio, una mediana, una tasa de conversión. Pero ese número es solo una estimación. Repite el mismo experimento mañana y podrías ver 270ms o 230ms. Normalmente recurriríamos a una fórmula para calcular nuestro margen de error. Pero esas fórmulas suelen asumir que tus datos siguen una curva de campana limpia y simétrica.

Los datos reales rara vez cooperan. La latencia de un sitio web, por ejemplo, suele estar sesgada: la mayoría de los usuarios cargan la página rápido, pero un puñado con conexiones lentas estira una cola larga a lo largo de tu gráfico. Aquí se ve cómo en código.

import numpy as np
import matplotlib.pyplot as plt

# Let's create some 'messy' latency data
# Most users are around 200ms, but some are much slower
np.random.seed(42)
data = np.random.exponential(scale=100, size=50) + 150

print(f"Our measured average latency: {np.mean(data):.2f}ms")

Obtenemos un solo promedio: 234.59ms. Pero ¿cuánto deberíamos confiar en él? Con apenas 50 usuarios, una sola persona que sufra un retraso de 2 segundos podría alterar ese número de forma sustancial. Necesitamos una manera de medir la incertidumbre sin depender de fórmulas que asumen que nuestros datos son “normales”.

La intuición: Levantándote por tus propias botas

Repetir nuestro experimento 1,000 veces nos diría cuánto se mueve el promedio. No tenemos el tiempo ni el dinero para eso.

En 1979, un estadístico llamado Bradley Efron popularizó un truco ingenioso llamado El Bootstrap. El nombre proviene de la antigua frase “levantarse tirando de los cordones de las botas”: la idea imposible de alzarse del suelo tirando de los cordones de tus propios zapatos. En estadística, significa usar los datos que ya tienes para simular los datos que no tienes.

¿Qué pasaría si nuestra muestra actual de 50 usuarios fuera una versión en miniatura del mundo entero? Para imaginar “realidades alternativas”, simplemente extraemos nuevas muestras de esos 50 usuarios.

Así es como haríamos esto manualmente por unas cuantas rondas.

# A manual look at 'alternative realities'
for i in range(3):
    # We pick 50 items from our data, allowing the same item to be picked twice
    resample = np.random.choice(data, size=len(data), replace=True)
    print(f"Reality #{i+1} average: {np.mean(resample):.2f}ms")

Cada ejecución nos da un promedio ligeramente diferente. Observar cuánto ‘oscila’ ese promedio empieza a revelar el verdadero rango de posibilidades.

La parte difícil: Por qué importa el ‘reemplazo’

Esta es la parte que suele confundir a la mayoría: ¿por qué importa replace=True?

Imagina una bolsa con 50 canicas. Si sacas 50 sin devolver ninguna, obtendrás las mismas 50 cada vez. El promedio nunca cambia. Sin margen de variación.

Sin embargo, si devuelves cada punto de datos después de extraerlo, abres la puerta a escenarios de “qué pasaría si”. En una simulación, ese usuario muy lento podría ser seleccionado tres veces. En otra, puede que no lo sea en absoluto. Esa variación es lo que nos permite medir la incertidumbre. Así que aquí está la diferencia.

# Without replacement: The average never changes
no_replace = np.random.choice(data, size=len(data), replace=False)
print(f"No replacement mean: {np.mean(no_replace):.2f}")

# With replacement: The average varies
with_replace = np.random.choice(data, size=len(data), replace=True)
print(f"With replacement mean: {np.mean(with_replace):.2f}")

La primera muestra siempre coincidirá con nuestros 234.59ms originales. La segunda no. Esa diferencia es la clave de todo.

Veamos qué pasa: Construyendo la distribución

Así que ejecutémoslo 10,000 veces en lugar de 3. Cada iteración registra un promedio. Al apilar miles de ellos, empieza a emerger una forma reconocible.

# We run the loop 10,000 times to be safe
bootstrap_means = []
for _ in range(10000):
    resample = np.random.choice(data, size=len(data), replace=True)
    bootstrap_means.append(np.mean(resample))

# Plot the results
plt.hist(bootstrap_means, bins=30, edgecolor='white')
plt.title("The Distribution of Possible Averages")
plt.xlabel("Latency (ms)")
plt.ylabel("Frequency")
plt.show()

No usamos una fórmula para una distribución T ni para un puntaje Z. Simplemente le pedimos a la computadora que simulara 10,000 mundos basados en nuestros datos originales. El histograma resultante muestra dónde probablemente se ubica el promedio ‘verdadero’.

Interpretando el intervalo de confianza

Entonces, ¿qué significa eso para nosotros? Ahora podemos calcular un Intervalo de Confianza — el rango donde se ubicaron el 95% central de nuestros promedios simulados.

# Calculate the 2.5th and 97.5th percentiles
lower_bound = np.percentile(bootstrap_means, 2.5)
upper_bound = np.percentile(bootstrap_means, 97.5)

print(f"We are 95% sure the true average is between {lower_bound:.2f}ms and {upper_bound:.2f}ms.")

Si ese rango es amplio — digamos, de 150ms a 400ms — nuestro promedio original de 234ms fue una estimación poco fiable. No deberíamos confiar en él para decisiones importantes. Un rango ajustado, como de 235ms a 250ms, y podemos estar mucho más seguros.

El detalle es el siguiente. La gente suele decir “hay un 95% de probabilidad de que la media verdadera esté aquí dentro”. Los estadísticos frecuentistas te dirán que la media verdadera es un número fijo. Es nuestro intervalo el que la contendría el 95% de las veces si ejecutáramos este proceso nuevamente. Sin embargo, para una recomendación de negocios, la conclusión es simple. Define la “zona de seguridad” para tu estimación.

Cierre: Cuándo usarlo (y cuándo tener cuidado)

El Bootstrap funciona para casi cualquier cosa. Estima la incertidumbre para una mediana o una correlación. Incluso puedes aplicarlo a métricas complejas de aprendizaje automático donde no existe una fórmula estándar.

Cuándo usarlo:

  • Cuando tus datos están sesgados o no siguen una curva de campana.
  • Cuando tienes un tamaño de muestra pequeño (pero no demasiado pequeño: generalmente al menos 10-20 puntos).
  • Cuando estás calculando algo inusual, como la razón de dos métricas diferentes.

La advertencia: Si tus 50 usuarios originales eran todos de la misma ciudad o todos usaban el mismo navegador, tu muestra está sesgada. El bootstrap no puede arreglar los datos sesgados. Solo te dará una respuesta muy segura que es fundamentalmente incorrecta. Te informa sobre el error de muestreo, no sobre la calidad de los datos.

Ahora que sabes cómo simular la incertidumbre, puedes aplicar esta misma lógica a problemas más complejos. Esta idea de ‘remuestreo’ sustenta técnicas de aprendizaje automático como Random Forests (también conocido como Bagging). Ya estás en camino de dominar la ciencia de datos robusta.

Comprueba tu comprensión

Las preguntas a continuación van desde el recuerdo simple hasta el diseño abierto, siguiendo aproximadamente la Taxonomía de Bloom.

Recordar ¿Por qué el remuestreo bootstrap debe hacerse “con reemplazo”, y qué le sucede al promedio si extraes una muestra sin reemplazo en su lugar?

Comprender En tus propias palabras, explica qué representan realmente las 10,000 medias bootstrap — ¿qué pregunta respondes al observar la forma de ese histograma?

Aplicar Usando el método de percentiles del artículo (np.percentile(bootstrap_means, 2.5) y 97.5), ¿qué te diría un intervalo resultante de [228.0, 241.5] sobre la confianza que deberías tener en la estimación original de 234.59ms, en comparación con el ejemplo “amplio” del artículo de 150ms-400ms?

Analizar La advertencia final del artículo dice que el bootstrap “no puede arreglar los datos sesgados” si los 50 usuarios eran todos de la misma ciudad. Explica paso a paso por qué remuestrear a partir de una muestra sesgada miles de veces sigue produciendo únicamente variaciones dentro de esa misma muestra sesgada — ¿qué información se necesitaría para detectar el sesgo que el remuestreo por sí solo nunca puede proporcionar?

Evaluar El artículo recomienda el bootstrap “cuando tienes un tamaño de muestra pequeño (pero no demasiado pequeño—usualmente al menos 10-20 puntos)”. Critica el límite inferior de esta regla: ¿qué falla específicamente con los intervalos de confianza bootstrap cuando la muestra original tiene, digamos, solo 5 puntos de datos, más allá de simplemente “el intervalo será amplio”?

Crear Diseña un análisis bootstrap para una nueva métrica que el artículo no cubre: el valor mediano del pedido para un conjunto de 40 transacciones de comercio electrónico con algunos valores atípicos extremos (un cliente compró $50,000 de inventario). Explica por qué el bootstrap se adapta bien a esta métrica en particular, dado que no existe una fórmula sencilla de libro de texto para el intervalo de confianza de una mediana.

Aplica lo que aprendiste

**Resumen:** Estás presentando el análisis de latencia en una revisión con las partes interesadas — 50 usuarios, datos con sesgo exponencial (escala=100, desplazamiento +150), media medida de 234.59ms. Un ingeniero senior objeta: "¿Por qué no simplemente usaste la fórmula estándar del intervalo t? Es más rápida y está respaldada por los libros de texto." Defiende tu elección del bootstrap sobre un intervalo t paramétrico para *este* conjunto de datos en ~200 palabras. Luego, presenta el argumento más fuerte a favor del lado paramétrico en ~100 palabras — dale su condición de victoria genuina más fuerte, no un hombre de paja.

Entregable: Un memorándum para las partes interesadas de ~300 palabras con dos secciones etiquetadas: “Por qué el bootstrap aquí” (~200 palabras) y “Cuándo ganaría el enfoque paramétrico” (~100 palabras). Sin código — este es un memorándum de defensa, no un notebook.

Rúbrica:

  • Defiende el bootstrap citando el sesgo real en este conjunto de datos (exponencial, n=50, media de 234.59ms) — no una vaga excusa de “los datos son desordenados”.
  • Invoca correctamente el muestreo con reemplazo y explica por qué produce la “fluctuación” que el muestreo sin reemplazo no puede generar.
  • Hace referencia al método de percentiles del IC (2.5th / 97.5th de 10,000 medias remuestreadas) como el mecanismo concreto que produjo el intervalo — no un vago “simulamos”.
  • Usa la interpretación frecuentista correcta del IC del 95%: no dice “95% de probabilidad de que la media verdadera esté en el intervalo”; en su lugar, lo enmarca como el intervalo que contendría la media verdadera el 95% de las veces al repetir todo el procedimiento.
  • El argumento más fuerte a favor del enfoque paramétrico le otorga una condición de victoria real — p. ej., una n grande, datos casi normales, o la necesidad de un límite de forma cerrada tratable — y reconoce al menos un escenario donde el intervalo t es la mejor herramienta.
  • Nombra la limitación de sesgo del cierre del artículo (p. ej., que los 50 sean de la misma ciudad / mismo navegador) como el límite explícito de la afirmación del bootstrap: cuantifica el error de muestreo, no la calidad de los datos — y concede que esta es una limitación de ambos métodos, no solo del bootstrap.

Esta traducción fue generada automáticamente y puede contener errores. Si el idioma inglés es tu preferencia, puedes leer el artículo original en inglés .

¿Buscas otra cosa?

Busca en todos los artículos por título, resumen o tema.