# Stochastic node from a trace - or sharing params across models

Hi,

I’m trying to use the posterior of some parameters, \theta_1, from one model, \rm M_1, as stochastic variables in another model, \rm M_2, but not to update these \theta_1 parameters in the second model (which will be used to train some other parameters, \theta_2).

I found this thread: Prevent prior from updating?
which creates a ‘stochastic node’ in theano, but I’m wondering if this can be extended beyond univariate, parametric as shown in the example? My \theta_1 are a small array of params with some correlation between each other and not completely normally distributed.

Ideally, there would be some way to sample from some multi-variate kde of these variables in my second model (maybe borrowing from: Prior propagation by nonparametric copulas), but as a backup, I could try to see if a MvNormal parameterization describes the posteriors well. In either case, I need some way of sampling these as multi-variate, stochastic nodes in \rm M_2, which are not inferred params in \rm M_2.

Some pseudo-code to describe what I’m trying to do:

import pymc3 as pm

# Dataset 1
X = some data
Y = some data
# Dataset 2
W = some data
Z = some data

with pm.Model() as Model_1:
# define priors
theta_1 = pm.Normal('theta_1', mu=0, sigma=1, shape=6)
err = pm.HalfNormal('err', sigma=1)

# expectation function
expect = f(theta_1, X)

# likelihood function
y_like = pm.Normal('y_like', mu=expect, sigma=err, observed=Y)

trace = pm.sample(1000)

with pm.Model() as Model_2:
# define priors
theta_2 = pm.Normal('theta_1', mu=0, sigma=1, shape=2)
err_2 = pm.HalfNormal('err_2', sigma=1)

# expectation function
expect_2 = g(trace['theta_1'], theta_2, W)

# likelihood function
z_like = pm.Normal('z_like', mu=expect_2, sigma=err_2, observed=Z)

trace_2 = pm.sample(1000)


To head this question off, I don’t want to combine the two models for two reasons:

1. The params \theta_1 are useful in quite a few other models, and it becomes unwieldy to combine many models with separate purposes.
2. I believe f(\theta_1,X) in \rm M_1 to be a strong model, but g(trace[’\theta_1’], \theta_2, W), or variants thereof in other models may not be good models. I don’t want \theta_1 to be skewed by bias introduced by a poor choice of g().

Daniel

I was trying to come up with a way to sample from another distribution using the following code but I ran into an error which I’m a little perplexed by. See below if it helps it all. The general idea is to make a step function which just makes a draw from a preexisting array.

import pymc3 as pm
import numpy as np

from pymc3.step_methods.arraystep import BlockedStep
external_vals = np.random.randn(10,2) * 5 + 2

class ExternalSample(BlockedStep):
def __init__(self, external, var):
self.vars = [var]
self.name = var.name
self.external = external

def step(self, point):
row_chosen = np.random.choice(self.external.shape[0])
point[self.name] = self.external[row_chosen]
return point

with pm.Model() as model:
external_pm = pm.Normal('external', shape=2)
y = pm.Normal('y', mu=external_pm, shape=2)
step = [ExternalSample(external_vals, external_pm)]
trace = pm.sample(step=step)


Thanks - I’ll check this out. I’m also wondering what is happening under the hood when I set the observed flag of pm.Normal to True? Is this treating that variable as a stochastic node at that point?