Distribution utility classes and functions¶
|
Statistical distribution |
|
Base class for discrete distributions |
|
Base class for continuous distributions |
|
|
|
Distribution based on a given log density function. |
|
|
|
Draw (fix) parameter values. |
|
Generate samples from the distribution of a random variable. |
-
class
pymc3.distributions.
Distribution
(name, *args, **kwargs)¶ Statistical distribution
-
class
pymc3.distributions.
Discrete
(name, *args, **kwargs)¶ Base class for discrete distributions
-
class
pymc3.distributions.
Continuous
(name, *args, **kwargs)¶ Base class for continuous distributions
-
class
pymc3.distributions.
NoDistribution
(name, *args, **kwargs)¶
-
class
pymc3.distributions.
DensityDist
(name, *args, **kwargs)¶ Distribution based on a given log density function.
A distribution with the passed log density function is created. Requires a custom random function passed as kwarg random to enable prior or posterior predictive sampling.
- Parameters
- logp: callable
A callable that has the following signature
logp(value)
and returns a theano tensor that represents the distribution’s log probability density.- shape: tuple (Optional): defaults to `()`
The shape of the distribution. The default value indicates a scalar. If the distribution is not scalar-valued, the programmer should pass a value here.
- dtype: None, str (Optional)
The dtype of the distribution.
- testval: number or array (Optional)
The
testval
of the RV’s tensor that follow theDensityDist
distribution.- random: None or callable (Optional)
If
None
, no random method is attached to theDensityDist
instance. If a callable, it is used as the distribution’srandom
method. The behavior of this callable can be altered with thewrap_random_with_dist_shape
parameter. The supplied callable must have the following signature:random(point=None, size=None, **kwargs)
, wherepoint
is aNone
or a dictionary of random variable names and their corresponding values (similar to whatMultiTrace.get_point
returns).size
is the number of IID draws to take from the distribution. Any extra keyword argument can be added as required.- wrap_random_with_dist_shape: bool (Optional)
If
True
, the providedrandom
callable is passed throughgenerate_samples
to make the random number generator aware of theDensityDist
instance’sshape
. IfFalse
, it is used exactly as it was provided.- check_shape_in_random: bool (Optional)
If
True
, the shape of the random samples generate in therandom
method is checked with the expected return shape. This test is only performed ifwrap_random_with_dist_shape is False
.- args, kwargs: (Optional)
These are passed to the parent class’
__init__
.
Notes
If the
random
method is wrapped with dist shape, what this means is that therandom
callable will be wrapped with thegenereate_samples()
function. The distribution’s shape will be passed togenerate_samples()
as thedist_shape
parameter. Any extrakwargs
provided torandom
will be passed asnot_broadcast_kwargs
ofgenerate_samples()
.Examples
with pm.Model(): mu = pm.Normal('mu',0,1) normal_dist = pm.Normal.dist(mu, 1) pm.DensityDist( 'density_dist', normal_dist.logp, observed=np.random.randn(100), random=normal_dist.random ) trace = pm.sample(100)
If the
DensityDist
is multidimensional, some care must be taken with the suppliedrandom
method. By default, the supplied random is wrapped bygenerate_samples()
to make it aware of the multidimensional distribution’s shape. This can be prevented settingwrap_random_with_dist_shape=False
. Furthermore, thesize
parameter is interpreted as the number of IID draws to take from this multidimensional distribution.with pm.Model(): mu = pm.Normal('mu', 0 , 1) normal_dist = pm.Normal.dist(mu, 1, shape=3) dens = pm.DensityDist( 'density_dist', normal_dist.logp, observed=np.random.randn(100, 3), shape=3, random=normal_dist.random, ) prior = pm.sample_prior_predictive(10)['density_dist'] assert prior.shape == (10, 100, 3)
If
wrap_random_with_dist_shape=False
, we start to get samples of an incorrect shape. By default, we can try to catch these situations.with pm.Model(): mu = pm.Normal('mu', 0 , 1) normal_dist = pm.Normal.dist(mu, 1, shape=3) dens = pm.DensityDist( 'density_dist', normal_dist.logp, observed=np.random.randn(100, 3), shape=3, random=normal_dist.random, wrap_random_with_dist_shape=False, # Is True by default ) err = None try: prior = pm.sample_prior_predictive(10)['density_dist'] except RuntimeError as e: err = e assert isinstance(err, RuntimeError)
The default catching can be disabled with the
check_shape_in_random
parameter.with pm.Model(): mu = pm.Normal('mu', 0 , 1) normal_dist = pm.Normal.dist(mu, 1, shape=3) dens = pm.DensityDist( 'density_dist', normal_dist.logp, observed=np.random.randn(100, 3), shape=3, random=normal_dist.random, wrap_random_with_dist_shape=False, # Is True by default check_shape_in_random=False, # Is True by default ) prior = pm.sample_prior_predictive(10)['density_dist'] # We get samples with an incorrect shape assert prior.shape != (10, 100, 3)
If you use callables that work with
scipy.stats
rvs, you must be aware that theirsize
parameter is not the number of IID samples to draw from a distribution, but the desiredshape
of the returned array of samples. It is the user’s responsibility to wrap the callable to make it comply with PyMC3’s interpretation ofsize
.with pm.Model(): mu = pm.Normal('mu', 0 , 1) normal_dist = pm.Normal.dist(mu, 1, shape=3) dens = pm.DensityDist( 'density_dist', normal_dist.logp, observed=np.random.randn(100, 3), shape=3, random=stats.norm.rvs, pymc3_size_interpretation=False, # Is True by default ) prior = pm.sample_prior_predictive(10)['density_dist'] assert prior.shape == (10, 100, 3)
-
pymc3.distributions.
TensorType
(dtype, shape, broadcastable=None)¶
-
pymc3.distributions.
draw_values
(params, point=None, size=None)¶ Draw (fix) parameter values. Handles a number of cases:
The parameter is a scalar
The parameter is an RV
parameter can be fixed to the value in the point
parameter can be fixed by sampling from the RV
parameter can be fixed using tag.test_value (last resort)
3) The parameter is a tensor variable/constant. Can be evaluated using theano.function, but a variable may contain nodes which
are named parameters in the point
are RVs with a random method
-
pymc3.distributions.
generate_samples
(generator, *args, **kwargs)¶ Generate samples from the distribution of a random variable.
- Parameters
- generator: function
Function to generate the random samples. The function is expected take parameters for generating samples and a keyword argument
size
which determines the shape of the samples. The args and kwargs (stripped of the keywords below) will be passed to the generator function.- keyword arguments
- ~~~~~~~~~~~~~~~~~
- dist_shape: int or tuple of int
The shape of the random variable (i.e., the shape attribute).
- size: int or tuple of int
The required shape of the samples.
- broadcast_shape: tuple of int or None
The shape resulting from the broadcasting of the parameters. If not specified it will be inferred from the shape of the parameters. This may be required when the parameter shape does not determine the shape of a single sample, for example, the shape of the probabilities in the Categorical distribution.
- not_broadcast_kwargs: dict or None
Key word argument dictionary to provide to the random generator, which must not be broadcasted with the rest of the args and kwargs.
- Any remaining args and kwargs are passed on to the generator function.