Source code for probflow.parameters.categorical_parameter

from typing import List, Union

import probflow.utils.ops as O
from probflow.distributions import Categorical
from probflow.utils.initializers import xavier

from .parameter import Parameter


[docs]class CategoricalParameter(Parameter): r"""Categorical parameter. This is a convenience class for creating a categorical parameter :math:`\beta` with a Categorical posterior: .. math:: \beta \sim \text{Categorical}(\mathbf{\theta}) By default, a uniform prior is used. TODO: explain that a sample is an int in [0, k-1] Parameters ---------- k : int > 2 Number of categories. shape : int or List[int] Shape of the array containing the parameters. Default = ``1`` posterior : |Distribution| class Probability distribution class to use to approximate the posterior. Default = :class:`.Categorical` prior : |Distribution| object Prior probability distribution function which has been instantiated with parameters. Default = :class:`.Categorical` ``(1/k)`` transform : callable Transform to apply to the random variable. Default is to use no transform. initializer : Dict[str, callable] Initializer functions to use for each variable of the variational posterior distribution. Keys correspond to variable names (arguments to the distribution), and values contain functions to initialize those variables given ``shape`` as the single argument. var_transform : Dict[str, callable] Transform to apply to each variable of the variational posterior. name : str Name of the parameter(s). Default = ``'CategoricalParameter'`` Examples -------- TODO: creating variable """ def __init__( self, k: int = 2, shape: Union[int, List[int]] = [], posterior=Categorical, prior=None, transform=None, initializer={"probs": xavier}, var_transform={"probs": O.additive_logistic_transform}, name="CategoricalParameter", ): # Check type of k if not isinstance(k, int): raise TypeError("k must be an integer") if k < 2: raise ValueError("k must be >1") # Make shape a list if isinstance(shape, int): shape = [shape] # Use a uniform prior if prior is None: prior = Categorical(O.ones(shape) / float(k)) # Create shape of underlying variable array shape = shape + [k - 1] # Initialize the parameter super().__init__( shape=shape, posterior=posterior, prior=prior, transform=transform, initializer=initializer, var_transform=var_transform, name=name, ) # shape should correspond to the sample shape self.shape = shape