Hi all!
I have a problem where I want to make a simple linear regression involving two fish body measurements (y \sim a+b*x). There are two fish species (first level) and three factors with two groups each: sex, season, and maturity stage. I want to estimate the parameters for each species (first level) and for each group within each species, i.e., for each sex, season, and maturity stage; that is, something like this:
species level: \alpha_s and \beta_s
sex: \alpha_{s, female}, \alpha_{s, male}, \beta_{s, female}, \beta_{s, male}
season: \alpha_{s, season1}, \alpha_{s, season2}, \beta_{s, season1}, \beta_{s, season2}
maturity: \alpha_{s, immature}, \alpha_{s, mature}, \beta_{s, immature}, \beta_{s, mature}
Where s is the species.
A minimal model for one factor is straightforward:
coords = {'Parameter': ['a', 'b'],
'Species': ['Sp1', 'Sp2'],
'Season': ['Season1', 'Season2'}
with pm.Model(coords = coords) as season_model:
# shared priors
pars = pm.Normal('B', mu = 0, sigma = 1,
dims = ('Parameter', 'Species'))
eps = pm.Exponential('e', lam = 2, dims = 'Species')
# group priors
a_season = pm.Normal('a_season', mu = pars[0], sigma = 1,
dims = ('Species', 'Season'))
b_season = pm.Normal('b_season', mu = pars[1], sigma = 1,
dims = ('Species', 'Season'))
# linear model
lm = a_season[sp_id, season_id] + beta_season[sp_id, season_id]*x
# likelihood
y_pred = pm.Normal('y_pred',
mu = lm,
sigma = eps[sp_id],
observed = y)
Which yields the desired parameters:
a[sp1]
a[sp2]
a[sp1, season1]
a[sp2, season2]
b[sp1]
...
Note that, for this problem, I’m not interested in getting parameters like a[sp1, season1, female, mature]
.
I’m assuming that extending the model to include the other factors requires either working with the indices or some form of matrix multiplication; however, I have not found a way other than (quite suboptimally) constructing three separate hierarchical models for the factor-level parameters (one for each factor) and another for the species.
Any suggestions will be appreciated.