Inferencia Bayesiana: De Prior a Posterior en Código Python
15 JUN., 2025
//5 min. de Lectura

En un mundo inundado de datos, la inferencia bayesiana emerge como un faro de racionalidad que transforma la incertidumbre en conocimiento cuantificable. Nosotros hemos comprobado cómo este marco probabilístico revoluciona decisiones empresariales, diagnósticos médicos y sistemas de recomendación, superando en flexibilidad a métodos estadísticos tradicionales. En este viaje práctico, desmitificaremos el teorema de Bayes y lo implementaremos en Python desde sus fundamentos hasta aplicaciones avanzadas. Descubrirás cómo actualizar creencias a la luz de nueva evidencia, transformando distribuciones previas en posteriores ricas en información.
El Teorema de Bayes Desmitificado: Más Allá de la Fórmula
El núcleo de la inferencia bayesiana es una ecuación elegante que actualiza creencias:
$$P(θ|D) = [P(D|θ) × P(θ)] / P(D)$$
Donde:
- \(\ P(θ|D) \): Distribución posterior (nuestras creencias actualizadas)
- \(\ P(D|θ) \): Verosimilitud (probabilidad de los datos dado el parámetro)
- \(\ P(θ) \): Distribución previa (creencias iniciales)
- \(\ P(D) \): Evidencia (probabilidad marginal de los datos)
Implementación básica en Python:
def bayes_theorem(prior, likelihood, evidence):
return (likelihood * prior) / evidence
# Ejemplo: Probabilidad de enfermedad dado test positivo
prior = 0.01 # Prevalencia de la enfermedad
likelihood = 0.95 # Sensibilidad del test
evidence = 0.95*0.01 + 0.05*0.99 # P(positivo)
posterior = bayes_theorem(prior, likelihood, evidence)
print(f"Probabilidad posterior: {posterior:.2%}") # Solo 16.1%
Este ejemplo revela la paradoja bayesiana: incluso con un test "95% preciso", un resultado positivo implica solo 16.1% de probabilidad real de enfermedad. La intuición humana suele fallar aquí, pero Bayes corrige nuestro sesgo.
Distribuciones Previas: El Arte de Cuantificar la Ignorancia
Elegir la previa adecuada es tanto ciencia como arte. Nosotros clasificamos previas en:
- Previas informativas: Basadas en conocimiento experto
- Previas débiles: Reflejan ignorancia controlada
- Previas conjugadas: Facilitan cálculo analítico
Implementación con PyMC3 para diferentes previas:
import pymc3 as pm
with pm.Model():
# Previa débil: Uniforme entre 0 y 100
theta_uniform = pm.Uniform('theta', 0, 100)
# Previa informativa: Normal centrada en 30 ± 10
theta_normal = pm.Normal('theta', mu=30, sigma=10)
# Previa conjugada (Binomial-Beta)
theta_beta = pm.Beta('theta', alpha=2, beta=2) # Previa simétrica
# Verosimilitud Binomial
likelihood = pm.Binomial('obs', n=100, p=theta_beta, observed=60)
# Muestreo de la posterior
trace = pm.sample(2000, tune=1000)
La clave está en análisis de sensibilidad: probar múltiples previas y verificar si posteriores convergen. En problemas reales, usamos previas jerárquicas que modelan dependencias entre parámetros.
MCMC en Python: Muestreo de la Posterior con PyMC3 y NumPyro
Para posteriores no conjugadas, usamos Métodos de Monte Carlo vía Cadenas de Markov (MCMC). Implementamos dos enfoques:
1. PyMC3 (Probabilistic Programming):
import pymc3 as pm
import arviz as az
# Modelo: Estimación de media y desviación
with pm.Model():
# Previas
mu = pm.Normal('mu', mu=0, sigma=10)
sigma = pm.HalfNormal('sigma', sigma=1)
# Verosimilitud
likelihood = pm.Normal('obs', mu=mu, sigma=sigma, observed=data)
# Muestreo con NUTS (algoritmo avanzado de MCMC)
trace = pm.sample(2000, tune=1000, cores=4)
# Visualización
az.plot_trace(trace)
2. NumPyro (Basado en JAX):
import numpyro
import numpyro.distributions as dist
from numpyro.infer import MCMC, NUTS
def model(data):
# Parámetros con previas
mu = numpyro.sample('mu', dist.Normal(0, 10))
sigma = numpyro.sample('sigma', dist.HalfNormal(1))
# Verosimilitud
numpyro.sample('obs', dist.Normal(mu, sigma), obs=data)
# Configurar MCMC
nuts_kernel = NUTS(model)
mcmc = MCMC(nuts_kernel, num_samples=2000, num_warmup=1000)
mcmc.run(rng_key=random.PRNGKey(0), data=data)
# Resultados
mcmc.print_summary()
Diagnóstico de convergencia esencial:
- R-hat < 1.01: Indica convergencia
- Trazas estacionarias: Visualmente estables
- Autocorrelación baja: Muestras independientes
Aplicaciones Prácticas: De AB Testing a Sistemas de Recomendación
Implementemos dos casos reales:
1. Bayesian AB Testing:
def bayesian_ab_test(clicks_A, views_A, clicks_B, views_B):
with pm.Model():
# Previas Beta para tasas de conversión
theta_A = pm.Beta('theta_A', alpha=1, beta=1)
theta_B = pm.Beta('theta_B', alpha=1, beta=1)
# Verosimilitudes Binomiales
pm.Binomial('obs_A', p=theta_A, n=views_A, observed=clicks_A)
pm.Binomial('obs_B', p=theta_B, n=views_B, observed=clicks_B)
# Diferencia y probabilidad de que B > A
pm.Deterministic('diff', theta_B - theta_A)
pm.Deterministic('B_better', theta_B > theta_A)
trace = pm.sample(2000)
prob = trace['B_better'].mean()
print(f"Probabilidad de que B supere a A: {prob:.2%}")
2. Sistema de Recomendación Bayesiano:
import pymc3 as pm
import theano.tensor as tt
# Modelo de factorización matricial probabilística
with pm.Model() as pmf_model:
# Hiperparámetros
alpha = 2.0 # Previa de concentración
# Latent feature matrices
U = pm.Gamma('U', alpha=alpha, beta=alpha, shape=(n_users, k))
V = pm.Gamma('V', alpha=alpha, beta=alpha, shape=(n_items, k))
# Predicción de ratings
R_hat = tt.dot(U, V.T)
# Verosimilitud Poisson (para conteos)
pm.Poisson('obs', mu=R_hat[user_indices, item_indices],observed=ratings)
En AB testing bayesiano, obtenemos probabilidades directas ("Probabilidad de que B sea mejor: 92%") en lugar de p-values crípticos. Para recomendaciones, modelamos incertidumbre en preferencias latentes.
Inferencia Variacional: Velocidad para Datos Masivos
Cuando MCMC es muy lento, usamos Inferencia Variacional (VI):
from pymc3 import Variational
import pymc3 as pm
with pm.Model():
theta = pm.Normal('theta', mu=0, sigma=10)
likelihood = pm.Normal('obs', mu=theta, sigma=1, observed=data)
# Aproximación variacional
mean_field = pm.fit(method='advi', n=50000)
# Muestreo de la posterior aproximada
trace_variational = mean_field.sample(2000)
Comparativa de rendimiento:
Método | Tiempo (100k datos) | Precisión |
---|---|---|
MCMC (NUTS) | 45 min | Alta |
VI (ADVI) | 1.2 min | Media-Alta |
VI (SVGD) | 2.5 min | Muy Alta |
Para big data, combinamos VI con mini-batch usando pm.Minibatch
en PyMC3, reduciendo tiempo de entrenamiento en órdenes de magnitud.
Conclusión: La Actualización Continua como Filosofía
La inferencia bayesiana no es solo una técnica estadística; es un modelo mental para navegar la incertidumbre. Nosotros hemos implementado cómo este enfoque transforma datos en conocimiento probabilístico, permitiendo decisiones robustas en entornos complejos.
Al dominar las herramientas aquí presentadas—teorema de Bayes, previas significativas, MCMC con PyMC3, inferencia variacional y aplicaciones prácticas—adquieres la capacidad de construir modelos que evolucionan con la evidencia. La verdadera potencia surge cuando integramos este flujo en sistemas en tiempo real: modelos que se actualizan continuamente con nuevos datos, refinando sus predicciones constantemente. En la era de la incertidumbre, la inferencia bayesiana en Python es tu brújula para transformar datos dudosos en conclusiones confiables.
Comentarios
0Sin comentarios
Sé el primero en compartir tu opinión.
También te puede interesar
exploraremos estrategias avanzadas de fine-tuning que van más allá del ajuste básico