mixle.inference.blackbox module

Black-box Bayesian inference for any model: a Laplace posterior over the parameters.

The conjugate path needs a registered closed form; the autograd VI/NUTS path needs a per-family from-parameters scorer (so it covers flat models + mixtures of leaves). Neither works for an arbitrary composable model. This module does: it treats a fitted model’s parameters as the latent, flattens them to an UNCONSTRAINED vector (positive params via log, unit via logit, simplex via softmax), and fits a Gaussian posterior in that space from a finite-difference Hessian of the model’s own seq_log_density – which every model has. No conjugacy, no autograd, no per-model inference code.

post = laplace_posterior(fitted_model, data) post.sample(…) # parameter draws (a fitted model per draw) post.cov # unconstrained-space posterior covariance

Coverage is the parameter round-trip in _flatten() – the scalar exponential-family leaves, the Categorical simplex, plus Composite, Mixture and HeterogeneousBayesianNetwork (recursively), so heterogeneous records, mixtures-of-anything, and learned Bayesian networks (categorical CPTs + conditional-linear-Gaussian coefficients) are covered out of the box. It is extensible exactly like register_family: add a leaf’s (extract, rebuild) and every composite over it works. A model whose structure is not yet flattenable raises a clear error rather than returning a wrong answer.

class LaplacePosterior(mode_model, u_mode, cov, rebuild)[source]

Bases: object

Gaussian Laplace posterior over a model’s parameters (in the unconstrained space), with draws rebuilt back into fitted models. mean_model is the mode; cov the unconstrained covariance.

sample(n=1, rng=None)[source]
Parameters:

n (int)

summary()[source]
Return type:

dict

laplace_posterior(model, data, *, eps=1e-4, ridge=1e-6)[source]

Laplace posterior over model’s parameters from a finite-difference Hessian of its own seq_log_density – works for ANY model whose parameters _flatten() covers (the scalar exponential-family leaves, Composite and Mixture, recursively), conjugate or not, with no per-model inference code. model should be the fitted (MLE/MAP) model – its parameters are the Laplace mode. Returns a LaplacePosterior you can .sample() (a fitted model per draw).

Parameters:
Return type:

LaplacePosterior