JointCategorical#
- class pymc_extras.distributions.JointCategorical(name: str, *args, rng=None, dims: str | Sequence[str | None] | None = None, initval=None, observed=None, total_size=None, transform=UNSET, default_transform=UNSET, **kwargs)[source]#
Joint distribution over
n_lagscategorical states.A draw is a vector \((x_0, \dots, x_{n\_lags - 1})\), each entry taking one of
n_statesvalues. Unlike a product of independent categoricals, the entries can be arbitrarily correlated: the distribution is parameterized by the probability of every one of then_states ** n_lagsconfigurations, one array axis per entry.\[\Pr(x_0, \dots, x_{n\_lags - 1}) = p[x_0, \dots, x_{n\_lags - 1}]\]- Parameters:
p (tensor_like of float) – Probability of each state configuration, with shape
(n_states,) * n_lags: one axis per entry of a draw, sop[i, j, ...]is the probability of drawing[i, j, ...]. Any leading axes are batch dimensions. Note the parameter grows exponentially inn_lags, as the joint is stored explicitly.logit_p (tensor_like of float) – Alternative parametrization, as unnormalized log-probabilities of the same shape. Only one of
porlogit_pmay be given.n_lags (int) – Number of states in the joint. This is the support dimensionality: a single draw is a vector of length
n_lags. The number of values each entry can take is taken from the trailing axes ofp/logit_p.
Examples
A joint over two binary states. Of the four possible paths, only the two that stay put,
[0, 0]and[1, 1], carry appreciable mass, so the pair is strongly correlated even though each state is marginally 50/50:import numpy as np import pymc as pm import pymc_extras as pmx # One axis per lag, so p[i, j] is the probability of drawing [i, j]. p = np.array( [ [0.45, 0.05], # [0, 0], [0, 1] [0.05, 0.45], # [1, 0], [1, 1] ] ) dist = pmx.JointCategorical.dist(p=p, n_lags=2) pm.draw(dist, draws=5) # array([[1, 1], # [0, 0], # [0, 0], # [1, 1], # [0, 1]])
Each row is one draw: a vector of
n_lags=2states, the first entry being \(x_0\) and the second \(x_1\). Switching paths like[0, 1]show up in roughly one draw in ten. Setting those entries to exactly0.0instead would make them impossible, leaving a joint supported on two configurations only.Notes
This is the distribution of the smoothed initial states of a marginalized
DiscreteMarkovChainwithn_lags > 1, where the firstn_lagsstates are correlated a posteriori.- __init__()#
Methods
__init__()dist([p, logit_p])Create a tensor variable corresponding to the cls distribution.
rv_op(logit_p, *, n_lags[, size, rng])