I am still new to PyMC3 and statistics, so I am looking for a critique of my hierarchical model that will hopefully improve its sampling speed. Right now, it starts out fast but slows down dramatically <1 sample/second after about 400 samples.
The data set consists of about 2000 timeseries (these are product revenues), each about 30 time periods in length. A lot of the data is missing (right-censored). I model the timeseries as a piecewise function (logistic growth, followed by exponential decay) and use PyMC3 to infer the parameters of that function for each individual timeseries, as well as its hyperparameters for the whole dataset.
Hopefully, it makes some sense with the code:
y = CF # revenue data
t = np.arange(y.shape[1]) # time index
n_products = y.shape[0] # number of products to be modeled
s = (n_products, 1) # Dimensionality of prior distributions
with pm.Model() as truncated_like_model:
# Logistic growth hyperpriors
Smax_sd = pm.HalfCauchy('Smax_sd', beta = 1000)
t0_mu = pm.Normal('t0_mu', mu = -.5)
t0_sd = pm.HalfCauchy('t0_sd', beta = 1)
Kon_sd = pm.HalfCauchy('Kon_sd', beta = 1)
# Logistic growth priors
Smax = pm.HalfNormal('Smax', sd = Smax_sd, shape = s)
t0 = pm.Normal('t0', mu = t0_mu, sd = t0_sd, shape = s)
Kon = pm.HalfNormal('Kon', sd = Kon_sd, shape = s)
# Exponential decay hyperpriors
t1_sd = pm.HalfCauchy('t1_sd', beta = 2)
Koff_sd = pm.HalfCauchy('Koff_sd', beta = 1)
# Exponential decay priors
t1 = pm.HalfNormal('t1', sd = t1_sd, shape = s)
Koff = pm.HalfNormal('Koff', sd = Koff_sd, shape = s)
# Piecewise sales function
growth = Smax / (1 + pm.math.exp(-Kon*(t-t0)))
decay = Smax * pm.math.exp(-Koff*(t-t1))
# Soft switch
weight = pm.math.sigmoid(2 * (t - t1))
# Likelihood
mu = pm.math.abs_(growth + weight * (decay - growth))
sigma = pm.HalfCauchy('sigma', beta=100) #* pm.math.sqrt(pm.math.sqrt(t+1.))
likelihood = pm.TruncatedNormal('sales', mu = mu, sd = sigma, lower = 0, upper = y.max().max(), observed = y)
Any advice is greately appreciated!