Hello !
I’m trying to model a process using a zero-inflated exponential. I’ve written up a log-probability function for it, and giving it a test-drive in theano, I believe it gives me what I’m expecting. However, sampling with PyMC3 returns strange results – the zero-inflation rate always comes out at zero.
# Fix parameters
lam = 3
p = 0.2
# Generate some zero-inflated exponential random numbers
data = np.random.exponential(1/lam, size=100000)
data[np.random.rand(len(data)) < p] = 0
print("Number of zeros : {}".format((data == 0).sum()))
print("Mean : {:.2f}".format(data.mean()))
# Define the log-likelihood of a zero-inflated exponential
def zero_inflated_exponential(lam, p, x):
"""
Returns the log-probability of an exponential distribution,
with a fixed probability of seeing a zero instead.
"""
return tt.switch(
tt.eq(x, 0.),
tt.log(p + lam - (lam * p)),
tt.log(lam - (lam * p)) - (lam * x)
)
with pm.Model() as m:
# Priors on lambda and zero rate
lam_ = pm.HalfNormal("lam", sd=2)
p_ = pm.Uniform("p", lower=0, upper=1, testval=0.1)
# Our custom log-prob function
observed = pm.DensityDist(
"observed",
zero_inflated_exponential,
observed={"lam": lam_, "p": p_, "x": data}
)
trace = pm.sample(1000, chains=4, tune=500)
pm.traceplot(trace, combined=True);
Here’s the result.
Any help much appreciated in figuring out why this is happening. Note that when p = 0
, the MCMC correctly infers the value of lam
. What am I missing ?
Thanks so much.