model definition
jwdegee opened this issue · comments
I would like to fit a fully specified model. In lme I would write this as:
f = "choice ~ 1 + stimulus*reward + (1+stimulus*reward|subject_id)"`
In formulae this gives the following error:
import formulae as fm
fm.model_description(f)
891 return NotImplemented
892 else:
--> 893 raise ValueError("LHS of group specific term cannot have more than one term.")
894
895 def __repr__(self):
The following does seem to work:
f = "choice ~ 1 + stimulus*reward + (1|subject_id) + (stimulus|subject_id) + (reward|subject_id) + (stimulus:reward|subject_id)"
fm.model_description(f)
Is this the syntax for a fully specified model in formulae? Output:
ModelTerms(
ResponseTerm(
Term(
name= choice
variable= choice
kind= None
)
),
InterceptTerm(),
Term(
name= stimulus
variable= stimulus
kind= None
),
Term(
name= reward
variable= reward
kind= None
),
InteractionTerm(
name= stimulus:reward
variables= {'stimulus', 'reward'}
),
GroupSpecTerm(
expr= InterceptTerm(),
factor= Term(
name= subject_id
variable= subject_id
kind= None
)
),
GroupSpecTerm(
expr= Term(
name= stimulus
variable= stimulus
kind= None
),
factor= Term(
name= subject_id
variable= subject_id
kind= None
)
),
GroupSpecTerm(
expr= Term(
name= reward
variable= reward
kind= None
),
factor= Term(
name= subject_id
variable= subject_id
kind= None
)
),
GroupSpecTerm(
expr= InteractionTerm(
name= stimulus:reward
variables= {'stimulus', 'reward'}
),
factor= Term(
name= subject_id
variable= subject_id
kind= None
)
)
)
Ah, fitting the model does not work and gives:
formula = "choice ~ 1 + stimulus*reward + (1|subject_id) + (stimulus|subject_id) + (reward|subject_id) + (stimulus:reward|subject_id)"
model_fitted = model.fit(formula=formula, family="bernoulli", draws=2000, target_accept=0.8)
676 string += f"{self.expr.name}|"
677 else:
--> 678 raise ValueError("Invalid LHS expression for group specific term")
679
680 if isinstance(self.factor, Term):
ValueError: Invalid LHS expression for group specific term
Hi @jwdegee, thanks for opening this issue!
This problem should be partially solved if you install it from master branch now. The following example works on my computer
import bambi as bmb
import numpy as np
import pandas as pd
np.random.seed(1234)
data = pd.DataFrame({
"choice": np.random.normal(size=20),
"stimulus": np.concatenate(
(
np.repeat("A", 5),
np.repeat("B", 5),
np.repeat("A", 5),
np.repeat("B", 5),
)
),
"reward": np.concatenate(
(
np.repeat("A", 5),
np.repeat("A", 5),
np.repeat("B", 5),
np.repeat("B", 5),
)
),
"subject_id": np.arange(20)
})
f = "choice ~ stimulus * reward + (stimulus|subject_id) + (reward|subject_id) + (stimulus:reward|subject_id)"
model = bmb.Model(data)
fitted = model.fit(f)
Just note that it is not necessary to add the "1"
before the common and group-specific terms since the intercept is added by default.
It is still not possible to use the *
operator within group-specific terms, that's why I had to write the three terms separately. I'm going to track that issue in #11.
Just let me know if you need more help with this :)
This should work with f = "choice ~ stimulus * reward + (stimulus*reward|subject_id)"
now since #12.
Please feel free to let me know if you have any problems with this on your side 👍
That works! Thanks for the super fast fix and amazing package!
@jwdegee you may want to reinstall either from master or pip. I've found some bugs with the encoding when using categoric group-specific terms and they are fixed now.
ok will do thanks!