Help with Mixture of Weibull Distribution


#1

import pymc3 as pm
import numpy as np

#Use iterable of distributions instead of array of random variables
with pm.Model() as weibull_2seg_2clust_withspike:
gamma_alpha = pm.Uniform(‘gamma_alpha’, lower=0.0, upper=30.0)
gamma_beta = pm.Uniform(‘gamma_beta’, lower=0.0, upper=30.0)
shape1 = pm.Uniform(‘shape1’, lower=0.0, upper=30.0)
scale1 = pm.Gamma(‘scale1’, alpha=gamma_alpha, beta=gamma_beta)
shape2 = pm.Uniform(‘shape2’, lower=0.0, upper=30.0)
scale2 = pm.Gamma(‘scale2’, alpha=gamma_alpha, beta=gamma_beta)

weibull1 = pm.Weibull('weibull1', alpha=shape1, beta=scale1)
weibull2 = pm.Weibull('weibull2', alpha=shape2, beta=scale2)   
#obs = pm.Normal('obs', mu=weibull1 + weibull2 , sd=10, observed=[1,2,3,4,5])

#weibull1 = pm.Weibull.dist(alpha=shape1, beta=scale1)
#weibull2 = pm.Weibull.dist(alpha=shape2, beta=scale2)

w = pm.Dirichlet('w', a=np.array([1, 1]))
obs = pm.Mixture('obs', w=w, comp_dists=[weibull1, weibull2], observed=[1,2,3,4,5])

trace = pm.sample(1000)

Above is a sample code reproducing my error. Any help is appreciated.


#2

You should uncommented and use below.

# weibull1 = pm.Weibull.dist(alpha=shape1, beta=scale1)
# weibull2 = pm.Weibull.dist(alpha=shape2, beta=scale2)

#3

Thanks @junpenglao

I was trying to create a mixture of 2 weibull distributions and am facing few issues with that line

import pymc3 as pm
import numpy as np

#Use iterable of distributions instead of array of random variables
with pm.Model() as weibull_2seg_2clust_withspike:
    gamma_alpha = pm.Uniform('gamma_alpha', lower=0.0, upper=30.0)
    gamma_beta = pm.Uniform('gamma_beta', lower=0.0, upper=30.0)
    shape1 = pm.Uniform('shape1', lower=0.0, upper=30.0)
    scale1 = pm.Gamma('scale1', alpha=gamma_alpha, beta=gamma_beta)
    shape2 = pm.Uniform('shape2', lower=0.0, upper=30.0)
    scale2 = pm.Gamma('scale2', alpha=gamma_alpha, beta=gamma_beta)   
    
    #weibull1 = pm.Weibull('weibull1', alpha=shape1, beta=scale1)
    #weibull2 = pm.Weibull('weibull2', alpha=shape2, beta=scale2)   
    #obs = pm.Normal('obs', mu=weibull1 + weibull2 , sd=10, observed=[1,2,3,4,5])
    
    weibull1 = pm.Weibull.dist(alpha=shape1, beta=scale1)
    weibull2 = pm.Weibull.dist(alpha=shape2, beta=scale2)
    
    w = pm.Dirichlet('w', a=np.array([1, 1]))
    obs = pm.Mixture('obs', w=w, comp_dists=[weibull1, weibull2], observed=[1,2,3,4,5])
    
    trace = pm.sample(1000)

#4

I am getting a huge stack trace with above code with a final error of ValueError: Mass matrix contains zeros on the diagonal. Some derivatives might always be zero.


#5

That usually is an indication of bad prior causing your model either unidentifiable or difficult to inference (Model diagnostics for “Mass matrix contains zeros on the diagonal”).
Try changing replacing the uniform prior (usually a bad choice for NUTS) to something more informative, eg
shape1 = pm.HalfNormal('shape1', 1.)


#6

Thanks. Trying it.

By the way when i used

    #trace = pm.sample(1000)
    
    inference = pm.fit(method='advi')  # this is mean field ADVI.  something like 'fullrank_advi' might be tried too
    trace = inference.sample(1000)

original code worked


#7

NUTS sampler worked smoothly with HalfNormal prior as well