parameterspace.priors.categorical
Categorical (BasePrior)
Categorical prior with separate probabilities for each value.
Source code in parameterspace/priors/categorical.py
class Categorical(BasePrior):
"""Categorical prior with separate probabilities for each value."""
@store_init_arguments
def __init__(self, prior_values: Union[list, np.ndarray]):
"""
Args:
prior_values: Array containing the probabilities for each value.
"""
super().__init__((0, 1))
self.probabilities = np.array(prior_values)
if not np.all(self.probabilities >= 0):
raise ValueError("Probabilities must be non-negative!")
self.probabilities = self.probabilities / np.sum(self.probabilities)
self.numerical_values = (
np.arange(len(self.probabilities), dtype=float) + 0.5
) / len(self.probabilities)
def loglikelihood(self, value):
return np.log(self.pdf(value))
def pdf(self, value):
"""Probability given the numerical representation(s).
The numerical representation is converted to integers and the corresponding
prior_values are returned.
If the value exceeds the given range of values, a ValueError is raised.
Only finite values are converted, and the respective probability is computed.
NaN and INF will result in a NaN. For example:
value = [nan, inf, 0]
will result in
[NaN, NaN, p(0)].
"""
value = np.atleast_1d(value)
idx = np.isfinite(value)
integer_value = np.around(len(self.probabilities) * value[idx] - 0.5).astype(
int
)
pdf = np.full(value.shape, np.nan, dtype=float)
try:
pdf[idx] = self.probabilities[integer_value]
except IndexError as e:
raise ValueError(
"Unknown value in the numerical representation for a "
+ "categorical parameter encountered!"
) from e
return pdf.squeeze()
def sample(self, num_samples=None, random_state=np.random):
return random_state.choice(
self.numerical_values, size=num_samples, replace=True, p=self.probabilities
)
def __repr__(self):
return (
f"Categorical prior for {len(self.probabilities)} values "
+ f"with p = {self.probabilities}"
)
def __eq__(self, other):
return (
super().__eq__(other)
and (len(self.probabilities) == len(other.probabilities))
and np.allclose(self.probabilities, other.probabilities)
)
loglikelihood(self, value)
Compute the log PDF (up to an additive constant) of a given value.
Note
Values for the priors are always after the transformation!
Parameters:
Name | Type | Description | Default |
---|---|---|---|
value |
[description] |
required |
Returns:
Type | Description |
---|---|
[descriptions] |
Source code in parameterspace/priors/categorical.py
def loglikelihood(self, value):
return np.log(self.pdf(value))
pdf(self, value)
Probability given the numerical representation(s).
The numerical representation is converted to integers and the corresponding prior_values are returned. If the value exceeds the given range of values, a ValueError is raised.
Only finite values are converted, and the respective probability is computed. NaN and INF will result in a NaN. For example: value = [nan, inf, 0] will result in [NaN, NaN, p(0)].
Source code in parameterspace/priors/categorical.py
def pdf(self, value):
"""Probability given the numerical representation(s).
The numerical representation is converted to integers and the corresponding
prior_values are returned.
If the value exceeds the given range of values, a ValueError is raised.
Only finite values are converted, and the respective probability is computed.
NaN and INF will result in a NaN. For example:
value = [nan, inf, 0]
will result in
[NaN, NaN, p(0)].
"""
value = np.atleast_1d(value)
idx = np.isfinite(value)
integer_value = np.around(len(self.probabilities) * value[idx] - 0.5).astype(
int
)
pdf = np.full(value.shape, np.nan, dtype=float)
try:
pdf[idx] = self.probabilities[integer_value]
except IndexError as e:
raise ValueError(
"Unknown value in the numerical representation for a "
+ "categorical parameter encountered!"
) from e
return pdf.squeeze()
sample(self, num_samples=None, random_state=<module 'numpy.random' from '/home/runner/.cache/pypoetry/virtualenvs/parameterspace-9AYrJA9h-py3.8/lib/python3.8/site-packages/numpy/random/__init__.py'>)
Draw random samples from the prior.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
num_samples |
[description] |
None |
Returns:
Type | Description |
---|---|
[descriptions] |
Source code in parameterspace/priors/categorical.py
def sample(self, num_samples=None, random_state=np.random):
return random_state.choice(
self.numerical_values, size=num_samples, replace=True, p=self.probabilities
)