Documentation

Get Started

Install pyINLA, understand how models are specified, and fit your first Bayesian model.

What is pyINLA?

pyINLA is a Python interface to INLA (Integrated Nested Laplace Approximations), a high-performance engine written in C/C++ for fast, approximate Bayesian inference.

INLA is designed for Latent Gaussian Models (LGMs), a flexible class that includes generalized linear models, mixed effects models, spatial models, and time series. In these models:

Instead of sampling (like MCMC), INLA uses Laplace approximations to analytically compute posterior marginals, making it orders of magnitude faster for this model class. pyINLA joins R-INLA as the two official wrappers for the INLA engine.

Learn how INLA works →

Installation

pip install pyinla

We recommend using a virtual environment (uv, conda, or venv) to keep dependencies isolated.

Model Specification

In pyINLA, you write the statistical model as a Python dictionary. Here is how the math maps to code.

The Mathematical Model

Consider a mixed-effects regression with Gaussian observations:

$$y_i \mid \eta_i \sim \text{Gaussian}(\eta_i,\; \sigma^2_e)$$ $$\eta_i = \underbrace{\beta_0}_{\text{intercept}} + \underbrace{\beta_1 x_{1i} + \beta_2 x_{2i}}_{\text{fixed effects}} + \underbrace{u_{g(i)}}_{\text{random effect}}$$ $$u_j \overset{\text{iid}}{\sim} \mathcal{N}(0,\; \sigma^2_u)$$

From Math to Code

Each part of the equation maps directly to a key in the model dictionary:

Math Meaning pyINLA code
$y_i$ Response variable 'response': 'y'
$\text{Gaussian}$ Likelihood family family='gaussian'
$\beta_0$ Intercept '1' in fixed
$\beta_1 x_{1i},\; \beta_2 x_{2i}$ Covariates 'x1', 'x2' in fixed
$u_{g(i)} \sim \mathcal{N}(0, \sigma^2_u)$ Random intercept per group {'id': 'group', 'model': 'iid'}

Runnable Example

Copy-paste this into Python, no data files needed:

import pandas as pd
from pyinla import pyinla

# 10 observations, 3 groups
df = pd.DataFrame({
    'y':     [2.1, 3.5, 2.8, 5.2, 4.9, 6.1, 1.9, 3.3, 5.7, 4.4],
    'x1':    [0.3, 0.7, 0.5, 1.2, 1.0, 1.5, 0.2, 0.6, 1.4, 1.1],
    'x2':    [1.0, 1.2, 0.8, 2.1, 1.9, 2.5, 0.9, 1.1, 2.3, 1.8],
    'group': [  1,   1,   1,   2,   2,   2,   3,   3,   3,   3],
})

# Math:  y_i = beta_0 + beta_1*x1 + beta_2*x2 + u_group(i) + e_i
model = {
    'response': 'y',
    'fixed': [
        '1',                       # beta_0  (intercept)
        'x1',                      # beta_1  (covariate)
        'x2'                       # beta_2  (covariate)
    ],
    'random': [
        {'id': 'group', 'model': 'iid'}  # u_j ~ N(0, sigma_u^2)
    ]
}

result = pyinla(model=model, family='gaussian', data=df)

print(result.summary_fixed)     # Fixed effect estimates
print(result.summary_hyperpar)  # Hyperparameter estimates

Learn More

Explore these topics to master pyINLA:

Next Steps