Library / SDK
bambinos/bambi avatar
bambinos/bambi

Bambi turns a formula into a Bayesian model with priors it picks for you

BAyesian Model-Building Interface (Bambi) in Python.

1,305 stars152 forksPythonMIT

At a glance

What is it?
Bambi is a formula-level interface over PyMC for fitting Bayesian models, including the mixed-effects models common in the social sciences, where the priors are chosen for you and printed back in the model description so you can see what was assumed. It is a layer above a probabilistic programming framework rather than a replacement for one.
Who is it for?
Adopt Bambi if you want to fit Bayesian regression and mixed-effects models without writing a PyMC model by hand, and you are prepared to read the priors it chose before trusting them. Do not adopt it for a model PyMC expresses more directly and that you intend to customise heavily, since Bambi is the convenience layer and you will eventually drop to the layer below.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 4 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 21, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What the interface actually removes

Bambi is a high-level Bayesian model-building interface in Python, built on top of PyMC, and its purpose is to make it easy to fit mixed-effects models common in social sciences settings using a Bayesian approach.

What that removes is the model specification. Writing a regression in PyMC means declaring priors, a likelihood and the sampling call. Bambi takes a formula instead:

python
data = bmb.load_data("sleepstudy")
model = bmb.Model('Reaction ~ Days', data)
print(model)
results = model.fit(draws=1000)

The model-construction line is `bmb.Model('Reaction ~ Days', data)`. `fit()` tells the sampler to start running and returns an `InferenceData` object, which you then pass to `az.summary(results)` for the parameter distribution and sample diagnostics, or `az.plot_trace(results)` to look at the chains.

That last point is the design worth understanding. Bambi does not own the diagnostics or the visualisation; it hands you ArviZ's `InferenceData`, which means the standard tools for checking convergence work unchanged.

The load_data call is a small convenience with a large effect on reproducibility: the package ships the sleepstudy dataset, so the example is the same dataset everyone else in the ecosystem uses.

The priors are printed, which is the point

Print the model and you get the assumptions in plain text:

code
   Formula: Reaction ~ Days
    Family: gaussian
      Link: mu = identity
  Observations: 180
      Priors:
    target = mu
        Common-level effects
            Intercept ~ Normal(mu: 298.5079, sigma: 261.0092)
            Days ~ Normal(mu: 0.0, sigma: 48.8915)

    Auxiliary parameters
            sigma ~ HalfStudentT(nu: 4.0, sigma: 56.1721)

Read that carefully. The intercept prior is centred at the observed mean of the response, 298.5, with a wide standard deviation of 261. The Days coefficient is centred at zero with sigma 48.9, which is again derived from the data rather than fixed at one. And the residual scale uses a half-Student-t with four degrees of freedom, which is a heavy-tailed default rather than a normal one.

The library is choosing sensible, weakly informative, data-informed priors so you do not have to. The reason this matters is not convenience. A Bayesian fit is entirely governed by the priors, and a library that silently picks them would be hiding the one thing you most need to check. Bambi prints them as the first thing you see.

The one place to push back is when your data is on a scale where a data-derived prior is a poor choice, which is a judgement call the printed description exists to support.

The printed summary also states the family and link explicitly, gaussian with identity here, so you can confirm the model is what you meant before spending any sampling time.

Families, links and the event syntax

The second example shows how a non-Gaussian response is specified. You pass `family="bernoulli"` and Bambi uses a logit link by default.

There is also syntax sugar for choosing which event you are modelling:

python
model = bmb.Model("g['Yes'] ~ x1 + x2", data, family="bernoulli")
fitted = model.fit()

Writing `g['Yes']` states that the probability of a Yes response is the modelled quantity. The README is careful to say this notation is not mandatory: with `"g ~ x1 + x2"`, Bambi picks one of the events to model and tells you which one it picked.

That behaviour is the right default for a library aimed at people who may not think in terms of reference levels, and stating which event was chosen removes the ambiguity that otherwise produces a silently inverted coefficient.

Descriptions accept strings or components, and the wider option surface documented on the site covers more families and link functions than the README shows. The README's scope is a demonstration; the documentation is the specification.

The dependency list tells you the compatibility cost

The runtime dependencies in pyproject.toml are what make Bambi a thin layer rather than an independent implementation:

toml
dependencies = [
    "arviz_plots>=1.0.0,<2.0.0",
    "formulae>=0.6.0,<0.7.0",
    "graphviz",
    "matplotlib>=3.9.0",
    "pandas>=1.0.0",
    "pytensor>=3.0.0,<4.0.0",
    "pymc>=6.0.0,<7.0.0",
    "seaborn>=0.13.2,<0.14",
    "sparse>=0.17.0,<0.18",
]

The PyMC constraint is the one that matters for planning. Bambi tracks a major PyMC line, so a PyMC upgrade is a Bambi upgrade, and both must move together.

Note the ArviZ relationship: the README talks about ArviZ functions and `InferenceData`, while the dependency list pins `arviz_plots` for the plotting side. Which one to call for a given plot is a detail worth checking in the documentation rather than assuming.

`formulae` and `sparse` are also listed among Bambi's runtime dependencies.

The optional extras are the interesting part for performance. A `jax` extra pulls in blackjax, jax and numpyro, and a `nutpie` extra pulls in numba and the nutpie sampler. The nutpie extra carries a comment explaining a hard cap: numba is limited to below 0.66 because pytensor requires numba up to 0.65.1 and numba 0.66.0 makes the dependency solve unsatisfiable.

That comment is a useful signal about what adopting an alternative sampler costs you: a pin, and an upstream constraint you do not control.

Installation, versions and who maintains it

Bambi requires Python 3.12 or newer, and the README recommends the Anaconda distribution for the interpreter and the key numerical libraries. Installation is one line:

bash
pip install bambi

For the bleeding edge version there is a direct install from GitHub. The README notes that ArviZ, formulae, NumPy, pandas and PyMC should all be installed by the Bambi installer with no further action required.

The release cadence is steady: 0.19.0 on 2026-07-12, 0.20.0 on 2026-08-10 and 0.21.0 on 2026-09-10, roughly monthly, and the last push was on 2026-10-07. The version is dynamic in pyproject.toml, using setuptools_scm, so the number comes from the repository history rather than being edited by hand.

The project describes itself as a community project and welcomes contributions, with a CONTRIBUTING guide, a CODE_OF_CONDUCT and a contact form for reporting violations, and a GOVERNANCE file at the repository root.

Donations go to the sister project PyMC through NumFOCUS rather than to Bambi itself, which is worth knowing if you are deciding where to direct support for the stack.

There is a CHANGELOG.md, a CITATION.cff and a formal citation in the Journal of Statistical Software from 2022, and the documentation, the logo and the notebooks all live under the bambinos organisation.

The licence is MIT.

Editorial conclusion

Adopt Bambi if you want to fit Bayesian regression and mixed-effects models without writing a PyMC model by hand, and you are prepared to read the priors it chose before trusting them. Do not adopt it for a model PyMC expresses more directly and that you intend to customise heavily, since Bambi is the convenience layer and you will eventually drop to the layer below. Verify first that your Python is 3.12 or newer, that your PyMC is on the 6.x line that Bambi requires, and that the generated priors in `print(model)` match your domain before you sample.

Frequently asked questions

What is Bambi and what does it sit on top of?

Bambi is a high-level Bayesian model-building interface in Python built on top of the PyMC probabilistic programming framework, designed to make mixed-effects models common in social sciences easy to fit from a formula.

How do I install Bambi?

With `pip install bambi` in a Python 3.12 or newer environment, using the Anaconda distribution as the README recommends for the interpreter and numerical libraries. A bleeding edge version can be installed with `pip install git+https://github.com/bambinos/bambi.git`.

How do I fit a model and see the results in Bambi?

Build a model with `bmb.Model('Reaction ~ Days', data)` and call `model.fit(draws=1000)`, which returns an ArviZ InferenceData object. Pass it to `az.summary(results)` for parameter summaries and diagnostics, or `az.plot_trace(results)` to visualise the chains.

How do I model a binary outcome in Bambi?

Pass `family="bernoulli"`, which uses a logit link by default. You can also state which event to model with syntax like `g['Yes'] ~ x1 + x2`, though that notation is optional since Bambi picks an event and tells you which.

Official sources

  1. bambinos/bambi on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/bambinos-bambi.svg)](https://hysenlabs.com/projects/bambinos-bambi)