Hello all,
I am having a heck of a time figuring out how to use DensityDist. In this case I am looking to use a left-skewed Gumbel and that is implemented in scipy which gives the logp for you which seems like a good thing to not have to get right. Here is my most recent attempt, I have tried several combinations of Theano stuff (that I seem to have a mental block against understanding) but am not sure the issue lies there. The observed values are just a few representative numbers, I have a large data set.
import numpy as np
import pymc3 as pm
import scipy
import scipy.stats
import theano.tensor as tt
from theano.compile.ops import as_op
with pm.Model() as model_l:
@as_op(itypes=[tt.dvector], otypes=[tt.dscalar])
def logp_(value):
return scipy.stats.gumbel_l(loc=loc, scale=scale).logpdf(value)
loc = pm.Uniform('loc', -100, 100)
scale = pm.Uniform('scale', 0, 100)
gumbel_l = pm.DensityDist('gumbel_l', logp_,
observed=[0, -5, -10, -20])
trace1970 = pm.sample(1000, njobs=4)
pm.traceplot(trace1970, combined=True)
pm.summary(trace1970)
Which gives:
ValueError: setting an array element with a sequence.
I suppose this is from scipy.stats.gumbel_l.logpdf()
not liking vector input.
So I tried wrapping this in a list comprehension:
with pm.Model() as model_l:
@as_op(itypes=[tt.dvector], otypes=[tt.dvector])
def logp_(value):
return np.asarray([scipy.stats.gumbel_l(loc=l, scale=s).logpdf(value)
for l, s in zip(loc, scale)])
loc = pm.Uniform('loc', -100, 100)
scale = pm.Uniform('scale', 0, 100)
gumbel_l = pm.DensityDist('gumbel_l', logp_,
observed=[0, -5, -10, -20])
trace1970 = pm.sample(1000, njobs=4)
pm.traceplot(trace1970, combined=True)
pm.summary(trace1970)
Which gives:
TypeError: TensorType does not support iteration. Maybe you are using builtin.sum instead of theano.tensor.sum? (Maybe .max?)
This whole effort seems like something that people might want to do commonly as scipy.stats has a ton of distributions. However I could not find an internet example.
Anyone have any tips/examples here?