Predicciones con Incertidumbre: PyMC3 para Ciencia de Datos

15 JUN., 2025

//

5 min. de Lectura

En el mundo real, las predicciones perfectas son una ilusión. Nosotros enfrentamos constantemente la incertidumbre: desde fluctuaciones del mercado hasta variabilidad biológica. PyMC3 emerge como la herramienta esencial para científicos de datos que buscan no solo predecir, sino cuantificar la incertidumbre en sus predicciones. Este artículo revela cómo el modelado probabilístico bayesiano con PyMC3 transforma puntos únicos en distribuciones completas, proporcionando no solo respuestas sino intervalos de confianza, probabilidades de escenarios y medidas de riesgo. Descubrirás cómo implementar modelos que capturan la complejidad del mundo real, desde problemas básicos hasta arquitecturas avanzadas de deep learning probabilístico.

Fundamentos de PyMC3: Más Allá de los P-Valores

PyMC3 implementa inferencia probabilística mediante muestreo MCMC (Monte Carlo vía Cadenas de Markov) y VI (Inferencia Variacional). Nosotros contrastamos este enfoque con estadística frecuentista:

Enfoque Frecuentista Bayesiano (PyMC3)
Incertidumbre Intervalos de confianza Distribuciones posteriores completas
Resultado p-valores crípticos Probabilidades interpretables
Datos escasos Problemas con poder estadístico Incorporación de conocimiento previo
Complejidad Limitado a modelos lineales Modelos jerárquicos y no lineales

Instalación básica:

    # Instalación de PyMC3 y dependencias
    pip install pymc3 arviz numpy pandas matplotlib

    # Importación estándar
    import pymc3 as pm
    import arviz as az
    import numpy as np

Construcción de Modelos: De Regresión a Deep Learning Probabilístico

Implementemos modelos escalando en complejidad:

1. Regresión Lineal Bayesiana:

    
    with pm.Model() as linear_model:
        # Priors
        alpha = pm.Normal('intercept', mu=0, sigma=10)
        beta = pm.Normal('slope', mu=0, sigma=10, shape=X.shape[1])
        sigma = pm.HalfNormal('sigma', sigma=1)
        
        # Lineal predictor
        mu = alpha + pm.math.dot(X, beta)
        
        # Likelihood
        likelihood = pm.Normal('y', mu=mu, sigma=sigma, observed=y)
        
        # Muestreo
        trace = pm.sample(2000, tune=1000, cores=4)
    

2. Modelo Jerárquico para Datos Agrupados:

    
    with pm.Model() as hierarchical_model:
        # Hiperpriors
        mu_alpha = pm.Normal('mu_alpha', mu=0, sigma=10)
        sigma_alpha = pm.HalfNormal('sigma_alpha', sigma=5)
        
        # Efectos por grupo
        alpha = pm.Normal('alpha', mu=mu_alpha, sigma=sigma_alpha, shape=n_groups)
        
        # Efectos fijos
        beta = pm.Normal('beta', mu=0, sigma=5, shape=X.shape[1])
        
        # Likelihood
        mu = alpha[group_idx] + pm.math.dot(X, beta)
        likelihood = pm.Normal('y', mu=mu, sigma=sigma, observed=y)
    

3. Bayesian Neural Network con PyMC3:

    
    import theano.tensor as tt

    # Arquitectura de red neuronal
    def build_nn(inputs):
        # Capa oculta con 20 neuronas
        w1 = pm.Normal('w1', mu=0, sigma=1, shape=(inputs.shape[1], 20))
        b1 = pm.Normal('b1', mu=0, sigma=1, shape=20)
        layer1 = tt.tanh(tt.dot(inputs, w1) + b1)
        # Capa de salida
        w2 = pm.Normal('w2', mu=0, sigma=1, shape=(20, 1))
        b2 = pm.Normal('b2', mu=0, sigma=1, shape=1)
        output = tt.dot(layer1, w2) + b2
        
        return output

    with pm.Model() as nn_model:
        # Construir red
        prediction = build_nn(X)
        
        # Priors para pesos ya definidos en build_nn
        
        # Likelihood
        pm.Normal('y', mu=prediction, sigma=sigma, observed=y)
        
        # Muestreo con NUTS
        trace = pm.sample(target_accept=0.95)
    

Inferencia y Diagnóstico: Validando Nuestras Cadenas

El muestreo MCMC requiere validación rigurosa:

  • R-hat < 1.01: Indica convergencia
  • ESS > 400: Tamaño muestral efectivo suficiente
  • Autocorrelación baja: Muestras independientes

Diagnóstico con ArviZ:

    
    # Resumen estadístico
    az.summary(trace, round_to=2)

    # Gráfico de rastreo
    az.plot_trace(trace)

    # Gráfico de bosque
    az.plot_forest(trace, var_names=['beta'])

    # Autocorrelación
    az.plot_autocorr(trace)
    

Para problemas de convergencia:

  • Aumentar tune (fase de adaptación)
  • Usar target_accept=0.95
  • Reescalar variables
  • Considerar parametrizaciones no centradas

Predicciones con Intervalos de Confianza: La Incertidumbre Cuantificada

Generamos predicciones con intervalos de credibilidad:

    
    with linear_model:
        # Predicción sobre nuevos datos
        pm.set_data({'x': X_new})
        posterior_predictive = pm.sample_posterior_predictive(
        trace, samples=2000, var_names=['y']
        )

        # Extraer intervalos de credibilidad
        y_pred = posterior_predictive['y']
        y_mean = y_pred.mean(axis=0)
        y_hdi = az.hdi(y_pred)  # Intervalo de densidad más alta
    

Visualización con incertidumbre:

    
    import matplotlib.pyplot as plt

    plt.figure(figsize=(10, 6))
    plt.plot(X_new, y_mean, 'b-', label='Predicción media')
    plt.fill_between(
        X_new.flatten(), 
        y_hdi[:, 0], 
        y_hdi[:, 1], 
        color='blue', 
        alpha=0.2, 
        label='94% HDI'
    )
    plt.scatter(X_train, y_train, c='red', alpha=0.4, label='Datos observados')
    plt.legend()
    plt.title('Predicción con Intervalos de Credibilidad')
    plt.show()
    

Para decisiones empresariales, calculamos probabilidades de escenarios:

    
    # Probabilidad de que las ventas excedan 1000 unidades
    sales_samples = posterior_predictive['sales']
    prob_over_1000 = (sales_samples > 1000).mean()
    print(f"Probabilidad de ventas > 1000: {prob_over_1000:.2%}")

    # Valor en Riesgo (VaR) al 95%
    var_95 = np.percentile(sales_samples, 5)
    print(f"Peor escenario (95% confianza): {var_95:.0f} unidades")
    

Casos de Éxito: PyMC3 en Acción

Aplicaciones reales con impacto medible:

  • Finanzas: Modelo de riesgo crediticio con probabilidad de default dinámica
  • Salud: Predicción de progresión de enfermedades con intervalos de credibilidad
  • Marketing: Atribución bayesiana de conversión multicanal
  • Manufactura: Control de calidad con modelos jerárquicos por lote

Ejemplo: Modelo de crecimiento epidemiológico:

    
    with pm.Model() as seir_model:
        # Parámetros epidemiológicos con priors
        beta = pm.Lognormal('beta', mu=0, sigma=0.5)
        gamma = pm.Lognormal('gamma', mu=np.log(1/8), sigma=0.2)
        sigma = pm.Lognormal('sigma', mu=np.log(1/5), sigma=0.2)
        
        # Compartimentos S, E, I, R
        S, E, I, R = [tt.vector() for _ in range(4)]
        
        # Ecuaciones diferenciales
        dS = -beta * S * I / N
        dE = beta * S * I / N - sigma * E
        dI = sigma * E - gamma * I
        dR = gamma * I
        
        # Solución ODE
        solution, updates = theano.scan(
        fn=lambda t, S, E, I, R: [S + dS, E + dE, I + dI, R + dR],
        sequences=[time],
        outputs_info=[S0, E0, I0, R0]
        )
        
        # Likelihood
        pm.NegativeBinomial('obs', mu=solution[2], alpha=phi, observed=cases)
    

Optimización para Producción: De Jupyter a APIs en Tiempo Real

Llevamos modelos PyMC3 a producción con:

  • Inferencia Variacional: Para predicción rápida
  • Caché de posteriores: Reutilización de distribuciones muestreadas
  • Serialización: Almacenamiento con pickle o joblib
  • APIs con FastAPI: Servicio de predicciones con incertidumbre

API de predicción con FastAPI:

    
    from fastapi import FastAPI
    import joblib

    app = FastAPI()
    model = joblib.load('bayesian_model.pkl')

    @app.post("/predict")
    async def predict(data: dict):
    samples = model.predict(data['inputs'], samples=1000)
    return {
        "mean": float(samples.mean()),
        "hdi_94": [float(samples.hdi[0]), float(samples.hdi[1])],
        "samples": samples.tolist()
    }
    

Para actualizaciones en tiempo real, implementamos Bayesian Online Learning con filtros de partículas.

Conclusión: La Incertidumbre como Ventaja Competitiva

Dominar PyMC3 para predicciones con incertidumbre no es solo una habilidad técnica; es un cambio de paradigma en la toma de decisiones. Nosotros hemos comprobado cómo organizaciones que cuantifican y comunican incertidumbre toman decisiones más robustas, gestionan riesgos proactivamente y generan confianza con stakeholders.

En 2024, con la integración de PyMC3 con bibliotecas como TensorFlow Probability y PyTorch, el modelado bayesiano se ha vuelto accesible para problemas de gran escala. La verdadera ventaja competitiva ya no está en predicciones puntuales, sino en comprender y gestionar el espectro completo de posibilidades. Cuando entregamos no solo un número sino una distribución, transformamos datos en sabiduría estratégica.

Inicia sesión para dar like
¡Like agregado!
Share:

Comentarios

0
Mínimo 10 caracteres /

Sin comentarios

Sé el primero en compartir tu opinión.

También te puede interesar

15 JUN., 2025 Inferencia Bayesiana: De Prior a Posterior en Código Python

desmitificaremos el teorema de Bayes y lo implementaremos en Python

Bonnie image
José Elías Romero Guanipa
Autor
logo

©2024 ViveBTC