API Reference#

This reference provides detailed documentation for all modules, classes, and methods in the current release of PyMC experimental.

pymc_experimental.distributions#

pymc_experimental.distributions.histogram_utils.histogram_approximation(name, dist, *, observed, **h_kwargs)[source]#

Approximate a distribution with a histogram potential.

Parameters
  • name (str) – Name for the Potential

  • dist (aesara.tensor.var.TensorVariable) – The output of pm.Distribution.dist()

  • observed (ArrayLike) – Observed value to construct a histogram. Histogram is computed over 0th axis. Dask is supported.

Returns

Potential

Return type

aesara.tensor.var.TensorVariable

Examples

Discrete variables are reduced to unique repetitions (up to min_count)

>>> import pymc as pm
>>> import pymc_experimental as pmx
>>> production = np.random.poisson([1, 2, 5], size=(1000, 3))
>>> with pm.Model(coords=dict(plant=range(3))):
...     lam = pm.Exponential("lam", 1.0, dims="plant")
...     pot = pmx.distributions.histogram_approximation(
...         "pot", pm.Poisson.dist(lam), observed=production, min_count=2
...     )

Continuous variables are discretized into n_quantiles

>>> measurements = np.random.normal([1, 2, 3], [0.1, 0.4, 0.2], size=(10000, 3))
>>> with pm.Model(coords=dict(tests=range(3))):
...     m = pm.Normal("m", dims="tests")
...     s = pm.LogNormal("s", dims="tests")
...     pot = pmx.distributions.histogram_approximation(
...         "pot", pm.Normal.dist(m, s),
...         observed=measurements, n_quantiles=50
...     )

For special cases like Zero Inflation in Continuous variables there is a flag. The flag adds a separate bin for zeros

>>> measurements = abs(measurements)
>>> measurements[100:] = 0
>>> with pm.Model(coords=dict(tests=range(3))):
...     m = pm.Normal("m", dims="tests")
...     s = pm.LogNormal("s", dims="tests")
...     pot = pmx.distributions.histogram_approximation(
...         "pot", pm.Normal.dist(m, s),
...         observed=measurements, n_quantiles=50, zero_inflation=True
...     )

pymc_experimental.utils#

pymc_experimental.utils.spline.bspline_interpolation(x, *, n=None, eval_points=None, degree=3, sparse=True)[source]#

Interpolate sparse grid to dense grid using bsplines.

Parameters
  • x (Variable) – Input Variable to interpolate. 0th coordinate assumed to be mapped regularly on [0, 1] interval

  • n (int (optional)) – Resolution of interpolation

  • eval_points (vector (optional)) – Custom eval points in [0, 1] interval (or scaled properly using min/max scaling)

  • degree (int, optional) – BSpline degree, by default 3

  • sparse (bool, optional) – Use sparse operation, by default True

Returns

The interpolated variable, interpolation is across 0th axis

Return type

Variable

Examples

>>> import pymc as pm
>>> import numpy as np
>>> half_months = np.linspace(0, 365, 12*2)
>>> with pm.Model(coords=dict(knots_time=half_months, time=np.arange(365))) as model:
...     kernel = pm.gp.cov.ExpQuad(1, ls=365/12)
...     # ready to define gp (a latent process over parameters)
...     gp = pm.gp.gp.Latent(
...         cov_func=kernel
...     )
...     y_knots = gp.prior("y_knots", half_months[:, None], dims="knots_time")
...     y = pm.Deterministic(
...         "y",
...         bspline_interpolation(y_knots, n=365, degree=3),
...         dims="time"
...     )
...     trace = pm.sample_prior_predictive(1)

Notes

Adopted from BayesAlpha where it was written by @aseyboldt

pymc_experimental.utils.prior.prior_from_idata(idata: InferenceData, name='trace_prior_', *, var_names: Sequence[str], **kwargs: Union[ParamCfg, RVTransform, str, Tuple]) Dict[str, TensorVariable][source]#

Create a prior from posterior using MvNormal approximation.

The approximation uses MvNormal distribution. Keep in mind that this function will only work well for unimodal posteriors and will fail when complicated interactions happen.

Moreover, if a retrieved variable is constrained, you should specify a transform for the variable, e.g. pymc.distributions.transforms.log for standard deviation posterior.

Parameters
  • idata (arviz.InferenceData) – Inference data with posterior group

  • var_names (Sequence[str]) – names of variables to take as is from the posterior

  • kwargs (Union[ParamCfg, aeppl.transforms.RVTransform, str, Tuple]) – names of variables with additional configuration, see more in Examples

Examples

>>> import pymc as pm
>>> import pymc.distributions.transforms as transforms
>>> import numpy as np
>>> with pm.Model(coords=dict(test=range(4), options=range(3))) as model1:
...     a = pm.Normal("a")
...     b = pm.Normal("b", dims="test")
...     c = pm.HalfNormal("c")
...     d = pm.Normal("d")
...     e = pm.Normal("e")
...     f = pm.Dirichlet("f", np.ones(3), dims="options")
...     trace = pm.sample(progressbar=False)

You can reuse the posterior in the new model.

>>> with pm.Model(coords=dict(test=range(4), options=range(3))) as model2:
...     priors = prior_from_idata(
...         trace,                  # the old trace (posterior)
...         var_names=["a", "d"],   # take variables as is
...
...         e="new_e",              # assign new name "new_e" for a variable
...                                 # similar to dict(name="new_e")
...
...         b=("test", ),           # set a dim to "test"
...                                 # similar to dict(dims=("test", ))
...
...         c=transforms.log,       # apply log transform to a positive variable
...                                 # similar to dict(transform=transforms.log)
...
...                                 # set a name, assign a dim and apply simplex transform
...         f=dict(name="new_f", dims="options", transform=transforms.simplex)
...     )
...     trace1 = pm.sample_prior_predictive(100)