Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get the transform docs into the API pages. #3690

Merged
merged 12 commits into from
Nov 26, 2019
1 change: 1 addition & 0 deletions RELEASE-NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
- Wrapped `DensityDist.rand` with `generate_samples` to make it aware of the distribution's shape. Added control flow attributes to still be able to behave as in earlier versions, and to control how to interpret the `size` parameter in the `random` callable signature. Fixes [3553](https://github.com/pymc-devs/pymc3/issues/3553)
- Added `theano.gof.graph.Constant` to type checks done in `_draw_value` (fixes issue [3595](https://github.com/pymc-devs/pymc3/issues/3595))
- `HalfNormal` did not used to work properly in `draw_values`, `sample_prior_predictive`, or `sample_posterior_predictive` (fixes issue [3686](https://github.com/pymc-devs/pymc3/pull/3686))
- Random variable transforms were inadvertently left out of the API documentation. Added them. (See PR [3690](https://github.com/pymc-devs/pymc3/pull/3690)).

## PyMC3 3.7 (May 29 2019)

Expand Down
1 change: 1 addition & 0 deletions docs/source/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ API Reference
api/data
api/model
api/model_graph
api/variables
api/shape_utils


Expand Down
1 change: 1 addition & 0 deletions docs/source/api/distributions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ Distributions
distributions/multivariate
distributions/mixture
distributions/timeseries
distributions/transforms
distributions/utilities
143 changes: 143 additions & 0 deletions docs/source/api/distributions/transforms.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
****************************************************************
Transformations of a random variable from one space to another.
****************************************************************

Note that for convenience these entities can be addressed as
``pm.transforms.``\ *X* for any name *X*, although they are actually
implemented as ``pm.distributions.transforms.``\*X*.

.. currentmodule:: pymc3.distributions.transforms


.. contents ::

..
.. autosummary::

transform
stick_breaking
logodds
interval
log_exp_m1
lowerbound
upperbound
ordered
log
sum_to_1
t_stick_breaking
circular
CholeskyCovPacked
Chain



Transform Instances
~~~~~~~~~~~~~~~~~~~

Transform instances are the entities that should be used in the
``transform`` parameter to a random variable constructor. These are
initialized instances of the Transform Classes, which are described
below.

.. glossary::
``stick_breaking``
Instantiation of :class:`~pymc3.distributions.transforms.StickBreaking`
:class:`~pymc3.distributions.transforms.Transform` class for use in the ``transform``
argument of a random variable.

``logodds``
Instantiation of
:class:`~pymc3.distributions.transforms.LogOdds` :class:`~pymc3.distributions.transforms.Transform` class
for use in the ``transform`` argument of a random variable.

``interval``
Alias of
:class:`~pymc3.distributions.transforms.Interval` :class:`~pymc3.distributions.transforms.Transform` class
for use in the ``transform`` argument of a random variable.

``log_exp_m1``
Instantiation of
:class:`~pymc3.distributions.transforms.LogExpM1` :class:`~pymc3.distributions.transforms.Transform` class
for use in the ``transform`` argument of a random variable.

``lowerbound``
Alias of
:class:`~pymc3.distributions.transforms.LowerBound` :class:`~pymc3.distributions.transforms.Transform` class
for use in the ``transform`` argument of a random variable.

``upperbound``
Alias of
:class:`~pymc3.distributions.transforms.UpperBound` :class:`~pymc3.distributions.transforms.Transform` class
for use in the ``transform`` argument of a random variable.

``ordered``
Instantiation of
:class:`~pymc3.distributions.transforms.Ordered` :class:`~pymc3.distributions.transforms.Transform` class
for use in the ``transform`` argument of a random variable.

``log``
Instantiation of
:class:`~pymc3.distributions.transforms.Log` :class:`~pymc3.distributions.transforms.Transform` class
for use in the ``transform`` argument of a random variable.


``sum_to_1``
Instantiation of
:class:`~pymc3.distributions.transforms.SumTo1` :class:`~pymc3.distributions.transforms.Transform` class
for use in the ``transform`` argument of a random variable.


``circular``
Instantiation of
:class:`~pymc3.distributions.transforms.Circular` :class:`~pymc3.distributions.transforms.Transform` class
for use in the ``transform`` argument of a random variable.


.. autofunction:: t_stick_breaking


Transform Base Classes
~~~~~~~~~~~~~~~~~~~~~~

Typically the programmer will not use these directly.

.. autoclass:: Transform
:members:
.. autoclass:: transform
:members:
.. autoclass:: TransformedDistribution
:members:


Transform Composition Classes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. autoclass:: Chain
:members:
.. autoclass:: CholeskyCovPacked
:members:


Specific Transform Classes
~~~~~~~~~~~~~~~~~~~~~~~~~~

.. autoclass:: Log
:members:
.. autoclass:: LogExpM1
:members:
.. autoclass:: LogOdds
:members:
.. autoclass:: Interval
:members:
.. autoclass:: LowerBound
:members:
.. autoclass:: UpperBound
:members:
.. autoclass:: Ordered
:members:
.. autoclass:: SumTo1
:members:
.. autoclass:: StickBreaking
:members:
.. autoclass:: Circular
:members:
28 changes: 28 additions & 0 deletions docs/source/api/variables.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
Random Variables
----------------

.. currentmodule:: pymc3.model

The normal PyMC3 programmer will typically not need to interact with these classes, except possibly when debugging. Otherwise they are primarily of interest to developers.


.. autoclass:: PyMC3Variable
:members:


.. autoclass:: ValueGradFunction
:members:


.. autoclass:: FreeRV
:members:

.. autoclass:: ObservedRV
:members:

.. autoclass:: MultiObservedRV
:members:

.. autoclass:: TransformedRV
:members:

40 changes: 22 additions & 18 deletions docs/source/developer_guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -378,25 +378,29 @@ https://github.com/pymc-devs/pymc3/blob/6d07591962a6c135640a3c31903eba66b34e71d8
self.add_random_variable(var)
return var

In general, if there is observed, the RV is defined as a ``ObservedRV``,
otherwise if it has a transformed method, it is a ``TransformedRV``, otherwise, it returns the
most elementary form: a ``FreeRV``.
In general, if a variable has observations (``observed`` parameter), the RV is defined as an ``ObservedRV``,
otherwise if it has a ``transformed`` (``transform`` parameter) attribute, it is a
``TransformedRV``, otherwise, it will be the most elementary form: a
``FreeRV``. Note that this means that random variables with
observations cannot be transformed.

Below, I will take a deeper look into ``TransformedRV``, a normal user
Below, I will take a deeper look into ``TransformedRV``. A normal user
might not necessary come in contact with the concept, as
``TransformedRV`` and ``TransformedDistribution`` are intentionally not
user facing.

Because in PyMC3 there is no bijector class like in TFP or pyro, we only
have a partial implementation called ``Transform``, which implements
Jacobian correction for forward mapping only (there is no Jacobian
correction for inverse mapping). The use case we considered are limited
correction for inverse mapping). The use cases we considered are limited
to the set of distributions that are bounded, and the transformation
maps the bounded set to the real line - see
`doc <https://docs.pymc.io/notebooks/api_quickstart.html#Automatic-transforms-of-bounded-RVs>`__.
`doc
<https://docs.pymc.io/notebooks/api_quickstart.html#Automatic-transforms-of-bounded-RVs>`__.
However, other transformations are possible.
In general, PyMC3 does not provide explicit functionality to transform
one distribution to another. Instead, a dedicated distribution is
usually created in consideration of optimising performance. But getting a
usually created in order to optimise performance. But getting a
``TransformedDistribution`` is also possible (see also in
`doc <https://docs.pymc.io/notebooks/api_quickstart.html#Transformed-distributions-and-changes-of-variables>`__):

Expand All @@ -422,7 +426,7 @@ usually created in consideration of optimising performance. But getting a



Now, back to ``model.RV(...)`` - things return from ``model.RV(...)``
Now, back to ``model.RV(...)`` - things returned from ``model.RV(...)``
are Theano tensor variables, and it is clear from looking at
``TransformedRV``:

Expand All @@ -431,19 +435,19 @@ are Theano tensor variables, and it is clear from looking at
class TransformedRV(TensorVariable):
...

as for ``FreeRV`` and ``ObservedRV``, they are TensorVariable with
Factor:
as for ``FreeRV`` and ``ObservedRV``, they are ``TensorVariable``\s with
``Factor`` as mixin:

.. code:: python

class FreeRV(Factor, TensorVariable):
...

and ``Factor`` basically `enable and assign the
``Factor`` basically `enable and assign the
logp <https://github.com/pymc-devs/pymc3/blob/6d07591962a6c135640a3c31903eba66b34e71d8/pymc3/model.py#L195-L276>`__
(representated as a tensor also) property to a Theano tensor (thus
making it a random variable). For a ``TransformedRV``, it transform the
distribution into a ``TransformedDistribution``, and then model.Var is
making it a random variable). For a ``TransformedRV``, it transforms the
distribution into a ``TransformedDistribution``, and then ``model.Var`` is
called again to added the RV associated with the
``TransformedDistribution`` as a ``FreeRV``:

Expand Down Expand Up @@ -483,11 +487,11 @@ the model logp), and also deterministic transformation (as bookkeeping):
named\_vars, free\_RVs, observed\_RVs, deterministics, potentials,
missing\_values. The model context then computes some simple model
properties, builds a bijection mapping that transforms between
dictionary and numpy/Theano ndarray, thus allowing logp/dlogp function
to have two equivalent version: one take a dict as input and the other
take a ndarray as input. More importantly, a pm.Model() contains methods
to compile Theano function that takes Random Variables (that are also
initialised within the same model) as input.
dictionary and numpy/Theano ndarray, thus allowing the ``logp``/``dlogp`` functions
to have two equivalent versions: one takes a ``dict`` as input and the other
takes an ``ndarray`` as input. More importantly, a ``pm.Model()`` contains methods
to compile Theano functions that take Random Variables (that are also
initialised within the same model) as input, for example:

.. code:: python

Expand Down
1 change: 1 addition & 0 deletions pymc3/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from .blocking import *
from .distributions import *
from .distributions import transforms
from .glm import *
from . import gp
from .math import logaddexp, logsumexp, logit, invlogit, expand_packed_triangular, probit, invprobit
Expand Down
6 changes: 0 additions & 6 deletions pymc3/distributions/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,6 @@
from .timeseries import MvGaussianRandomWalk
from .timeseries import MvStudentTRandomWalk

from .transforms import transform
from .transforms import stick_breaking
from .transforms import logodds
from .transforms import log
from .transforms import sum_to_1

from .bound import Bound

__all__ = ['Uniform',
Expand Down
Loading