Skip to content

Convert zero-inflated distributions to Mixture subclasses #2231

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

Closed
wants to merge 40 commits into from
Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
b407bdb
Added zero-inflated binomial distribution
fonnesbeck May 27, 2017
73694ef
Raise NotImplementedError for SplineWrapper gradient operation (#2211)
a-rodin May 27, 2017
524b88e
Fixed syntax error
fonnesbeck May 27, 2017
17b27b0
Added ZeroInflatedBinomial to global namespace
fonnesbeck May 27, 2017
4fd07b8
Fixed attribute error in call to scipy.stats
fonnesbeck May 27, 2017
da5401f
Use setup.py to create test environment
ColCarroll May 27, 2017
cfd29aa
Mock is also used
ColCarroll May 27, 2017
d35f0e5
Imported but untested requirements
ColCarroll May 27, 2017
0f7f6b5
Use conda numpy/scipy/mkl-service
ColCarroll May 27, 2017
b505f47
Merge pull request #2229 from ColCarroll/update_create_testenv
twiecki May 28, 2017
c3afa00
Vi summary (#2230)
ferrine May 28, 2017
52761c2
Return identity matrix if no scaling provided
a-rodin May 27, 2017
c4659b4
Simplify calculation of identity scaling matrix
a-rodin May 29, 2017
eb6042f
Merge pull request #2232 from a-rodin/scaling-default-to-identity
May 29, 2017
4a8f64f
scaling for NUTS using 'advi_map'
May 29, 2017
1aea645
Revert "Merge pull request #2232 from a-rodin/scaling-default-to-iden…
twiecki May 29, 2017
9b0f4fc
Merge pull request #2234 from junpenglao/master
May 29, 2017
999be1e
Imported ZeroInflatedBinomial in test_distributions
fonnesbeck May 29, 2017
e478fe3
Converted zero-inflated distributions to Mixture subclasses
fonnesbeck May 29, 2017
8bc7cbd
Changed docstring of zero-inflated distributions to specify two-compo…
fonnesbeck May 29, 2017
e7b7462
Fixing typo
KarinKnudson May 29, 2017
69e223b
Merge pull request #2237 from karink520/mixture_typo
May 29, 2017
a750e3d
Fixed dimension-matching issue with mixture weights in zero-inflated …
fonnesbeck May 29, 2017
4515977
Reversed order of psi, 1-psi to make them consistent with the definit…
fonnesbeck May 29, 2017
3d83c6d
Change sample() to use live_plot_kwargs instead of **kwargs. (#2235)
twiecki May 30, 2017
9327794
Clean up GLM doc (#2241)
May 30, 2017
9cb6d53
Don't broadcast conditions in Mixture logp
AustinRochford May 31, 2017
482e751
statsmodels is required for some examples
AustinRochford May 31, 2017
9047dfa
Revert "statsmodels is required for some examples"
AustinRochford May 31, 2017
541afd8
Merge pull request #2243 from AustinRochford/mixture-bound-dont-broad…
AustinRochford May 31, 2017
504fd60
Added zero-inflated binomial distribution
fonnesbeck May 27, 2017
8a9936b
Fixed syntax error
fonnesbeck May 27, 2017
9f7e8ee
Added ZeroInflatedBinomial to global namespace
fonnesbeck May 27, 2017
16576f9
Fixed attribute error in call to scipy.stats
fonnesbeck May 27, 2017
b7cfd1f
Imported ZeroInflatedBinomial in test_distributions
fonnesbeck May 29, 2017
b4494c6
Converted zero-inflated distributions to Mixture subclasses
fonnesbeck May 29, 2017
e847161
Changed docstring of zero-inflated distributions to specify two-compo…
fonnesbeck May 29, 2017
4e8df1c
Fixed dimension-matching issue with mixture weights in zero-inflated …
fonnesbeck May 29, 2017
1e05632
Reversed order of psi, 1-psi to make them consistent with the definit…
fonnesbeck May 29, 2017
0217259
Merge branch 'zero_inflated_binomial' of github.com:pymc-devs/pymc3 i…
fonnesbeck May 31, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions pymc3/distributions/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
from .discrete import Constant
from .discrete import ZeroInflatedPoisson
from .discrete import ZeroInflatedNegativeBinomial
from .discrete import ZeroInflatedBinomial
from .discrete import DiscreteUniform
from .discrete import Geometric
from .discrete import Categorical
Expand Down Expand Up @@ -106,6 +107,7 @@
'Constant',
'ZeroInflatedPoisson',
'ZeroInflatedNegativeBinomial',
'ZeroInflatedBinomial',
'DiscreteUniform',
'Geometric',
'Categorical',
Expand Down
63 changes: 62 additions & 1 deletion pymc3/distributions/discrete.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

__all__ = ['Binomial', 'BetaBinomial', 'Bernoulli', 'DiscreteWeibull',
'Poisson', 'NegativeBinomial', 'ConstantDist', 'Constant',
'ZeroInflatedPoisson', 'ZeroInflatedNegativeBinomial',
'ZeroInflatedPoisson', 'ZeroInflatedBinomial', 'ZeroInflatedNegativeBinomial',
'DiscreteUniform', 'Geometric', 'Categorical']


Expand Down Expand Up @@ -644,6 +644,67 @@ def _repr_latex_(self, name=None, dist=None):
get_variable_name(psi))


class ZeroInflatedBinomial(Discrete):
R"""
Zero-inflated Binomial log-likelihood.

.. math::

f(x \mid n, p, \psi) = \left\{ \begin{array}{l}
(1-\psi) + \psi (1-p)^{n}, \text{if } x = 0 \\
\psi {n \choose x} p^x (1-p)^{n-x}, \text{if } x=1,2,3,\ldots,n
\end{array} \right.

======== ==========================
Support :math:`x \in \mathbb{N}_0`
Mean :math:`(1 - \psi) n p`
Variance :math:`(1-\psi) n p [1 - p(1 - \psi n)].`
======== ==========================

Parameters
----------
n : int
Number of Bernoulli trials (n >= 0).
p : float
Probability of success in each trial (0 < p < 1).
psi : float
Expected proportion of Poisson variates (0 < psi < 1)

"""

def __init__(self, n, p, psi, *args, **kwargs):
super(ZeroInflatedBinomial, self).__init__(*args, **kwargs)
self.n = n = tt.as_tensor_variable(n)
self.p = p = tt.as_tensor_variable(p)
self.psi = psi = tt.as_tensor_variable(psi)
self.bin = Binomial.dist(n, p)
self.mode = self.bin.mode

def random(self, point=None, size=None, repeat=None):
n, p, psi = draw_values([self.n, self.p, self.psi], point=point)
g = generate_samples(stats.binom.rvs, n, p,
dist_shape=self.shape,
size=size)
sampled = g * (np.random.random(np.squeeze(g.shape)) < psi)
return reshape_sampled(sampled, size, self.shape)

def logp(self, value):
return tt.switch(value > 0,
tt.log(self.psi) + self.bin.logp(value),
tt.log((1. - self.psi) + self.psi * tt.pow(1 - self.p, self.n)))

def _repr_latex_(self, name=None, dist=None):
if dist is None:
dist = self
n = dist.n
p = dist.p
psi = dist.psi
return r'${} \sim \text{{ZeroInflatedBinomial}}(\mathit{{n}}={}, \mathit{{p}}={}, \mathit{{psi}}={})$'.format(name,
get_variable_name(n),
get_variable_name(p),
get_variable_name(psi))


class ZeroInflatedNegativeBinomial(Discrete):
R"""
Zero-Inflated Negative binomial log-likelihood.
Expand Down
4 changes: 4 additions & 0 deletions pymc3/tests/test_distributions.py
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,10 @@ def test_zeroinflatednegativebinomial(self):
self.checkd(ZeroInflatedNegativeBinomial, Nat,
{'mu': Rplusbig, 'alpha': Rplusbig, 'psi': Unit})

def test_zeroinflatedbinomial(self):
self.checkd(ZeroInflatedBinomial, Nat,
Copy link
Member

@junpenglao junpenglao May 29, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You forgot to import ZeroInflatedBinomial in the test_distributions.py

{'n': NatSmall, 'p': Unit, 'psi': Unit})

@pytest.mark.parametrize('n', [1, 2, 3])
def test_mvnormal(self, n):
self.pymc3_matches_scipy(MvNormal, RealMatrix(5, n),
Expand Down
3 changes: 3 additions & 0 deletions pymc3/tests/test_distributions_random.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,9 @@ class TestZeroInflatedNegativeBinomial(BaseTestCases.BaseTestCase):
distribution = pm.ZeroInflatedNegativeBinomial
params = {'mu': 1., 'alpha': 1., 'psi': 0.3}

class TestZeroInflatedBinomial(BaseTestCases.BaseTestCase):
distribution = pm.ZeroInflatedBinomial
params = {'n': 10, 'p': 0.6, 'psi': 0.3}

class TestDiscreteUniform(BaseTestCases.BaseTestCase):
distribution = pm.DiscreteUniform
Expand Down