Implementing Hierarchical Bayesian Regression with NumPyro
A step-by-step guide to hierarchical Bayesian regression using NumPyro.
Overview
In this tutorial, we explore hierarchical Bayesian regression with NumPyro and walk through the entire workflow in a structured manner. We start by generating synthetic data, then we define a probabilistic model that captures both global patterns and group-level variations. Through each code snippet, we set up inference using NUTS, analyze posterior distributions, and perform posterior predictive checks.
Setting Up the Environment
Before diving into modeling, we set up our environment by installing NumPyro and importing the required libraries. This ensures our Colab session is fully equipped for hierarchical modeling.
try:
import numpyro
except ImportError:
!pip install -q "llvmlite>=0.45.1" "numpyro[cpu]" matplotlib pandas
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import jax
import jax.numpy as jnp
from jax import random
import numpyro
def generate_data(key, n_groups=8, n_per_group=40):
# Function implementation here
key = random.PRNGKey(0)
df, truth = generate_data(key)Generating Synthetic Data
Next, we generate synthetic hierarchical data mimicking real-world group-level variation. We prepare the data for processing in JAX:
def generate_data(key, n_groups=8, n_per_group=40):
# Function implementation here
# Generate data
key = random.PRNGKey(0)
df, truth = generate_data(key)Defining the Hierarchical Regression Model
We define our hierarchical regression model and launch the NUTS-based MCMC sampler:
def hierarchical_regression_model(x, group_idx, n_groups, y=None):
# Function implementation here
nuts = NUTS(hierarchical_regression_model, target_accept_prob=0.9)
mcmc = MCMC(nuts, num_warmup=1000, num_samples=1000, num_chains=1)
mcmc.run(random.PRNGKey(1), x=x, group_idx=groups, n_groups=n_groups, y=y)
samples = mcmc.get_samples()Analyzing Posterior Samples
We compute summaries of our posterior samples and conduct posterior predictive checks:
def param_summary(arr):
# Function implementation here
for name in ["mu_alpha", "mu_beta", "sigma_alpha", "sigma_beta", "sigma_obs"]:
m, lo, hi = param_summary(samples[name])
print(f"{name}: mean={m:.3f}, HPDI=[{lo:.3f}, {hi:.3f}]")Visualizing Results
Finally, we visualize the estimated group-level intercepts and slopes to compare them with true values:
alpha_g = np.asarray(samples["alpha_g"]).mean(axis=0)
beta_g = np.asarray(samples["beta_g"]).mean(axis=0)
fig, axes = plt.subplots(1, 2, figsize=(12, 4))
axes[0].bar(range(n_groups), alpha_g)
axes[0].axhline(truth["true_alpha"], linestyle="--")
plt.show()Conclusion
We have implemented a comprehensive hierarchical Bayesian regression workflow using NumPyro. This process allows us to model hierarchical relationships effectively, leveraging the strengths of JAX-powered inference.
Сменить язык
Читать эту статью на русском