mixle.ppl.vmp module¶
Variational Message Passing (VMP) engine for mixle.ppl.
A real message-passing engine for conjugate-exponential (Gaussian-Gamma) models (Winn & Bishop, 2005): each unobserved node carries a variational factor q in an exponential family, holds its natural parameters, and exchanges messages with the factors it touches —
node posterior natural params = prior natural params + sum of incoming factor messages
Coordinate ascent updates each node from the others’ expected sufficient statistics; the ELBO is computed each sweep and increases monotonically.
The graph is built from a model by object identity: the same RandomVariable handle
used in multiple positions becomes ONE node that combines messages from every factor
touching it (parameter tying / shared latents). Priors that are themselves handles become
parent nodes — hierarchies of any depth. Use Graph directly for multi-factor
models, or fit(how="vmp") which auto-builds a single-factor graph.
- class GaussianVNode(prior_mean, prior_prec)[source]
Bases:
objectNode q(x) = Normal(m, s2); prior Normal(prior_mean, 1/prior_prec) where prior_mean may be another node (hierarchy).
inboxholds message thunks from the factors / children touching this node — the mechanism behind sharing.- is_gaussian = True
- ex()[source]
- ex2()[source]
- update()[source]
- entropy()[source]
- cross_prior()[source]
- class GammaVNode(a0, b0)[source]
Bases:
objectNode q(t) = Gamma(a, b) over a precision.
- is_gaussian = False
- et()[source]
- elogt()[source]
- update()[source]
- entropy()[source]
- cross_prior()[source]
- class DirichletVNode(alpha0)[source]
Bases:
objectNode q(pi) = Dirichlet(alpha) over a simplex (categorical probabilities).
- is_gaussian = False
- expected()[source]
- expected_log()[source]
- update()[source]
- entropy()[source]
- cross_prior()[source]
- class Graph[source]
Bases:
objectA VMP factor graph for arbitrary conjugate-Gaussian DAGs with shared variables.
mu = Normal(0, 10) # one shared latent handle fit = (Graph()
.observe(Normal(mu, 1.0), data_a) # factor A uses mu .observe(Normal(mu, 2.0), data_b) # factor B uses the SAME mu .fit())
fit.posterior(mu) # evidence from A and B combined
A prior that is itself a RandomVariable becomes a parent node (hierarchy, any depth). A Gamma in a scale slot is read as a prior on the precision (the conjugate choice).
- observe(model, data)[source]
- Return type:
Graph
- vmp_fit(rv, data, *, max_its=300, tol=1e-8, rng=None)[source]
Auto-build a single-factor VMP graph for a nested Gaussian model and fit it.
Handles
Normal(mean, scale)wheremeanis a (possibly deeply nested) Normal prior chain andscaleis a constant sd or a Gamma prior on the precision — e.g.Normal(Normal(0,10), Gamma(1,1))(unknown mean + precision) orNormal(Normal(Normal(0,100), 5), 1)(mean with a hyperprior). For multi-factor models or shared variables across datasets, useGraphdirectly.
- class MixtureVMPResult(weights, comps, responsibilities, elbo_trace, normalizer_trace)[source]
Bases:
object- summary()[source]
- mixture_vmp(data, K, *, max_its=300, tol=1e-7, rng=None, m0=None, s0=None, a0=1.0, b0=1.0, alpha0=1.0)[source]
Bayesian Gaussian mixture by variational message passing (VBEM).