-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
turing_model part 1: fixed-effects #17
Conversation
But the drawbacks from Artifacts are negligible. It could be something like
It's easier than it looks: https://pkgdocs.julialang.org/v1/artifacts/. It clutters the diff less, makes switching to a newer version of the dataset easier, you even have to handle paths slightly less yourself because you can just say |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes nice stuff 💯
src/turing_model.jl
Outdated
@model function normal_model( | ||
y, | ||
X; | ||
predictors=size(X, 2), | ||
μ_X=μ_X, | ||
σ_X=σ_X, | ||
prior=custom_prior, | ||
residual=1 / std(y), | ||
) | ||
α ~ prior.intercept | ||
β ~ filldist(prior.predictors, predictors) | ||
σ ~ Exponential(residual) | ||
y ~ MvNormal(α .+ X * β, σ^2 * I) | ||
return (; α, β, σ, y) | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this closure be moved into a separate function? It's very difficult to read now whether it's a function call or function definition. E.g.
function construct_normal_model(y, X, predictors, ...)
return @model function normal_model(
...
end
end
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Besides that, it might also be interesting to be able to access the model definition from outside for other purposes. I don't know how realistic that is, but e.g., to allow people to just look at and work with the interiors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes! I was thinking in a turing_code
function to return or print the Turing underlying Turing code.
I think that we can also have that function to be the main one. turing_model
would just call turing_code
and eval the string as a macro. Is that possible?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, ideally that would work in DPPL itself. We have been thinking about adding the original expression to the model struct and use it for printing, which would be pretty minor change but just hasn't been considered to be of high urgency.
However, this will then only work on the instantiated model object, not the result of the @model
itself, which after all is just a bunch of method definitions of the model evaluator function.
I wouldn't do eval within the function. If necessary, you could have a top-level dict of names to code and evaluate those on the top level, but I don't really see the advantage.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I will try to work on something during the week. This week is nasty because there are a lot of final committees and also tons of final semester assessments to grade. But it is the final week of the academic semester for me. I will add the turing_code
suggestion in the comment down below /
src/turing_model.jl
Outdated
@model function student_model( | ||
y, | ||
X; | ||
predictors=size(X, 2), | ||
μ_X=μ_X, | ||
σ_X=σ_X, | ||
prior=custom_prior, | ||
residual=1 / std(y), | ||
) | ||
α ~ prior.intercept | ||
β ~ filldist(prior.predictors, predictors) | ||
σ ~ Exponential(residual) | ||
ν ~ prior.auxiliary | ||
y ~ arraydist(LocationScale.(α .+ X * β, σ, TDist.(ν))) | ||
return (; α, β, σ, ν, y) | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above. With more than 120 lines, this method is too long to be easily readable
Co-authored-by: Rik Huijzer <[email protected]>
Things to do:
|
Ready to review again. I could not implement easily The whole |
Ok, this is a big PR. 50% of the package was done in this PR.
Mainly it implements everything for specifying and sampling models using
@formula
macro that do not have random-effects, i.e. the(1 | group)
,(x1 | group)
or(1 + x1 | group)
terms inside the@formula
.Implemented likelihoods:
Datasets in
data/
I am also adding 3 datasets from
stan-dev/rstanarm
:kidiq
wells
roaches
Their license is GPL-3. They are used extensively in tutorials(see
storopoli/Bayesian-Julia
and also Gelman & Hill (2007), Gelman et al. (2013) (the BDA), Gelman et al. (2020) (RoS).I know that @rikhuijzer hates data being hard-coded into a package but they are very small and are used for tests and tutorials (not implement yet, but in the roadmap)
Relates to #2.
@yebai feel free to review or ask for others to review.