bayesian-workflow
Opinionated Bayesian modeling workflow with PyMC and ArviZ.
Skill by [Alexandre Andorra](https://alexandorra.github.io/)
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/brycewang-stanford-bayesian-workflow
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: ml, writing, productivity
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
- Runs as
- Python package
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/bayesian-workflow
What's inside
- Skill name
bayesian-workflow- Description
- Opinionated Bayesian modeling workflow with PyMC and ArviZ. Contains critical guardrails (nutpie sampler, prior/posterior predictive checks, LOO-PIT calibration, prior sensitivity checks, 94% HDI, non-centered parameterizations, reproducible seeds) that agents won't apply unprompted — always consult before writing Bayesian model code. Trigger on: building probabilistic/Bayesian models, prior elicitation, MCMC inference, convergence diagnostics (divergences, R-hat, ESS), model comparison (LOO-CV, ELPD, stacking weights), hierarchical/multilevel models, count regressions, logistic regression with uncertainty, prior sensitivity analysis, reporting Bayesian results, or mentions of PyMC, ArviZ, InferenceData, credible intervals, posterior distributions, shrinkage, uncertainty quantification. Also trigger for model comparison, diagnosing sampling problems, choosing priors, or presenting stats to non-technical audiences.
- License
- MIT
- Metadata
- author: [Alexandre Andorra](https://alexandorra.github.io/) · version: 1.2
- Instructions
- 153 lines in SKILL.md · view on GitHub
Before installing
- Ships executable scripts
Files (13)
- README.md
- SKILL.md
- main.py
- pyproject.toml
- diagnostics.md · references/
- hierarchical.md · references/
- model-comparison.md · references/
- model-criticism.md · references/
- priors.md · references/
- reporting.md · references/
- sensitivity.md · references/
- calibration_check.py · scripts/
- diagnose_model.py · scripts/
SKILL.md (first lines)
# Bayesian Workflow
## Workflow overview
Every Bayesian analysis follows this sequence. Do not skip steps -- especially model criticism.
1. **Formulate** — Define the generative story. What underlying process, that we're precisely trying to model, created the data?
2. **Specify priors** — See [references/priors.md](references/priors.md)
3. **Implement in PyMC** — Write the model. Prefer PyMC 5+ syntax. Use the latest version possible.
4. **Run prior predictive checks** — `pm.sample_prior_predictive()`. Verify priors produce plausible data ranges before fitting
5. **Inference** — `pm.sample(nuts_sampler="nutpie")`. Always use nutpie for speed (the nutpie python package provides cutting-edge sampling). Don't hardcode the number of chains — let the sampler pick the best default for the platform.
6. **Diagnose convergence** — Use `arviz_stats.diagnose(idata)` as the first check (requires arviz-stats >= 1.0.0). It covers R-hat, ESS, divergences, tree depth, and E-BFMI in one call. See [references/diagnostics.md](references/diagnostics.md)
7. **Criticize the model** — See [references/model-criticism.md](references/model-criticism.md)
8. **Check prior sensitivity** — Run `psense_summary(idata)` to verify conclusions are robust to prior choices. Visualize with `plot_psense_dist(idata)` from `arviz_plots`. Requires `log_likelihood` and `log_prior` in the InferenceData — compute them after sampling if needed. See [references/sensitivity.md](references/sensitivity.md)
9. **Compare models** (if applicable) — See [references/model-comparison.md](references/model-comparison.md)
10. **Report results** — See [references/reporting.md](references/reporting.md). When the user asks for a report or mentions a non-technical audience, generate a **standalone markdown report file** (not just code comments) using the template in reporting.md. Adapt the language to the audience — if they're new to Bayesian stats, include a glossary and plain-language explanations of key concepts.
## Installation
Prefer conda-forge / mamba-forge to install PyMC and its dependencies — pip can cause issues with
compiled backends (nutpie, JAX). Example:
```bash
mamba install -c conda-forge pymc nutpie arviz arviz-stats preliz
```
## PyMC model template
```python
import pymc as pm
import arviz as az
import numpy as np
RANDOM_SEED = sum(map(ord, "churn-logistic-v1"))
rng = np.random.default_rng(RANDOM_SEED)
# always use dimensions and coordinates in PyMC models
with pm.Model(coords=coords) as model:
# use Data containers when working on a PyMC model
data = pm.Data("data", df["y"].to_numpy(), dims="obs")
# --- Priors ---
# Always document WHY each prior was chosen
mu = pm.Normal("mu", mu=0, sigma=10) # Weakly informative: allows wide range
# --- Data model ---
pm.Normal("obs", mu=mu, sigma=1, observed=data, dims="obs")
# --- Prior predictive check ---
prior_pred = pm.sample_prior_predictive(random_seed=rng)
# --- Inference ---
idata = pm.sample(nuts_sampler="nutpie", random_seed=rng)
idata.extend(prior_pred)
# --- Posterior predictive check ---
idata.extend(pm.sample_posterior_predictive(idata, random_seed=rng))
# --- Compute log-likelihood and log-prior for sensitivity checks & LOO ---
pm.compute_log_likelihood(idata, model=model)
pm.compute_log_prior(idata, model=model)
# --- Save immediately after sampling ---
# Late crashes can destroy valid results. Save to disk before any post-processing.
idata.to_netcdf("model_output.nc")
```
## Critical rules
- **Always run prior predictive checks** before sampling. If prior predictions span implausible ranges, fix priors first. If you have issues or doubts for some parameters, use the [PreliZ](https://preliz.readthedocs.io/en/latest/) package to elicit priors from the user.
- **Always check convergence** before interpreting results. R-hat > 1.01 or ESS < 100 * nbr_chains means the results are unreliable.
- **Always run posterior predictive checks**. A model that fits well numerically but cannot reproduce the data is useless.
- **Always run calibration checks** (PIT / coverage). Use ArviZ's `plot_ppc_pit` for this — it handles all data types (continuous, binary, count) correctly. See [references/model-criticism.md](references/model-criticism.md).
- **Document every prior choice** with a brief justification in a code comment.
- **Never report point estimates alone**. Always include credible intervals (default: 94% HDI).
- **Use `arviz_stats.diagnose(idata)` as the first diagnostic on every model** (arviz-stats >= 1.0.0). It checks R-hat, ESS, divergences, tree depth saturation, and E-BFMI in one call. Follow up with `az.plot_trace(idata, kind="rank_vlines")` for visual inspection.
- **Don't hardcode number of chains.** Let PyMC / nutpie choose the optimal default for the user's platform. Just call `pm.sample()` without specifying `chains`.
- **Use reproducible, descriptive seeds.** Never use magic numbers like `42`. Instead, derive a seed from the analysis name: `RANDOM_SEED = sum(map(ord, "my-analysis-name"))`. Pass it to `pm.sample(random_seed=rng)`, `pm.sample_prior_predictive(random_seed=rng)`, and numpy via `rng = np.random.default_rng(RANDOM_SEED)`.
- **Save InferenceData immediately after sampling** with `idata.to_netcdf("model_output.nc")`. Late crashes or kernel restarts can destroy valid MCMC results — save before any post-processing.
- **Use ArviZ for all plots and calibration.** Don't write custom plotting code when ArviZ already handles it — including for binary data, count data, and calibration. ArviZ developers have thought through edge cases so you don't have to.
- **Prefer xarray over numpy for InferenceData operations.** `InferenceData` and `DataTree` objects are backed by xarray — use xarray's labeled indexing (`.sel()`, `.mean(dim=...)`, etc.) instead of converting to numpy arrays. This preserves dimension labels, avoids shape bugs, and makes code more readable. Fall back to numpy only when xarray can't do what you need.
- **Always generate analysis notes alongside code.** When producing a model script, also produce a companion markdown file (`analysis_notes.md` or similar) that interprets the results — what the diagnostics mean, what the posteriors tell us, what the calibration plots show. Code without interpretation is incomplete.
- **Always use the posterior mean (not median) for predictive probabilities.** The proper Bayesian predictive distribution averages over the posterior: `P(Y=k|x) = (1/S) Σ P(Y=k|x,θₛ)`. This is the mean, not the median. The median does not correspond to the posterior predictive distribution, can violate probability coherence (probabilities may not sum to 1), and biases calibration due to Jensen's inequality. In code: use `np.mean(probs, axis=sample_axis)`, never `np.median(...)`.
- **Use `pm.set_data()` + `pm.sample_posterior_predictive()` for out-of-sample predictions.** Don't manually extract posterior samples and recompute predictions — let PyMC propagate uncertainty properly. Define predictors as `pm.Data(...)` during model building, then swap in new data:
```python
# After fitting the model:
with model:
pm.set_data({"X": X_new, "group_idx": group_idx_new})
oos_preds = pm.sample_posterior_predictive(idata, predictions=True, random_seed=rng)
```
- **Check model identifiability before interpreting components.** If two model components always appear together in the likelihood (e.g., a league intercept and a home advantage term when every observation is from home perspective), their individual posteriors reflect prior assumptions, not data signal — only their sum is identified. Use `az.plot_pair()` to check for strong posterior correlations between components. If correlation is near ±1, the components are not separately identifiable — either merge them or restructure the data.
## Common model families
| Problem | Data model | Typical priors | Reference |
|---|---|---|---|
| Continuous outcome | Normal / StudentT | Normal, Gamma avoiding 0 for positive-constrained parameters | [references/priors.md](references/priors.md) |
| Binary outcome | Bernoulli or Binomial if aggregated, with logit inverse-link | Normal(0, 1.5) on coeffs | [references/priors.md](references/priors.md) |
| Count data | Poisson / NegBinomial | Gamma on rate, avoiding 0 | [references/priors.md](references/priors.md) |
| Count data with excess zeros | ZeroInflatedPoisson / ZeroInflatedNegBinomial | Gamma on rate; Beta or Normal+logit on zero-inflation prob | [references/priors.md](references/priors.md) |
| Positive count data (no zeros) | Hurdle Poisson / Hurdle NegBinomial | Separate zero-gate (Bernoulli) and count (Truncated) components | [references/priors.md](references/priors.md) |
| Ordinal outcome | OrderedLogistic (cumulative link) | Normal on coeffs; Normal with ordered transform on cutpoints | [references/priors.md](references/priors.md) |
| Censored data (survival, limits of detection) | `pm.Censored(dist, lower, upper)` | Same as uncensored, applied to underlying distribution | [references/priors.md](references/priors.md) |
| Truncated data | `pm.Truncated(dist, lower, upper)` | Same as underlying distribution | [references/priors.md](references/priors.md) |
| High-dimensional / sparse regression | Normal / StudentT with sparsity prior on coefficients | Regularized Horseshoe or R2-D2 on coeffs | [references/priors.md](references/priors.md) |
| Hierarchical / multilevel | Varies | See partial pooling pattern | [references/hierarchical.md](references/hierarchical.md) |
| Time series | state space models / Gaussian Processes | Problem-specific | [references/priors.md](references/priors.md) |
## Utility scripts
Run `diagnose_model.py` after sampling to get a structured convergence + diagnostics report:
```bash
python scripts/diagnose_model.py --idata path/to/inference_data.nc
```
Run `calibration_check.py` to generate calibration plots:From brycewang-stanford/Auto-Empirical-Research-Skills, MIT.
More from brycewang-stanford/Auto-Empirical-Research-Skills
- 0.746score
causal-inference
[Alexandre Andorra](https://alexandorra.github.io/)
Production-grade Bayesian causal inference with PyMC, CausalPy, and DoWhy.
SkillCFreshness: C★ 4.8KClaude Code +9 - 0.740score
latex-to-quarto
Christopher T. Kenny
Converts LaTeX article-class .tex documents to Quarto .qmd format for multi-format publishing (HTML, PDF, Word).
SkillCFreshness: C★ 4.8KClaude Code +9 - 0.738score
stat-writing
stat-writing-one-skill
End-to-end statistical writing assistant for LaTeX - draft title/abstract/keywords, expand outlines into sections, audit manuscripts, write reviewer reports…
SkillCFreshness: C★ 4.8KClaude Code +9 - 0.736score
medical-imaging-review
user
Write comprehensive literature reviews for medical imaging AI research.
SkillCFreshness: C★ 4.8KClaude Code +9 - 0.735score
pseudo-merge
Christopher T. Kenny
Takes a proofread or apsa-style report file (or any markdown file using **Original:** / **Recommended:** syntax) and rewrites the original source file with…
SkillCFreshness: C★ 4.8KClaude Code +9 - 0.735score
proofread
Christopher T. Kenny
Expert copy editor for Quarto (.qmd) files.
SkillCFreshness: C★ 4.8KClaude Code +9 - 0.735score
assess-outline
Christopher T. Kenny
Assesses a research paper outline (.qmd file) against structured criteria from Kosuke Imai's empirical research guide.
SkillCFreshness: C★ 4.8KClaude Code +9 - 0.735score
markdown-unwrap
Christopher T. Kenny
Unwraps hard-wrapped markdown files so that each sentence ends with a newline instead of mid-sentence line breaks.
SkillCFreshness: C★ 4.8KClaude Code +9 - 0.735score
paper-summary
Christopher T. Kenny
Writes expert academic paper summaries for social science research, particularly political science and applied statistics.
SkillCFreshness: C★ 4.8KClaude Code +9 - 0.735score
apsa-style
Christopher T. Kenny
APSA style checker for Quarto (.qmd) files.
SkillCFreshness: C★ 4.8KClaude Code +9 - 0.735score
quarto-clean
Christopher T. Kenny
Cleans a Quarto (.qmd) file by replacing LaTeX holdovers with proper Quarto/Pandoc syntax so the document renders correctly to HTML, PDF (Typst/LaTeX), and…
SkillCFreshness: C★ 4.8KClaude Code +9 - 0.735score
write-well
Christopher T. Kenny
Prose quality checker for Quarto (.qmd) files, grounded in William Zinsser's *On Writing Well* (30th Anniversary Edition).
SkillCFreshness: C★ 4.8KClaude Code +9
Signals
- Stars
- 4,757
- Forks
- 556
- Open issues
- 1
- Last commit (this folder)
- Jun 4, 2026 (4 months ago)
- Last release
- Jul 2, 2026 (3 months ago)
From GitHub (fetched Oct 24, 2026).
Details
- Version
- 1.2
- License
- MIT
- Website
- copaper.ai
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from [Alexandre Andorra](https://alexandorra.github.io/)
Cite this page
bayesian-workflow skill. Agent Mart. https://agentmart.dev/skills/brycewang-stanford-bayesian-workflow (last updated 2026-10-24)