Reference / binference.samplers.MAP

binference.samplers.MAP

class binference.samplers.MAP(model, *, space='auto', tol=1e-08, max_iter=20000, accelerate=True, algorithm='auto', init=None, rng=None, progress=False)[source]

Maximum a posteriori (or maximum-likelihood) estimate of the population.

For conjugate priors (Dirichlet family, GammaRates) the posterior mode on the simplex is found by EM – “iterated stacking”, \(\rho_k \leftarrow \sum_i w_i r_{ik}(\rho)/W\) plus prior pseudo-counts – accelerated with SQUAREM (Varadhan & Roland 2008). For a Dirichlet prior with all concentrations >= 1 (exactly 1 with a selection function), and for GammaRates with all shapes >= 1, the default uses mix-SQP (Kim et al. 2020) instead, a second-order method that converges in tens of iterations where EM can need thousands (broad likelihoods). With selection it solves for the fractions of the observed population, \(\phi_k \propto S_k\rho_k\), in which the likelihood is concave, and maps the mode back; rates \(\lambda = \Lambda\psi\) reduce to the same problem with \(S_k + b_k\) in place of \(S_k\) once the total \(\Lambda\) is profiled out. The default Dirichlet(1) prior gives the maximum-likelihood estimate (the NPMLE on the grid). Other priors, or space="unconstrained", maximise the density in the unconstrained coordinates with L-BFGS.

Parameters:
modelPopulationModel
space{“auto”, “simplex”, “unconstrained”}

Coordinates the mode is found in. "simplex" maximises the density of the fractions (requires a conjugate prior); "unconstrained" the density in unconstrained coordinates (always interior); "auto" picks "simplex" unless the prior density is unbounded at the boundary (concentrations or shapes below one, Polya trees; prior.unbounded_density()), where the simplex mode can have exact zeros, or a selection or response is inferred jointly. The choice is in info["space"] and the solver in info["algorithm"].

tolfloat

Tolerance on first-order optimality. It bounds the KKT gap (kkt_gap()) for EM, and for mix-SQP the same gap of the problem it solves (in the observed fractions under selection, the composition for rates); the largest absolute gradient divided by max(1, W) for L-BFGS, whose estimates keep the largest absolute gradient in info["grad_norm"] and have kkt_gap NaN. A run that can no longer improve the objective in floating point counts as converged when that measure is below 1e3 * tol.

max_iterint

Maximum number of (accelerated) EM iterations or L-BFGS iterations.

acceleratebool

Use SQUAREM acceleration (EM only).

algorithm{“auto”, “mixsqp”, “em”}

Solver on the simplex. "auto" uses mix-SQP where it applies (Dirichlet prior with concentrations >= 1, or exactly 1 with selection; GammaRates with shapes >= 1), EM on the simplex otherwise, and L-BFGS in the unconstrained space. "mixsqp" and "em" solve on the simplex, as space="simplex" does (not for joint models).

initarray_like (K,), optional

Starting fractions (or rates). By default mix-SQP starts after 10 regularised EM steps from uniform, the other algorithms after up to 50.

rng, progress

Accepted for a common signature; unused.

__init__(model, *, space='auto', tol=1e-08, max_iter=20000, accelerate=True, algorithm='auto', init=None, rng=None, progress=False)[source]

Methods

__init__(model, *[, space, tol, max_iter, ...])

run()

Find the mode.

unsupported(model)

Why the engine cannot run on model, or None when it can.

Attributes

approximate

joint

whether the engine infers a selection from injections or a tallied response jointly (DECISIONS #30, #80, #81)

markov

whether its draws are Markov chains, described by R-hat and ESS

name

joint = True

whether the engine infers a selection from injections or a tallied response jointly (DECISIONS #30, #80, #81)

run()[source]

Find the mode.