About alterlab-pymc
alterlab-pymc is a skill for building, fitting, and evaluating Bayesian models with PyMC and ArviZ. It serves analysts and researchers working on uncertainty, hierarchical data, MCMC or variational inference, with workflow guides and diagnostics for the current APIs.
Key features
- 01Build regression and hierarchical models
- 02Run MCMC and variational inference
- 03Check prior and posterior predictions
- 04Diagnose convergence and sampling issues
- 05Compare models with PSIS-LOO
Use cases
- 01Estimate effects with uncertainty intervals
- 02Analyze grouped or multilevel data
- 03Check model fit with predictive simulations
- 04Compare candidate Bayesian models
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ alterlab-ieu/ alterlab-academic-skills --skill alterlab-pymcAfter installing, type/alterlab-pymcin Claude Code to confirm it loaded.
Bundled files
References and scripts installed along with SKILL.md.
assets/hierarchical_model_template.pylinear_regression_template.pyevals/evals.jsonreferences/distribution_selection.mddistributions.mdmodel_comparison.mdmodel_patterns.mdsampling_inference.mdworkflow_examples.mdworkflows.mdscripts/model_comparison.pymodel_diagnostics.pyDetails
From the project READMEPyMC Bayesian Modeling
Overview
PyMC is a Python library for Bayesian modeling and probabilistic programming. Build, fit, validate, and compare Bayesian models using the current API (PyMC ≥ 6 with ArviZ ≥ 1.1), including hierarchical models, MCMC sampling (NUTS), variational inference, and PSIS-LOO model comparison.
uv pip install "pymc[nutpie]" "arviz[matplotlib,h5netcdf]" # nutpie sampler, plotting backend, NetCDF I/O
PyMC 6 changed several defaults and names that most tutorials still use — read Version notes at the end before reusing PyMC 5 / ArviZ 0.x code.
When to Use This Skill
This skill should be used when:
- Building Bayesian models (linear/logistic regression, hierarchical models, time series, etc.)
- Performing MCMC sampling or variational inference
- Conducting prior/posterior predictive checks
- Diagnosing sampling issues (divergences, convergence, ESS)
- Comparing multiple models with PSIS-LOO cross-validation
- Implementing uncertainty quantification through Bayesian methods
- Working with hierarchical/multilevel data structures
- Handling missing data or measurement error in a principled way
Does NOT Trigger
| Scenario | Use Instead |
|---|---|
| Frequentist regression with p-values, standard errors, and residual diagnostics | alterlab-statsmodels |
| Reporting-focused mixed-effects model for nested data (lme4/glmmTMB/brms, statsmodels MixedLM, or bambi formulas) with ICC and variance-component reporting | alterlab-multilevel-models |
| Pooling effect sizes across studies (fixed/random effects, heterogeneity, funnel plots) | alterlab-meta-analysis |
| Point-prediction machine learning (random forests, gradient boosting, CV tuning) | alterlab-scikit-learn |
Standard Bayesian Workflow
Follow this 8-step workflow for building and validating Bayesian models:
- Data preparation — standardize predictors, handle missing data, set up
coords - Model building — weakly informative priors, named
dims,pm.Data()for predictables - Prior predictive check —
pm.sample_prior_predictive; validate priors before fitting - Fit —
pm.sample(draws=2000, tune=1000, chains=4, target_accept=0.9), thenpm.compute_log_likelihood(idata)if you will compare models - Diagnostics — R-hat < 1.01, ESS > 400, no divergences, good trace mixing
- Posterior predictive check —
pm.sample_posterior_predictive; check fit vs. observed data - Analyze —
az.summary,az.plot_dist(wasplot_posterior),az.plot_forest - Predict —
pm.set_datathenpm.sample_posterior_predictive; extract HDI intervals
Full step-by-step code: references/workflow_examples.md.
Common Model Patterns
PyMC supports linear/logistic/Poisson regression, hierarchical (multilevel) models, and
time-series (AR). Ready-to-adapt code for each lives in references/model_patterns.md.
Use the non-centered parameterization for hierarchical models when groups have few observations: the centered form creates funnel geometry that NUTS explores poorly, which shows up as divergences.
Templates: assets/linear_regression_template.py, assets/hierarchical_model_template.py.
Distribution Selection
Choosing priors and likelihoods is the highest-leverage modeling decision. A quick chooser
(scale params, unbounded, positive, probabilities, correlation matrices; continuous/count/binary/
categorical likelihoods) is in references/distribution_selection.md. The comprehensive catalog
is in references/distributions.md.
Model Comparison and Sampling
- Compare models with PSIS-LOO (
scripts/model_comparison.py); interpretelpd_diffagainstdseand check Pareto-k. ArviZ 1.x has no WAIC. - Sample with NUTS by default (nutpie when installed); raise
target_acceptfor divergences; ADVI for fast approximation. - Diagnose with
scripts/model_diagnostics.py(check_diagnostics,create_diagnostic_report). - Troubleshoot divergences, low ESS, high R-hat, slow sampling.
Code and decision rules: references/model_comparison.md. Detailed sampling-algorithm guide:
references/sampling_inference.md.
Best Practices
Model Building
- Always standardize predictors for better sampling
- Use weakly informative priors (not flat)
- Use named dimensions (
dims) for clarity - Non-centered parameterization for hierarchical models
- Check prior predictive before fitting
Sampling
- Run multiple chains (at least 4) for convergence
- Use
target_accept=0.9as baseline (higher if needed) - Call
pm.compute_log_likelihood(idata)before model comparison - Set random seed for reproducibility
Validation
- Check diagnostics before interpretation (R-hat, ESS, divergences)
- Posterior predictive check for model validation
- Compare multiple models when appropriate
- Report uncertainty (HDI intervals, not just point estimates)
Start simple and add complexity gradually, iterating on the model based on each predictive check (see the 8-step workflow above).
Resources
This skill includes:
References (references/)
workflow_examples.md: Full step-by-step code for the 8-step Bayesian workflow (data prep → predictions).model_patterns.md: Ready-to-adapt code for linear/logistic/Poisson regression, hierarchical, and AR time-series models.distribution_selection.md: Quick chooser for priors and likelihoods by parameter/outcome type.model_comparison.md: PSIS-LOO comparison, diagnostic scripts, and troubleshooting (divergences, ESS, R-hat, slow sampling).distributions.md: Comprehensive catalog of PyMC distributions organized by category (continuous, discrete, multivariate, mixture, time series). Use when selecting priors or likelihoods.sampling_inference.md: Detailed guide to sampling algorithms (NUTS, Metropolis, SMC), variational inference (ADVI, SVGD), and handling sampling issues. Use when encountering convergence problems or choosing inference methods.workflows.md: A single end-to-end runnable script (data prep → save) plus extra cookbook recipes not inworkflow_examples.md— missing-data imputation, QR reparameterization, mixture models, and a model-averaging helper.
Scripts (scripts/)
-
model_diagnostics.py: Automated diagnostic checking and report generation (handles both PyMC-NUTS and nutpie sample stats). Functions:check_diagnostics()for quick checks,create_diagnostic_report()for comprehensive analysis with plots. -
model_comparison.py: PSIS-LOO model comparison utilities. Functions:compare_models(),check_loo_reliability(),model_averaging().
Templates (assets/)
-
linear_regression_template.py: Complete template for Bayesian linear regression with full workflow (data prep, prior checks, fitting, diagnostics, predictions). -
hierarchical_model_template.py: Complete template for hierarchical/multilevel models with non-centered parameterization and group-level analysis.
Quick Reference
Model Building
with pm.Model(coords={'var': names}) as model:
# Priors
param = pm.Normal('param', mu=0, sigma=1, dims='var')
# Likelihood
y = pm.Normal('y', mu=..., sigma=..., observed=data)
Sampling
idata = pm.sample(draws=2000, tune=1000, chains=4, target_accept=0.9) # returns xarray.DataTree
pm.compute_log_likelihood(idata) # needed for LOO / az.compare
Diagnostics
from scripts.model_diagnostics import check_diagnostics
check_diagnostics(idata)
Model Comparison
from scripts.model_comparison import compare_models
compare_models({'m1': idata1, 'm2': idata2}) # PSIS-LOO; higher elpd is better
Predictions
# X must have been wrapped at build time: pm.Data('X', X, dims=('obs', 'predictors'))
with model:
pm.set_data({'X': X_new}, coords={'obs': range(len(X_new))})
pm.sample_posterior_predictive(idata, predictions=True, extend_inferencedata=True)
# predictions land in idata.predictions
Additional Notes
- PyMC integrates with ArviZ for visualization and diagnostics
- Use
pm.model_to_graphviz(model)to visualize model structure (needs thegraphvizpackage) - Save results with
idata.to_netcdf('results.nc')(requiresh5netcdfornetCDF4, e.g.arviz[h5netcdf]); load withaz.from_netcdf('results.nc') - For very large models, consider minibatch ADVI or data subsampling
Version notes (PyMC 6 / ArviZ 1.x)
PyMC 6.0 (May 2026) moved to ArviZ 1.x and PyTensor 3. Code written for PyMC 5 / ArviZ 0.x fails in the ways below.
- Results are an
xarray.DataTree, notaz.InferenceData. Group access (idata.posterior,idata["posterior"]) still works;idata.extend(other)becameidata.update(other); list groups withlist(idata.children). - Log-likelihood: call
pm.compute_log_likelihood(idata)after sampling.pm.sample(idata_kwargs={"log_likelihood": True})is deprecated. - Sampler: nutpie is the default NUTS sampler when installed (400 tuning steps by default; PyMC's own NUTS keeps 1000). Select explicitly with
nuts_sampler="pymc" | "nutpie" | "numpyro" | "blackjax". Sample-stat names differ (tree_depthvsdepth), so diagnostics code should check which exists. Starting values go ininitvals=(start=fails). - Backend: PyTensor 3 compiles with Numba by default, so the first call includes JIT-compilation time.
- Summaries:
az.summaryreports 89% equal-tailed intervals (eti89_lb,eti89_ub) instead of 94% HDI (hdi_3%,hdi_97%). Useaz.summary(idata, ci_kind="hdi", ci_prob=0.94)or setaz.rcParams["stats.ci_kind"]/["stats.ci_prob"].az.hdi(..., prob=0.95)replaceshdi_prob=. - Plots return a
PlotCollection(save withpc.savefig("file.png"), show withpc.show());ax=/axes=arguments are gone. Renames:plot_posterior→plot_dist,plot_ppc→plot_ppc_dist(prior checks:group="prior_predictive",num_samples=instead ofnum_pp_samples=),plot_trace→plot_trace_dist(trace plus density),plot_dist_comparison→plot_prior_posterior. Install a backend witharviz[matplotlib]. - Model comparison:
az.waicis gone andaz.compare(dict)takes noic=/scale=; it ranks by PSIS-LOOelpd(higher is better) with stacking weights and reportselpd_diff,dse,p_worse, anddiag_*columns. - To predict on new data, the predictors must be wrapped in
pm.Data('X', X, dims=...)at build time — only then canpm.set_data({'X': X_new}, coords={...})swap them. A plain NumPy array baked into the graph cannot be replaced. pm.sample_prior_predictivetakesdraws=(the oldsamples=keyword was removed).- For out-of-sample predictions call
pm.sample_posterior_predictive(idata, predictions=True, extend_inferencedata=True, ...); results then live inidata.predictions, notidata.posterior_predictive.