mixle.inference.decision module¶
Bayes-optimal decisions under a fitted mixle posterior.
Given a Posterior (the Monte-Carlo law over an unknown – a
parameter, a latent state, or a future outcome), a loss function loss(action, draw) -> float, and a
finite set of candidate actions, bayes_action() returns the action that minimises the posterior
expected loss and a tail-risk profile (CVaR + loss quantiles) of the chosen action.
This is the decision half of the platform’s differentiator: a point predictor returns a number; a mixle model returns the action that is optimal under the user’s own loss and explicit about its tail risk.
It depends only on the public Posterior.samples(n, rng) contract
(mixle.inference.posterior), so it carries no serving / HTTP opinion – a lack of capability is
reported via mixle.capability.CapabilityError.
- bayes_action(posterior, loss, actions, *, n=2000, seed=0, cvar_alpha=0.1, quantiles=(0.05, 0.5, 0.95), vectorized=None, report='selection')[source]
Pick the Bayes action:
argmin_a E_{draw ~ posterior}[ loss(a, draw) ].The winner’s reported numbers carry selection bias unless you pay to remove it. The chosen action minimises K NOISY Monte-Carlo estimates, so its own
expected_lossis optimistic post-argmin (the winner’s curse): measured bias about -2.5 Monte-Carlo standard errors at K = 100 candidates – and it does NOT shrink withn, because more draws shrink the SE and the bias together.expected_loss_mc_seis returned so the optimism has a scale; with many near-tied candidates, read the winner’s advertised loss as roughly that many SEs too good.report="fresh-draws"removes the bias instead: the choice is made exactly as before, thennNEW posterior draws are taken and the winner’s reportedexpected_loss/risk_profileare recomputed on them (selection-independent, hence conditionally unbiased for the chosen action). That costs one moresamples(n, rng)call andnmore loss evaluations (one vectorized call) FOR THE WINNER ONLY – deliberately not the default, because a loss may be metered or side-effecting and the exact-invocation-count contract below is itself a stated guarantee;selection_expected_lossthen preserves the in-sample value the action won with.alternativesalways carries selection-stage estimates.- Parameters:
posterior (Any) – any object exposing
samples(n, rng)– e.g.mixle.inference.posterior(model, data, over=...)(parameter, latent, or predictive).loss (Callable[[Any, Any], float]) –
loss(action, draw) -> float(or a numpy-vectorizedloss(action, draws) -> array).actions (Sequence[Any]) – the finite candidate-action set to minimise over.
n (int) – number of posterior draws for the Monte-Carlo expectation.
seed (int) – RNG seed for the posterior draw (reproducible).
cvar_alpha (float) – tail mass for the CVaR / VaR of the chosen action (0.1 -> worst 10%).
quantiles (Sequence[float]) – loss quantiles to report per action. Reported quantiles (and the CVaR/VaR fields) are plug-in Monte Carlo estimates and carry NO uncertainty quantification of their own – tail quantities converge far more slowly than the mean whose
expected_loss_mc_seis reported, so raisenbefore leaning on a far tail (STAT-RR19-17).vectorized (bool | None) – the loss’s calling convention.
True-> called once per action with the whole draw array;False-> called once per draw;None(default) -> readloss.vectorizedif the loss declares it, else auto-detect by probing the array call once. A probe is a real invocation of the loss, so a loss that keeps state, records calls, or has side effects should declare its convention (argument or attribute) to be evaluated exactly the required number of times.report (str) –
"selection"(default) reports the winner’s selection-stage estimates plus their Monte-Carlo SE;"fresh-draws"re-estimates the winner onnnew draws (see above).
- Returns:
{action, action_index, expected_loss, expected_loss_mc_se, risk_profile, alternatives, report, vectorized}– plusselection_expected_losswhenreport="fresh-draws".- Raises:
ValueError – if
actionsis empty,nis not positive,cvar_alphais outside(0, 1], a quantile level is outside[0, 1], the posterior returns an empty, ragged, or wrong-sized sample batch (samples(n, rng)must return exactlyndraws), or a loss evaluates to NaN.TypeError – if
nis not an exact integer, orcvar_alpha/a quantile level is a Boolean, a string, or anything else that is not already a real number.CapabilityError – if
posteriordoes not expose thesamples(n, rng)contract.
- Return type: