LogNormalPrior#
- class pymc_marketing.special_priors.LogNormalPrior(dims=None, centered=True, **parameters)[source]#
Lognormal prior parameterized by positive-scale mean and std.
This prior differs from the standard
LogNormaldistribution, which takes log-scale parameters (mu_log,sigma_log). Instead, it is parameterized directly in terms of the mean and standard deviation (mean,std) on the positive scale, making it more intuitive and suitable for hierarchical modeling.To achieve this, the lognormal parameters are computed internally from the positive-domain parameters:
\[\begin{split}\mu_{\text{log}} &= \ln \left( \frac{\text{mean}^2}{\sqrt{\text{mean}^2 + \text{std}^2}} \right) \\ \sigma_{\text{log}} &= \sqrt{ \ln \left( 1 + \frac{\text{std}^2}{\text{mean}^2} \right) }\end{split}\]where \(\text{mean} > 0\) and \(\text{std} > 0\).
The prior is then defined as:
\[\phi \sim \text{LogNormal}(\mu_{\text{log}}, \sigma_{\text{log}})\]This construction ensures that the resulting random variable has approximately the intended mean and variance on the positive scale, even when \(\text{mean}\) and \(\text{std}\) are themselves random variables.
- Parameters:
- mean
Prior,float,int, array_like, optional The mean of the distribution on the positive scale. It can be omitted only when the instance is used as a likelihood, in which case the mean is supplied later as
mubycreate_likelihood_variable().- std
Prior,float,int, array_like The standard deviation of the distribution on the positive scale.
- dims
tuple[str, …], optional The dimensions of the distribution, by default None.
- centeredbool, optional
Whether to use the centered parameterization, by default True. Ignored when the instance is used as a likelihood, since an observed variable has no non-centered form.
- mean
References
Wikipedia, Log-normal distribution — Definitions.
Examples
Build a non-centered hierarchical model where information is shared across groups:
from pymc_marketing.special_priors import LogNormalPrior prior = LogNormalPrior( mean=Prior("Gamma", mu=1.0, sigma=1.0), std=Prior("HalfNormal", sigma=1.0), dims=("geo",), centered=False, )
Use it as an MMM likelihood under
link="identity"by configuring onlystd. The linear predictormubecomes the response-scale mean, so unlike a plainLogNormallikelihood the additive decomposition stays in the units of the target. Both the target and the fittedmumust be strictly positive; during sampling a non-positivemuis rejected with-inflog-probability rather than being silently folded to|mu|. This guard protects only log-probability evaluation: forward sampling is rewritten so that a non-positivemuproduces draws of exactlyexp(-inf) = 0, with no error (seecreate_likelihood_variable()); the MMM warns when prior or posterior predictive draws show this signature. The MMM’s default identity-link intercept prior is centered at zero, so roughly a third of prior-predictive draws hit this path out of the box; pair this likelihood with a positive intercept prior (for examplePrior("HalfNormal", sigma=2)or aNormalcentered well above zero) so the prior putsmuon the positive side.This parameterization also changes the noise model. Holding
stdconstant across dates makessigma_logshrink asmugrows, so the likelihood models (approximately) constant additive noise of sizestdin the units of the target. A plainLogNormallikelihood with fixedsigmainstead models constant relative noise, with a standard deviation proportional to the mean. Note the likelihood scale variable is namedy_std, noty_sigmaas with the defaultNormallikelihood.from pymc_extras.prior import Prior from pymc_marketing.special_priors import LogNormalPrior likelihood = LogNormalPrior( std=Prior("HalfNormal", sigma=0.5, dims=("country",)), dims=("date", "country"), ) mmm = MMM(..., model_config={"likelihood": likelihood})
Methods
LogNormalPrior.__init__([dims, centered])Create an observed LogNormal variable whose response-scale mean is
mu.LogNormalPrior.create_variable(name[, xdist])Create a variable from the prior distribution.
LogNormalPrior.from_dict(data)Create a SpecialPrior prior from a dictionary.
LogNormalPrior.sample_prior([coords, name])Sample from the prior distribution.
LogNormalPrior.to_dict([_orig])Convert the SpecialPrior to a dictionary.
Raise if observed data lies outside the LogNormal support.