Posterior predictive with spline model


I am currently working with the following spline model:

with pm.Model() as model:
    b = patsy.dmatrix('cc(ALPHA, knots=knots)', {'ALPHA': df['ALPHA'], 'knots': np.arange(30,360,30)})
    model.add_coord('spline', length=b.shape[1], mutable=True)
    model.add_coord('angle', df['ALPHA'], mutable=True)
    data_b = pm.MutableData('data_b', np.asarray(b), dims=('angle', 'spline'))

    tau = pm.HalfCauchy('tau', 20)
    beta = pm.Normal('beta', mu=0, sigma=tau, dims='spline')
    mu = pm.Deterministic('mu',, beta), dims='angle')
    sigma = pm.HalfNormal('sigma', 0.01)
    pm.Normal('force_obs', mu=mu, sigma=sigma, observed=df['Force'], dims='angle')

Up to the step of sample() everything is fine. I plotted the mu of the posterior after averaging over the chains and draws which yields very reasonable results with respect to the observed variable.
Meanwhile the results yielded by plotting the posterior_predictive after using sample_posterior_predictive() appear very poor fluctuating around 0. That surprises me as actually only a tiny sigma should be added to the otherwise good result of mu.

Does someone have an idea where this problem stems from? Weird enough, when executing sample_posterior_predictive() it shows me that not only the observed variable is sampled but also beta (although beta is already present in the posterior). I suppose this might be related to the issue.

Yes, that’s probably it. If you change some “mutable dims” between sampling and posterior predictive, then PyMC won’t use what it learned about variables associated with those dims. The logic being, that it has “never” seen the new dim coordinates and doesn’t know what the posterior for those would have been like. In that case it samples the variable from the respective prior predictive as well.

What were you trying to do with the mutable dims? It may help if you share all your code as well.

Thank you very much for the hint! I wasn’t aware of that. Actually the mutable=True setting was just an artifact from a prior experiment and the functionality is not necessary anymore.