Using a bounded variable within a Mixture

I am trying to use a Bounded variable within a Mixture model. I have the following so far:


with pm.Model() as model:
    alpha = pm.Gamma('alpha', 1,1)
    beta = pm.Beta('beta', 1, alpha, shape=K)
    w = pm.Deterministic('w', stick_breaking(beta))
    #a = pm.Uniform('a', 0, 50, shape=K)
    #b = pm.Uniform('b', 0, 50, shape=K)
    mu = pm.Uniform('mu', 0, 50, shape=K)
    bp = pm.Bound(pm.Poisson, lower=1)('bp', mu=mu)
    x = pm.Mixture('obs', w, bp.dist(), observed=df['x1'].values)

It throws the following error:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-121-ee34f0f15713> in <module>()
      8     mu = pm.Uniform('mu', 0, 50, shape=K)
      9     bp = pm.Bound(pm.Poisson, lower=1)('bp', mu=mu)
---> 10     x = pm.Mixture('obs', w, bp.dist(), observed=df['x1'].values)

AttributeError: 'FreeRV' object has no attribute 'dist'

How do I correct this?

I think you should write bp as bp = pm.Bound(pm.Poisson, lower=1).dist(mu=mu)

@aloctavodia
You mean like this?


with pm.Model() as model:
    alpha = pm.Gamma('alpha', 1,1)
    beta = pm.Beta('beta', 1, alpha, shape=K)
    w = pm.Deterministic('w', stick_breaking(beta))
    #a = pm.Uniform('a', 0, 50, shape=K)
    #b = pm.Uniform('b', 0, 50, shape=K)
    mu = pm.Uniform('mu', 0, 50, shape=K)
    bp = pm.Bound(pm.Poisson, lower=1).dist( mu=mu)
    #x = pm.Mixture('obs', w, pm.Poisson.dist(mu), observed=df['x1'].values)
    x = pm.Mixture('obs', w, bp, observed=df['x1'].values)

I get the following error:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
C:\Anaconda3\envs\stpy35\lib\site-packages\pymc3\distributions\mixture.py in _comp_modes(self)
     95         try:
---> 96             return tt.as_tensor_variable(self.comp_dists.mode)
     97         except AttributeError:

AttributeError: '_DiscreteBounded' object has no attribute 'mode'

During handling of the above exception, another exception occurred:

TypeError                                 Traceback (most recent call last)
<ipython-input-15-811a1e7927a9> in <module>()
      9     bp = pm.Bound(pm.Poisson, lower=1).dist( mu=mu)
     10     #x = pm.Mixture('obs', w, pm.Poisson.dist(mu), observed=df['x1'].values)
---> 11     x = pm.Mixture('obs', w, bp, observed=df['x1'].values)

C:\Anaconda3\envs\stpy35\lib\site-packages\pymc3\distributions\distribution.py in __new__(cls, name, *args, **kwargs)
     34                 raise TypeError("observed needs to be data but got: {}".format(type(data)))
     35             total_size = kwargs.pop('total_size', None)
---> 36             dist = cls.dist(*args, **kwargs)
     37             return model.Var(name, dist, data, total_size)
     38         else:

C:\Anaconda3\envs\stpy35\lib\site-packages\pymc3\distributions\distribution.py in dist(cls, *args, **kwargs)
     45     def dist(cls, *args, **kwargs):
     46         dist = object.__new__(cls)
---> 47         dist.__init__(*args, **kwargs)
     48         return dist
     49 

C:\Anaconda3\envs\stpy35\lib\site-packages\pymc3\distributions\mixture.py in __init__(self, w, comp_dists, *args, **kwargs)
     62 
     63         try:
---> 64             comp_modes = self._comp_modes()
     65             comp_mode_logps = self.logp(comp_modes)
     66             self.mode = comp_modes[tt.argmax(w * comp_mode_logps, axis=-1)]

C:\Anaconda3\envs\stpy35\lib\site-packages\pymc3\distributions\mixture.py in _comp_modes(self)
     96             return tt.as_tensor_variable(self.comp_dists.mode)
     97         except AttributeError:
---> 98             return tt.stack([comp_dist.mode for comp_dist in self.comp_dists],
     99                             axis=1)
    100 

TypeError: '_DiscreteBounded' object is not iterable

ups!

I guess this will also fail, right?

bp = pm.Bound(pm.Poisson, lower=1).dist(mu=mu, shape=K)

so, try this

bp = [pm.Bound(pm.Poisson, lower=1).dist(mu=mu[i]) for i in range(K)]
1 Like

@aloctavodia
Yes, that second one works. Thank you very much.

However, how do I refer to the variable by name? So I can grab it from trace, like so trace[‘myvar’]. Here is the code in case someone else needs to use similar tricks:

with pm.Model() as model:
    alpha = pm.Gamma('alpha', 1,1)
    beta = pm.Beta('beta', 1, alpha, shape=K)
    w = pm.Deterministic('w', stick_breaking(beta))
    #a = pm.Uniform('a', 0, 50, shape=K)
    #b = pm.Uniform('b', 0, 50, shape=K)
    mu = pm.Uniform('mu', 0, 50, shape=K)
    bp = [pm.Bound(pm.Poisson, lower=1).dist( mu=mu[i]) for i in range(K)] 
    #x = pm.Mixture('obs', w, pm.Poisson.dist(mu), observed=df['x1'].values)
    x = pm.Mixture('obs', w, bp, observed=df['x1'].values)

Not sure if that’s possible with the current implementation of Mixture. Maybe @AustinRochford has a solution.

ok, thank you @aloctavodia. Is it possible for me to message you in private, so perhaps you could show me around the codebase and that way help myself quicker and perhaps other folks as well?

You can contact me in private, no problem. But if you have a question that may also help others, is better to ask it publicly so other can benefit from it and also you may get a better/faster answer from others than from me.

1 Like

I think bp needs to have shape > 1 in order for a mixture to make sense.