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
testvalof the RV’s tensor that follow theDensityDistdistribution.- random: None or callable (Optional)
If
None, no random method is attached to theDensityDistinstance. If a callable, it is used as the distribution’srandommethod. The behavior of this callable can be altered with thewrap_random_with_dist_shapeparameter. The supplied callable must have the following signature:random(point=None, size=None, **kwargs), wherepointis aNoneor a dictionary of random variable names and their corresponding values (similar to whatMultiTrace.get_pointreturns).sizeis 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 providedrandomcallable is passed throughgenerate_samplesto make the random number generator aware of theDensityDistinstance’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 therandommethod 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
randommethod is wrapped with dist shape, what this means is that therandomcallable will be wrapped with thegenereate_samples()function. The distribution’s shape will be passed togenerate_samples()as thedist_shapeparameter. Any extrakwargsprovided torandomwill be passed asnot_broadcast_kwargsofgenerate_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
DensityDistis multidimensional, some care must be taken with the suppliedrandommethod. 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, thesizeparameter 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_randomparameter.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.statsrvs, you must be aware that theirsizeparameter is not the number of IID samples to draw from a distribution, but the desiredshapeof 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
sizewhich 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.