Creating custom likelihoods with DensityDist - what am I doing wrong?

I am trying to use a log-logistic (fisk) likelihood for my model. Seeing as PyMC3 doesn’t offer one, I decided to try and use DesnityDist to define my own log-likelihood analytically. I have followed the docs and have the following simple model:

# Set up priors
beta_1_ON = pm.Normal('beta_1_ON_{0}'.format(index), mu=3, sd=1)
beta_1_OFF = pm.Normal('beta_1_OFF_{0}'.format(index),mu=3, sd=1)
beta_2_ON = pm.Normal('beta_2_ON_{0}'.format(index), mu=1, sd=0.5)
beta_2_OFF = pm.Normal('beta_2_OFF_{0}'.format(index), mu=1, sd=0.5)

beta_0 = pm.Normal('beta_0_{0}'.format(index), mu=1, sd=0.5)

hyper_param_1_ON = pm.Normal('hyper_param_1_ON_{0}'.format(index), mu=0.5, sd=0.2)
hyper_param_1_OFF = pm.Normal('hyper_param_1_OFF_{0}'.format(index), mu=0.5, sd=0.2)
hyper_param_2_ON = pm.Normal('hyper_param_2_ON_{0}'.format(index), mu=0.2, sd=0.1)
hyper_param_2_OFF = pm.Normal('hyper_param_2_OFF_{0}'.format(index), mu=0.2, sd=0.1)

# Likelihood
alpha = beta_1_ON*np.power(ON_shared, hyper_param_1_ON) + beta_1_OFF*np.power(OFF_shared, hyper_param_1_OFF) + beta_0
beta = beta_2_ON*np.power(ON_shared, hyper_param_2_ON) + beta_2_OFF*np.power(OFF_shared, hyper_param_2_OFF)

mu = T.log(alpha)
s = T.power(beta, -1)
	
def logp(value):
    return T.exp(-(value - mu)/s)/(s*T.power((1 + T.exp(-(value - mu)/s)),2)) # this is the analytical form of logistic pdf

DWELLS_obs = pm.DensityDist('DWELLS_obs_{0}'.format(index), logp, observed=DWTIME)

# Sample using MCMC
step = pm.Metropolis([beta_1_ON, beta_1_OFF, beta_2_ON, beta_2_OFF, beta_0, hyper_param_1_ON, hyper_param_1_OFF, hyper_param_2_ON, hyper_param_2_OFF])
trace = pm.sample(1000, step=step)

# Update covariates to make prediction
ON_shared.set_value(estimated_ON)
OFF_shared.set_value(estimated_OFF)

# Sample again to find Posterior Predictive Distributino
ppc = pm.sample_ppc(trace, samples=500, size=100)

Unfortunately, I get the following error when trying to use this model:

Traceback (most recent call last):
File "/Users/conor/cmu/riss_icl/modelling/dwell_time/fisk2.py", line 247, in <module>
ppc = pm.sample_ppc(trace, samples=500, size=100)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/pymc3/sampling.py", line 571, in sample_ppc
ppc[var.name].append(var.distribution.random(point=param,
AttributeError: 'DensityDist' object has no attribute 'random'

I have never used DesnityDist before so I am not sure if I am correctly using it. I would greatly appreciate if anyone can help me understand what I am doing wrong!

See below, seems like it hasn’t been implemented yet but rather implementing as a subclass of distributions works

1 Like