Object Oriented Programming with set_value

I’m hoping to take a more object oriented programming approach with PyMC3 and created a function that compiles the pymc3 model I’m interested in:

def compile_model(mean_prior, std_prior, valuesA, valuesB, nu_prior=1/29, sig_lower=1, sig_upper=10):
    '''
    Compiles two sample ttest model in PyMC3. 
    '''
    with pm.Model() as model:

        # Priors
        muA = pm.Normal('muA', mu=mean_prior, sd=std_prior*2)
        muB = pm.Normal('muB', mu=mean_prior, sd=std_prior*2)

        sigA = pm.Uniform('sigA', lower=sig_lower, upper=sig_upper)
        sigB = pm.Uniform('sigB', lower=sig_lower, upper=sig_upper)

        nu_minus_1 = pm.Exponential('nu_minus_1', nu_prior)

        obsA = pm.StudentT('obsA', mu=muA, lam=1/sigA**2, nu=nu_minus_1 +1,
                              observed=valuesA)
        obsB = pm.StudentT('obsB', mu=muB, lam=1/sigB**2, nu=nu_minus_1 +1,
                          observed=valuesB)

    return model

However, I’ve found that I can’t use anything like

valuesB.set_value(new_valuesB)

since valuesB isn’t a global variable. Is there any way to update the data inside of the model created from compile_model() such as the following:

model = compile_model()
model.valuesA.set_value(new_valuesA)

Figured out a solution by using pm.Data() and pm.set_data()

def compile_model(mean_prior, std_prior, valuesA, valuesB, nu_prior=1/29, sig_lower=1, sig_upper=10):
    with pm.Model() as model:
        vecA = pm.Data('vecA', valuesA)
        vecB = pm.Data('vecB', valuesB)

        # Priors
        muA = pm.Normal('muA', mu=mean_prior, sd=std_prior*2)
        muB = pm.Normal('muB', mu=mean_prior, sd=std_prior*2)

        sigA = pm.Uniform('sigA', lower=sig_lower, upper=sig_upper)
        sigB = pm.Uniform('sigB', lower=sig_lower, upper=sig_upper)

        nu_minus_1 = pm.Exponential('nu_minus_1', nu_prior)

        obsA = pm.StudentT('obsA', mu=muA, lam=1/sigA**2, nu=nu_minus_1 +1,
                              observed=vecA)
        obsB = pm.StudentT('obsB', mu=muB, lam=1/sigB**2, nu=nu_minus_1 +1,
                          observed=vecB)

    return model



model = compile_model(mean_prior, std_prior, valuesA, valuesB)
new_valuesA, new_valuesB = gen_data()

with model:
      pm.set_data( {'vecA':new_valuesA, 'vecB':new_valuesB} )
4 Likes