I am trying to use a two-step procedure to estimate some ancillary variables and then use these estimated values in a real run:
the procedure is as follows:
with pm.Model(coords=coords) as baseModel:
# input data
NDVI_ = pm.MutableData("NDVI_", NDVI)
T_ = pm.MutableData("T11_", T_obs)
sm_ = pm.MutableData("sm_", sm_obs) #ONLY AVAILABLE FOR CALIBRATION
#priors
sigma_obs = 0.05
A_ = pm.Uniform('A_', 0, 1)
B_ = pm.Uniform('B_', 0, 1)
x1_ = pm.Deterministic('x1_', A_ + B_*NDVI_, dims='timeFrame')
def f(x1 = x1_, sm = sm_):
out = T(x1, sm) #external complex function
pp = len(out)
a = pt.tensor.zeros((2, sm_.shape))
for i in range(pp):
a = pt.tensor.set_subtensor(a[i], out[i])
return a
function_pm = pm.Deterministic('f', f(), dims=('obs_dim', 'timeFrame'))
obs = pm.Normal('obs', mu=function_pm, sigma=sigma_obs, observed=T_, dims=('obs_dim', 'timeFrame'))
with baseModel:
idatabaseModel = pm.sample()
This produce reasonable good âcalibratedâ samples of both A_
and B_
. Now, using the procedure described here, I want to use these learned samples from A_
and B_
to estimate sm_toEst
in a real run,
with pm.Model(coords=coordsNew) as predModel:
# NEW input data
NDVI_ = pm.MutableData("NDVI_", NDVI_new)
T_ = pm.MutableData("T_", T_new)
#priors
sm_toEst = pm.Uniform('sm_toEst', 0, 1, dims='timeFrame') #target variable
sigma_obs = 0.05
A_ = pm.Flat('A_')
B_ = pm.Flat('B_')
x1_new = pm.Deterministic('x1_new', A_ + B_*NDVI_, dims='timeFrame')
def f_new(x1 = x1_new, sm = sm_toEst):
out = T(x1, sm) #external complex function
pp = len(out)
a = pt.tensor.zeros((2, sm_.shape))
for i in range(pp):
a = pt.tensor.set_subtensor(a[i], out[i])
return a
# Likelihood (sampling distribution) of observations
function_pm = pm.Deterministic('f_new', f_new(), dims=('obs_dim', 'timeFrame'))
obsNew = pm.Normal('obsNew', mu=function_pm, sigma=sigma_obs, observed=T_, dims=('obs_dim', 'timeFrame'))
# as stated in the post
pp_pred = pm.sample_posterior_predictive(
idatabaseModel,
var_names=['obsNew', 'sm_toEst', 'x1_new'],
# predictions=True,
random_seed=rng,
)
The problem is that the estimated values of both sm_toEst
and obsNew
have a lot of variance. In fact, if I relearned the values of A_
and B_
while estimating sm_toEst
at the same time, the estimation is much better.
I am afraid I am not using sample_posterior_predictive
var_names
keyword correctly. But if I donât include it in the function call, the variable is not sampled. What I am doing wrong?