From 7cc570a867fa8a4f8018d91c0aab1cf2aab64258 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Mon, 14 Mar 2022 14:28:15 +0100 Subject: [PATCH] Rename ZeroInflatedPoisson theta parameter to mu For consistency with the base Poisson distribution --- RELEASE-NOTES.md | 1 + pymc/distributions/discrete.py | 28 ++++++++++++------------ pymc/tests/test_distributions.py | 16 +++++++------- pymc/tests/test_distributions_moments.py | 6 ++--- pymc/tests/test_sampling.py | 6 ++--- 5 files changed, 29 insertions(+), 28 deletions(-) diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index b14b39aa9c..1295d393d0 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -74,6 +74,7 @@ All of the above apply to: - The function `replace_with_values` function has been added to `gp.utils`. - `MarginalSparse` has been renamed `MarginalApprox`. - Removed `MixtureSameFamily`. `Mixture` is now capable of handling batched multivariate components (see [#5438](https://github.com/pymc-devs/pymc/pull/5438)). + - `ZeroInflatedPoisson` `theta` parameter was renamed to `mu` (see [#5584](https://github.com/pymc-devs/pymc/pull/5584)). - ... ### Expected breaks diff --git a/pymc/distributions/discrete.py b/pymc/distributions/discrete.py index 4a7c14423a..cadae04b8d 100644 --- a/pymc/distributions/discrete.py +++ b/pymc/distributions/discrete.py @@ -1414,8 +1414,8 @@ class ZeroInflatedPoisson: .. math:: - f(x \mid \psi, \theta) = \left\{ \begin{array}{l} - (1-\psi) + \psi e^{-\theta}, \text{if } x = 0 \\ + f(x \mid \psi, \mu) = \left\{ \begin{array}{l} + (1-\psi) + \psi e^{-\mu}, \text{if } x = 0 \\ \psi \frac{e^{-\theta}\theta^x}{x!}, \text{if } x=1,2,3,\ldots \end{array} \right. @@ -1428,13 +1428,13 @@ class ZeroInflatedPoisson: plt.style.use('arviz-darkgrid') x = np.arange(0, 22) psis = [0.7, 0.4] - thetas = [8, 4] - for psi, theta in zip(psis, thetas): - pmf = st.poisson.pmf(x, theta) + mus = [8, 4] + for psi, mu in zip(psis, mus): + pmf = st.poisson.pmf(x, mu) pmf[0] = (1 - psi) + pmf[0] pmf[1:] = psi * pmf[1:] pmf /= pmf.sum() - plt.plot(x, pmf, '-o', label='$\\psi$ = {}, $\\theta$ = {}'.format(psi, theta)) + plt.plot(x, pmf, '-o', label='$\\psi$ = {}, $\\mu$ = {}'.format(psi, mu)) plt.xlabel('x', fontsize=12) plt.ylabel('f(x)', fontsize=12) plt.legend(loc=1) @@ -1442,28 +1442,28 @@ class ZeroInflatedPoisson: ======== ========================== Support :math:`x \in \mathbb{N}_0` - Mean :math:`\psi\theta` - Variance :math:`\theta + \frac{1-\psi}{\psi}\theta^2` + Mean :math:`\psi\mu` + Variance :math:`\mu + \frac{1-\psi}{\psi}\mu^2` ======== ========================== Parameters ---------- psi: float Expected proportion of Poisson variates (0 < psi < 1) - theta: float + mu: float Expected number of occurrences during the given interval - (theta >= 0). + (mu >= 0). """ - def __new__(cls, name, psi, theta, **kwargs): + def __new__(cls, name, psi, mu, **kwargs): return _zero_inflated_mixture( - name=name, nonzero_p=psi, nonzero_dist=Poisson.dist(mu=theta), **kwargs + name=name, nonzero_p=psi, nonzero_dist=Poisson.dist(mu=mu), **kwargs ) @classmethod - def dist(cls, psi, theta, **kwargs): + def dist(cls, psi, mu, **kwargs): return _zero_inflated_mixture( - name=None, nonzero_p=psi, nonzero_dist=Poisson.dist(mu=theta), **kwargs + name=None, nonzero_p=psi, nonzero_dist=Poisson.dist(mu=mu), **kwargs ) diff --git a/pymc/tests/test_distributions.py b/pymc/tests/test_distributions.py index 2e8e599f1e..27610f456a 100644 --- a/pymc/tests/test_distributions.py +++ b/pymc/tests/test_distributions.py @@ -1747,33 +1747,33 @@ def test_constantdist(self): self.check_logcdf(Constant, I, {"c": I}, lambda value, c: np.log(value >= c)) def test_zeroinflatedpoisson(self): - def logp_fn(value, psi, theta): + def logp_fn(value, psi, mu): if value == 0: - return np.log((1 - psi) * sp.poisson.pmf(0, theta)) + return np.log((1 - psi) * sp.poisson.pmf(0, mu)) else: - return np.log(psi * sp.poisson.pmf(value, theta)) + return np.log(psi * sp.poisson.pmf(value, mu)) - def logcdf_fn(value, psi, theta): - return np.log((1 - psi) + psi * sp.poisson.cdf(value, theta)) + def logcdf_fn(value, psi, mu): + return np.log((1 - psi) + psi * sp.poisson.cdf(value, mu)) self.check_logp( ZeroInflatedPoisson, Nat, - {"psi": Unit, "theta": Rplus}, + {"psi": Unit, "mu": Rplus}, logp_fn, ) self.check_logcdf( ZeroInflatedPoisson, Nat, - {"psi": Unit, "theta": Rplus}, + {"psi": Unit, "mu": Rplus}, logcdf_fn, ) self.check_selfconsistency_discrete_logcdf( ZeroInflatedPoisson, Nat, - {"theta": Rplus, "psi": Unit}, + {"mu": Rplus, "psi": Unit}, ) def test_zeroinflatednegativebinomial(self): diff --git a/pymc/tests/test_distributions_moments.py b/pymc/tests/test_distributions_moments.py index db1af97b00..0727963a92 100644 --- a/pymc/tests/test_distributions_moments.py +++ b/pymc/tests/test_distributions_moments.py @@ -624,7 +624,7 @@ def test_constant_moment(c, size, expected): @pytest.mark.parametrize( - "psi, theta, size, expected", + "psi, mu, size, expected", [ (0.9, 3.0, None, 3), (0.8, 2.9, 5, np.full(5, 2)), @@ -632,9 +632,9 @@ def test_constant_moment(c, size, expected): (0.2, np.arange(1, 5) * 5, (2, 4), np.full((2, 4), np.arange(1, 5))), ], ) -def test_zero_inflated_poisson_moment(psi, theta, size, expected): +def test_zero_inflated_poisson_moment(psi, mu, size, expected): with Model() as model: - ZeroInflatedPoisson("x", psi=psi, theta=theta, size=size) + ZeroInflatedPoisson("x", psi=psi, mu=mu, size=size) assert_moment_is_expected(model, expected) diff --git a/pymc/tests/test_sampling.py b/pymc/tests/test_sampling.py index c957df19a6..9b4bfe062a 100644 --- a/pymc/tests/test_sampling.py +++ b/pymc/tests/test_sampling.py @@ -1128,11 +1128,11 @@ def test_shape_edgecase(self): def test_zeroinflatedpoisson(self): with pm.Model(): - theta = pm.Beta("theta", alpha=1, beta=1) + mu = pm.Beta("mu", alpha=1, beta=1) psi = pm.HalfNormal("psi", sd=1) - pm.ZeroInflatedPoisson("suppliers", psi=psi, theta=theta, size=20) + pm.ZeroInflatedPoisson("suppliers", psi=psi, mu=mu, size=20) gen_data = pm.sample_prior_predictive(samples=5000) - assert gen_data.prior["theta"].shape == (1, 5000) + assert gen_data.prior["mu"].shape == (1, 5000) assert gen_data.prior["psi"].shape == (1, 5000) assert gen_data.prior["suppliers"].shape == (1, 5000, 20)