Probabilistic Programming¶
mixle.ppl is an expression layer over the distribution and inference
contracts. It lets model code read like the statistical model while lowering
back to ordinary mixle.stats distributions, estimators, or inference
targets.
The PPL is intentionally thin. The distribution families underneath are the same families used by the explicit estimator API.
Parameter Slots¶
A parameter slot can hold:
a fixed value;
free, meaning estimate this parameter;another distribution, meaning a prior or latent variable;
an expression over fields, groups, named variables, or transforms.
from mixle.ppl import Normal, free
fixed = Normal(0.0, 1.0)
estimated = Normal(free, free)
hierarchical = Normal(Normal(0.0, 10.0), 1.0)
Fitting¶
from mixle.ppl import Field, Markov, Mix, Normal, Poisson, free
clusters = Mix([Normal(free, free), Normal(free, free)]).fit(data)
states = Markov(Normal(free, free), states=2).fit(sequences)
counts = Poisson(free * Field("x") + free).fit(y, given={"x": x})
Mix adds latent component assignments. Markov adds latent state through
time. Field reads covariates supplied through given=.
Route Selection¶
The how= argument selects the inference route. how="auto" inspects the
lowered model and chooses a route family such as conjugate, EM, MAP, Laplace,
VI, VMP, MCMC, HMC, NUTS, ensemble, or hierarchical inference.
model = Mix([Normal(free, free), Normal(free, free)]).fit(data, how="auto")
Use explicit how= values when comparing routes or when an automatic choice
is not the one you want.
Named Variables and Constraints¶
Named variables can be shared across a model and constrained by comparisons.
from mixle.ppl import Mix, Normal, constrain
a = Normal(0.0, 10.0, name="a")
b = Normal(0.0, 10.0, name="b")
ordered = constrain(a < b, Mix([Normal(a, 1.0), Normal(b, 1.0)]))
model = ordered.fit(data)
Use this for parameter tying, label-switching constraints, monotonicity, and other structural assumptions.
Regression and Group Effects¶
Fields and groups make GLM-like expressions concise.
from mixle.ppl import Field, Group, Normal, Poisson, free
y_model = Normal(free * Field("x") + free * Field("z") + free, free)
fitted = y_model.fit(y, given={"x": x, "z": z})
counts = Poisson(free * Field("x") + Group("site")).fit(
count_y,
given={"x": x, "site": site_ids},
)
Random effects can also be expressed with .each() on priors when the data
are grouped.
Neural Predictors¶
The PPL can use neural modules as predictors in distribution parameters.
from mixle.ppl import Categorical, Net, Transformer
classifier = Categorical(logits=Net(hidden=[64], out=3)).fit(
labels,
given={"x": features},
epochs=100,
)
next_token = Categorical(
logits=Transformer(out=vocab, d_model=64, n_layer=2, n_head=4)
).fit(next_ids, given={"x": contexts}, epochs=40)
Use Neural and LLM Models for the estimator-level neural leaf workflow.
Posterior and Predictive Checks¶
Depending on the route, fitted PPL objects can expose posterior summaries, posterior predictive checks, prior predictive checks, WAIC/LOO-style diagnostics, and comparison helpers.
from mixle.ppl import compare, posterior_predictive_check, posterior_summary
summary = posterior_summary(model)
check = posterior_predictive_check(model, data)
ranking = compare([model_a, model_b], data)
Lowering¶
lower converts a PPL expression to a concrete target.
from mixle.ppl import lower
dist = lower(rv, target="dist")
estimator = lower(rv, target="estimator")
Extension work should usually add a lowering rule rather than branch inside a fit loop.
Specialized PPL Surfaces¶
The namespace also includes:
field and spatial models such as
GaussianField,GP,RBF, and related kernels;conformal wrappers such as
ConformalRegressorandConformalClassifier;survival helpers such as
fit_censoredandkaplan_meier;posterior summaries such as
hdiandposterior_summary;guide-based routes such as
structured_viandadmixture.
When to Use PPL¶
Use the PPL when:
the model is clearer as an equation than as an estimator tree;
you need shared or constrained variables;
you want priors directly in parameter slots;
you want a concise latent model such as
MixorMarkov;you want to lower back to the same
mixle.statsmachinery.
Use explicit estimators when:
you are writing production library code;
you need direct control over encoders or estimators;
you are extending a distribution family;
you want the model tree to be explicit in ordinary Python objects.
API Map¶
Area |
Imports |
|---|---|
scalar families |
|
latent structure |
|
parameters and covariates |
|
constraints |
|
neural predictors |
|
diagnostics |
|
lowering |
|