pymc.find_constrained_prior#

pymc.find_constrained_prior(distribution, lower, upper, init_guess, mass=0.95, fixed_params=None, mass_below_lower=None, **kwargs)[source]#

Find optimal parameters to get mass % of probability of a distribution between lower and upper.

Note: only works for one- and two-parameter distributions, as there are exactly two constraints. Fix some combination of parameters if you want to use it on >=3-parameter distributions.

Parameters:
distributionDistribution

PyMC distribution you want to set a prior on. Needs to have a logcdf method implemented in PyMC.

lowerfloat

Lower bound to get mass % of probability of pm_dist.

upperfloat

Upper bound to get mass % of probability of pm_dist.

init_guessdict of {strfloat}

Initial guess for scipy.optimize.least_squares to find the optimal parameters of pm_dist fitting the interval constraint. Must be a dictionary with the name of the PyMC distribution’s parameter as keys and the initial guess as values.

massfloat, default 0.95

Share of the probability mass we want between lower and upper. Defaults to 95%.

fixed_paramsstr or float, optional, default None

Only used when pm_dist has at least three parameters. Dictionary of fixed parameters, so that there are only 2 to optimize. For instance, for a StudentT, you fix nu to a constant and get the optimized mu and sigma.

mass_below_lowerfloat, optional, default None

The probability mass below the lower bound. If None, defaults to (1 - mass) / 2, which implies that the probability mass below the lower value will be equal to the probability mass above the upper value.

Returns:
opt_paramsdict

The optimized distribution parameters as a dictionary. Dictionary keys are the parameter names and dictionary values are the optimized parameter values.

Notes

Optional keyword arguments can be passed to find_constrained_prior. These will be delivered to the underlying call to scipy.optimize.minimize().

Examples

# get parameters obeying constraints
opt_params = pm.find_constrained_prior(
    pm.Gamma, lower=0.1, upper=0.4, mass=0.75, init_guess={"alpha": 1, "beta": 10}
)

# use these parameters to draw random samples
samples = pm.Gamma.dist(**opt_params, size=100).eval()

# use these parameters in a model
with pm.Model():
    x = pm.Gamma("x", **opt_params)

# specify fixed values before optimization
opt_params = pm.find_constrained_prior(
    pm.StudentT,
    lower=0,
    upper=1,
    init_guess={"mu": 5, "sigma": 2},
    fixed_params={"nu": 7},
)

Under some circumstances, you might not want to have the same cumulative probability below the lower threshold and above the upper threshold. For example, you might want to constrain an Exponential distribution to find the parameter that yields 90% of the mass below the upper bound, and have zero mass below lower. You can do that with the following call to find_constrained_prior

opt_params = pm.find_constrained_prior(
    pm.Exponential,
    lower=0,
    upper=3.0,
    mass=0.9,
    init_guess={"lam": 1},
    mass_below_lower=0,
)