Hello! Thank you in advance for looking into my question. I created a simple model like this:
example_data = pd.DataFrame(data = {'BMI': np.array([13.43666, 16.061496, 22.998563, 14.499094, 18.248859, 13.811637, 15.061559, 19.873758, 15.436535, 13.186676]),
'WTGAIN': np.array([20, 39, 99, 31, 47, 99, 99, 1, 34, 29]),
'M_Ht_In': np.array([12, 12.8, 12.2, 12.2, 12.8, 13.8, 12.4, 13, 12.8, 13.4]),
'CLUSTERS': np.array([3, 3, 2, 3, 3, 2, 2, 3, 3, 3]),
'DBWT': np.array([2610, 3190, 3232, 2410, 2780, 3033, 2495, 3518, 3381, 2693])})
with pm.Model() as NonHier:
# add coordinates
NonHier.add_coord("num_cols", ['BMI','WTGAIN','M_Ht_In'])
NonHier.add_coord("obs", example_data.index)
# add data containers
X = pm.MutableData("X", example_data[['BMI','WTGAIN','M_Ht_In']].values)
y = pm.MutableData("y", example_data['DBWT'].values)
# make a simple model
α = pm.Normal("α", mu=0., sigma=3.)
β = pm.Normal("β", mu=0., sigma=3., dims="num_cols")
ϵ = pm.Normal("ϵ", mu=0., sigma=3.)
μ = pyt.tensor.dot(X, β) + α
yhat = pm.Normal("yhat", mu=μ, sigma=ϵ, observed=y)
# sample
trace = pm.sample(
100,
tune=25,
chains=3,
return_inferencedata=True,
idata_kwargs={'log_likelihood':True}
)
which as you can see, uses pytensor.dot to multiply the numerical data by the betas ( which in turn, were specified to have a specific dimension). This is all well and good, but I would like to include the ‘CLUSTERS’ column, too. I would like to essentially create a ‘hyperprior’ such that the data with cluster 2 has a separate hyperprior from the data with cluster 3. I believe that I do this by creating a new dimension.
But I am having trouble extending the multi-level modeling example with .dot(). Does anyone have suggestions as to how I should proceed?
I tried something like:
example_data = pd.DataFrame(data = {'BMI': np.array([13.43666, 16.061496, 22.998563, 14.499094, 18.248859, 13.811637, 15.061559, 19.873758, 15.436535, 13.186676]),
'WTGAIN': np.array([20, 39, 99, 31, 47, 99, 99, 1, 34, 29]),
'M_Ht_In': np.array([12, 12.8, 12.2, 12.2, 12.8, 13.8, 12.4, 13, 12.8, 13.4]),
'CLUSTERS': np.array([3, 3, 2, 3, 3, 2, 2, 3, 3, 3]),
'DBWT': np.array([2610, 3190, 3232, 2410, 2780, 3033, 2495, 3518, 3381, 2693])})
cluster_index, cluster_name = pd.factorize(example_data['CLUSTERS'])
with pm.Model() as Hier:
# add coordinates
Hier.add_coord("num_cols", ['BMI','WTGAIN','M_Ht_In'])
Hier.add_coord("obs", example_data.index)
Hier.add_coord("clusters", ["cluster_3", "cluster_2"] )
# add data containers
X = pm.MutableData("X", example_data[['BMI','WTGAIN','M_Ht_In']].values)
y = pm.MutableData("y", example_data['DBWT'].values)
# hyper-prior
δ = pm.Normal("δ", mu=0., sigma=3., dims="clusters")
# priors
ϵ = pm.Normal("ϵ", mu=0., sigma=3.)
# using the hyperpior 'δ'
α = pm.Normal("α", mu=δ, sigma=3., dims=("clusters", "num_cols"))
β = pm.Normal("β", mu=δ, sigma=3., dims=("clusters", "num_cols"))
# likelihood
μ = pyt.tensor.dot(X, β[cluster_index,:]) + α[cluster_index,:]
# response
yhat = pm.Normal("yhat", mu=μ, sigma=ϵ, observed=y)
# sample
trace = pm.sample(
100,
tune=25,
chains=3,
return_inferencedata=True,
idata_kwargs={'log_likelihood':True}
)
which of course, threw a shape mis-match error. I appreciate the help!