alterlab-pymc — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited alterlab-pymc (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
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/OPyMC 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.
This skill should be used when:
| 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 |
Follow this 8-step workflow for building and validating Bayesian models:
coordsdims, pm.Data() for predictablespm.sample_prior_predictive; validate priors before fittingpm.sample(draws=2000, tune=1000, chains=4, target_accept=0.9), then pm.compute_log_likelihood(idata) if you will compare modelspm.sample_posterior_predictive; check fit vs. observed dataaz.summary, az.plot_dist (was plot_posterior), az.plot_forestpm.set_data then pm.sample_posterior_predictive; extract HDI intervalsFull step-by-step code: references/workflow_examples.md.
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.
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.
scripts/model_comparison.py); interpret elpd_diff against dse and check Pareto-k. ArviZ 1.x has no WAIC.target_accept for divergences; ADVI for fast approximation.scripts/model_diagnostics.py (check_diagnostics, create_diagnostic_report).Code and decision rules: references/model_comparison.md. Detailed sampling-algorithm guide: references/sampling_inference.md.
dims) for clarityStart simple and add complexity gradually, iterating on the model based on each predictive check (see the 8-step workflow above).
This skill includes:
references/)workflow_examples.md — missing-data imputation, QR reparameterization, mixture models, and a model-averaging helper.scripts/)check_diagnostics() for quick checks, create_diagnostic_report() for comprehensive analysis with plots.compare_models(), check_loo_reliability(), model_averaging().assets/)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)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.comparefrom scripts.model_diagnostics import check_diagnostics
check_diagnostics(idata)from scripts.model_comparison import compare_models
compare_models({'m1': idata1, 'm2': idata2}) # PSIS-LOO; higher elpd is better# 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.predictionspm.model_to_graphviz(model) to visualize model structure (needs the graphviz package)idata.to_netcdf('results.nc') (requires h5netcdf or netCDF4, e.g. arviz[h5netcdf]); load with az.from_netcdf('results.nc')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.
az.InferenceData. Group access (idata.posterior, idata["posterior"]) still works; idata.extend(other) became idata.update(other); list groups with list(idata.children).pm.compute_log_likelihood(idata) after sampling. pm.sample(idata_kwargs={"log_likelihood": True}) is deprecated.nuts_sampler="pymc" | "nutpie" | "numpyro" | "blackjax". Sample-stat names differ (tree_depth vs depth), so diagnostics code should check which exists. Starting values go in initvals= (start= fails).az.summary reports 89% equal-tailed intervals (eti89_lb, eti89_ub) instead of 94% HDI (hdi_3%, hdi_97%). Use az.summary(idata, ci_kind="hdi", ci_prob=0.94) or set az.rcParams["stats.ci_kind"] / ["stats.ci_prob"]. az.hdi(..., prob=0.95) replaces hdi_prob=.PlotCollection (save with pc.savefig("file.png"), show with pc.show()); ax= / axes= arguments are gone. Renames: plot_posterior → plot_dist, plot_ppc → plot_ppc_dist (prior checks: group="prior_predictive", num_samples= instead of num_pp_samples=), plot_trace → plot_trace_dist (trace plus density), plot_dist_comparison → plot_prior_posterior. Install a backend with arviz[matplotlib].az.waic is gone and az.compare(dict) takes no ic=/scale=; it ranks by PSIS-LOO elpd (higher is better) with stacking weights and reports elpd_diff, dse, p_worse, and diag_* columns.pm.Data('X', X, dims=...) at build time — only then can pm.set_data({'X': X_new}, coords={...}) swap them. A plain NumPy array baked into the graph cannot be replaced.pm.sample_prior_predictive takes draws= (the old samples= keyword was removed).pm.sample_posterior_predictive(idata, predictions=True, extend_inferencedata=True, ...); results then live in idata.predictions, not idata.posterior_predictive.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.