I am trying to fit a hierarchical model using pymc3 and running into trouble where it looks like my priors are being sampled but my likelihood is not. I have tried replicating the approach described here that works for multiple observations.
I am using the mallard dataset found in the unmarked package in R, loaded as a pandas dataframe. You can grab the CSV I'm using from my GitHub page here. In brief, each row represents up to three observations (y1, y2, and y3 columns) collected along a single transect. I have tried removing rows with missing data (NaN) in any of the y columns or covariates (elevation, forest cover, survey length), which did not appear to change the issue I'm experiencing.
mallard = pd.read_csv('mallard.csv')
elev, length, forest = mallard.elev, mallard.length, mallard.forest
# transpose ys to have same shape as series of each covariate (elev, length...)
observations = mallard[['y1','y2','y3']].T
num_transects = len(mallard)
with pm.Model() as mallard_model:
# priors
# detection probability considered constant across all transects and plots
prob = pm.Beta('prob', alpha=1, beta=1)
# priors for deterministic linear model of local abundance at a transect
# that applies to all plots within a transect
b0 = pm.Normal('b0', mu=0, sd=10) # intercept
b1 = pm.Normal('b1', mu=0, sd=10) # elevation
b2 = pm.Normal('b2', mu=0, sd=10) # forest cover
b3 = pm.Normal('b3', mu=0, sd=10) # survey length
# linear model of local abundance using log link
lam = pm.Deterministic('lam', pm.math.exp(b0 + b1*elev + b2*forest + b3*length))
# likelihood of observations
# Ni is abundance at a transect, with binomial distribution across
# plots within a transect
Ni = pm.Poisson('Ni', mu=lam, shape=num_transects)
Y_obs = pm.Binomial('Y_obs', n=Ni, p=prob, observed=observations)
# inference, use default step functions for each parameter
trace = pm.sample(draws=5000, init='ADVI', n_init=10000)#, step=pm.Metropolis())
plt.figure(figsize=(7, 7))
pm.traceplot(trace[100:]) # leave out first 100 draws as burn-in
plt.tight_layout()
This is what comes out:
Assigned NUTS to prob_logodds_
Assigned NUTS to b0
Assigned NUTS to b1
Assigned NUTS to b2
Assigned NUTS to b3
Assigned Metropolis to Ni
Assigned Metropolis to Y_obs_missing
100%|████████████████████████████████| 5000/5000 [00:07<00:00, 675.88it/s]
I noticed there is no initialization output being reported using ADVI, which seems disconcerting.
I also found that if I force the model to use a particular step function (e.g., the pm.Metropolis()
I've commented out in the call to pm.sample
above), I do get sampling on some--but not all--parameters. Still no initialization reported either.
Any ideas how to get this working?