Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
e6418b2
feat(compute_rank_statistics): introduce param_transform and re-evalu…
Cab14bacc May 6, 2026
a51f926
feat(posterior sbc): Implement Posterior SBC
Cab14bacc May 7, 2026
34afaa0
chore(tests): Add posterior sbc tests and rename prior sbc tests
Cab14bacc May 7, 2026
336df6b
chore(docs): add posterior sbc example
Cab14bacc May 7, 2026
5c07b97
chore (docs): update phrasing
Cab14bacc May 11, 2026
98fcc38
fix: manual rebase artifacts
Cab14bacc May 26, 2026
a90a49b
fix: manual rebase artifacts
Cab14bacc May 26, 2026
3189ee0
fix(docstring): docstring of sbc class
Cab14bacc May 26, 2026
6231894
refactor: use print_exc instead of print for exception
Cab14bacc May 26, 2026
ff38ddc
chore(readme): add posterior quick start
Cab14bacc May 26, 2026
e8db62e
chore: fix linting errors
Cab14bacc May 26, 2026
52492ed
build: pin pymc version to < 6 to prevent syntax mismatch
Cab14bacc May 27, 2026
5ec4df7
fix: use lowered method argument
Cab14bacc May 27, 2026
fa3f050
refactor: simulator error logic
Cab14bacc May 27, 2026
7fdb9dd
chore: add tests for coverage
Cab14bacc May 27, 2026
55e5798
Update docs/examples/gallery/posterior_sbc.md
aloctavodia May 29, 2026
4cfd0a7
groups is a tutple
aloctavodia May 29, 2026
83dd0f0
Update simuk/sbc.py
aloctavodia May 29, 2026
6545024
refactor: use default_rng instead of np.random
Cab14bacc May 29, 2026
4dc942f
docs: change example to ipynb, change post sbc example to match prior…
Cab14bacc May 29, 2026
fc75ea6
fix: pin pymc>=6.0.0 to accomodate for new syntax
Cab14bacc May 29, 2026
b0e280b
fix: artifacts from renaming param_transform to transform
Cab14bacc May 29, 2026
6e715df
Upgrade bambi and arviz_base dependencies
aloctavodia Jun 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 77 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
# Simuk

Simuk is a Python library for simulation-based calibration (SBC) and the generation of synthetic data.
Simulation-Based Calibration is a method for validating Bayesian inference by checking whether the posterior distributions align with the expected theoretical results derived from the prior.

Simuk works with [PyMC](http://docs.pymc.io), [Bambi](https://bambinos.github.io/bambi/) and [NumPyro](https://num.pyro.ai/en/latest/index.html) models.
Prior Simulation-Based Calibration (Prior SBC) is a method for validating Bayesian inference by checking whether the posterior distributions align with the expected theoretical results derived from the prior.

Posterior Simulation-Based Calibration (Posterior SBC) is a method for validating Bayesian inference by checking whether the posterior distributions conditioned on the augmented data (original + posterior predictive) align with the expected theoretical results derived from the posterior.

For Prior SBC, Simuk works with [PyMC](http://docs.pymc.io), [Bambi](https://bambinos.github.io/bambi/) and [NumPyro](https://num.pyro.ai/en/latest/index.html) models.
For Posterior SBC, Simuk only works with [PyMC](http://docs.pymc.io) models for now.

## Installation

Expand All @@ -15,6 +19,8 @@ pip install simuk

## Quickstart

### Prior SBC

1. Define a PyMC or Bambi model. For example, the centered eight schools model:

```python
Expand All @@ -35,7 +41,7 @@ pip install simuk
```python
sbc = SBC(centered_eight,
num_simulations=100, # ideally this should be higher, like 1000
sample_kwargs={'draws': 25, 'tune': 50})
sample_kwargs={'draws': 100, 'tune': 100})

sbc.run_simulations()
```
Expand All @@ -52,7 +58,74 @@ should be close to uniform and within the oval envelope.
);
```

![Simulation based calibration plots, ecdf](ecdf.png)
![Prior Simulation based calibration plots, ecdf](docs/examples/img/prior_sbc.png)

We see that due to the funnel neck in the eight schools model, the inference algorithm is not well-calibrated, as indicated by the red points.

### Posterior SBC

Posterior SBC evaluates validity locally, conditional on observed data. It is
currently implemented for PyMC. This requires storing observed data in
`pm.Data` containers, using `dims` instead of static shapes, and resizing
covariates and coords in an `update_data` callback to match the augmented data.

1. Define the model with `pm.Data` and `dims`:

```python
import numpy as np
import pymc as pm

data = np.array([28.0, 8.0, -3.0, 7.0, -1.0, 1.0, 18.0, 12.0])
sigma = np.array([15.0, 10.0, 16.0, 11.0, 9.0, 11.0, 10.0, 18.0])

with pm.Model(coords={"school": np.arange(8)}) as centered_eight:
school_idx = pm.Data("school_idx", np.arange(8))
y_data = pm.Data("y_data", data)
sigma_data = pm.Data("sigma_data", sigma)

mu = pm.Normal("mu", mu=0, sigma=5)
tau = pm.HalfCauchy("tau", beta=5)
theta = pm.Normal("theta", mu=mu, sigma=tau, dims="school")
y_obs = pm.Normal("y", mu=theta[school_idx], sigma=sigma_data, observed=y_data)
```

2. Sample once to obtain the original trace:

```python
with centered_eight:
idata = pm.sample(progressbar=False)
```

3. Define `update_data` to resize covariates and run Posterior SBC:

```python
import simuk
from arviz_plots import plot_ecdf_pit

def update_data(model, augmented_data, simulation_idx):
with model:
pm.set_data({
"sigma_data": np.concatenate([sigma, sigma]),
"school_idx": np.concatenate([np.arange(8), np.arange(8)])
})

post_sbc = simuk.SBC(
centered_eight,
method="posterior",
trace=idata,
update_data=update_data,
num_simulations=50,
sample_kwargs={"draws": 100, "tune": 100},
progress_bar=False
)
post_sbc.run_simulations()

plot_ecdf_pit(post_sbc.simulations, group="posterior_sbc", visuals={"xlabel": False})
```

![Posterior Simulation based calibration plots, ecdf](docs/examples/img/posterior_sbc.png)

We see that the funnel neck in the eight schools model is avoided and the inference algorithm is well-calibrated locally for the observed data, as indicated by the absence of red points.

## References

Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
numpydoc_show_inherited_class_members = False
numpydoc_class_members_toctree = False

source_suffix = ".rst"
source_suffix = {".rst": "restructuredtext", ".ipynb": "myst-nb"}

master_doc = "index"
language = "en"
Expand Down
26 changes: 22 additions & 4 deletions docs/examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,31 @@ The gallery below presents examples that demonstrate the use of Simuk.
:gutter: 2 2 3 3

.. grid-item-card::
:link: ./examples/gallery/sbc.html
:link: ./examples/gallery/prior_sbc.html
:text-align: center
:shadow: none
:class-card: example-gallery

.. image:: examples/img/sbc.png
:alt: SBC
.. image:: examples/img/prior_sbc.png
:alt: Prior SBC

+++
SBC
Prior SBC

.. grid-item-card::
:link: ./examples/gallery/posterior_sbc.html
:text-align: center
:shadow: none
:class-card: example-gallery

.. image:: examples/img/posterior_sbc.png
:alt: Posterior SBC
+++
Posterior SBC

.. toctree::
:hidden:
:maxdepth: 1

examples/gallery/prior_sbc
examples/gallery/posterior_sbc
409 changes: 409 additions & 0 deletions docs/examples/gallery/posterior_sbc.ipynb

Large diffs are not rendered by default.

416 changes: 416 additions & 0 deletions docs/examples/gallery/prior_sbc.ipynb

Large diffs are not rendered by default.

240 changes: 0 additions & 240 deletions docs/examples/gallery/sbc.md

This file was deleted.

Binary file added docs/examples/img/posterior_sbc.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/examples/img/prior_sbc.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed docs/examples/img/sbc.png
Binary file not shown.
Loading
Loading