How can we build a mixture of mixtures?

Ok, I knew that I could use the mixture in that case. The previous code was a toy problem showing the encountered problem while trying to build a mixture myself…

Meanwhile I found an other work around for my problem :wink:

And then, I face another strange behavior :cry: : mixtures behaves differently if they have been built from a unique multi-dimensional distribution, or from a list of mono-dimensional distributions.

This is the method using a list of mono-dimensional distributions (let’s call this the ‘A’ version of the code) :

with pm.Model() as model:
    ln_nbr = 5
    ln_components = []
    for i in range(ln_nbr): # explicit loop (bad!?)
        mu = pm.Exponential('mu_'+str(i), lam=1) 
        sd = pm.HalfNormal('sd_'+str(i), sd=1) 
        ln_components.append(pm.Lognormal.dist(mu=mu,sd=sd)) #,shape=ln_nbr)
    ln_w = pm.Dirichlet('ln_w',a=np.array([0.0000001]*ln_nbr))
    ln_mix = pm.Mixture.dist(w=ln_w,comp_dists=ln_components)

In that case I can call : ln_mix.logp(x) (not show in the code example)
and it runs ok.

But If I do the same mixture built from a multidimensional random variable (instead of a list of mono-dimensional ones), then I can’t run the lopg method !! Why ??

The following code (‘B’ version) should (theoretically) be equivalent to the one above (A) : (but it’s not!)

with pm.Model() as model:
    # "continuous" part : lognormal mixture
    ln_nbr = 5
    mu = pm.Exponential('mu', lam=1, shape=ln_nbr)
    sd = pm.HalfNormal('sd', sd=1, shape=ln_nbr)
    ln_components = pm.Lognormal.dist(mu=mu,sd=sd,shape=ln_nbr)
    ln_w = pm.Dirichlet('ln_w',a=np.array([0.0000001]*ln_nbr))
    ln_mix = pm.Mixture.dist(w=ln_w,comp_dists=ln_components)
    print(" end lognorm part...")

When trying to access the “ln_mix.logp(x)” method, I get this error message :

TypeError: 'Lognormal' object is not iterable

The error is linked to the ln_mix.logp() call.

This is sad since I guess that this later model formulation (B) is the most efficient one (without explicit loop). Am I guessing right ?

If the B version is the most efficient, how can I still access the logp method when building my model that way ?

Thanks for your help (even for the "mis leading " one :wink: , it helped me better understand my problem and the library philosophy.)