Bayesian calibration with exterior model

I want to do a Bayesian calibration on an exterior model, in order to find the true value of the parameter “teta”.

I made a simple code to try to explain. Here “teta” is the parameter that I want to calibrate in the exterior model. The problem is that the exterior model can only receive integers or floats and not the variable FreeRV. How can I convert teta so that I can pass it to the exterior model?

import pymc3 as pm


def exterior_model(param):
    if param > 2:
        y = param * 3 + 2
    else:
        y = param * 1 + 2
    return y


true_param = 3  # Should receive the posterior parameter mean value = 3
observation = exterior_model(true_param)

prior_param = 1

with pm.Model() as model:
    #Prior parameter
    teta = pm.Normal("teta", mu=prior_param, sigma=1)
    
    model_mean = pm.Deterministic('mu', exterior_model(teta))
    #Likelihood
    likelihood = pm.Normal("y", mu = model_mean, sigma=1, observed=observation)

    #posterior
    trace = pm.sample(1000, cores=1)

Hi k.f

When it comes to fitting non-standard models like this piecewise function, things get a bit tricker. To make computation efficient, pymc depends on being able to represent your model symbolically (like as an algebra problem) and the extract derivates. It does all this with a library called pytensor. So your choices are broadly to rewrite your exterior_model in pytensor code or to wrap your exterior_model in a pytensor operation. Here is the guide that walks you through the wrapping process:

and here is an example of how you might rewrite your exterior_model as a pytensor function:

with pm.Model() as model:
    # Prior parameter
    teta = pm.Normal('teta', mu=prior_param, sigma=1)
  
    exterior_model = pt.switch(pt.gt(teta,2),teta * 3 + 2,teta * 1 + 2)

    model_mean = pm.Deterministic('mu', exterior_model)
    #Likelihood
    likelihood = pm.Normal("y", mu = model_mean, sigma=1, observed=observation)

    #posterior
    trace = pm.sample(1000, cores=1)
1 Like