Add alternative default priors#360
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #360 +/- ##
==========================================
+ Coverage 88.87% 90.20% +1.33%
==========================================
Files 16 17 +1
Lines 1411 1613 +202
==========================================
+ Hits 1254 1455 +201
- Misses 157 158 +1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
…with machinery to use correlated priors
…essions in group-specific terms
|
I think this is ready for a review @aloctavodia, @canyon289, @twiecki. I know there's a lot going on in this PR and many things may not be that clear. Please ask as many questions as you want. The TL;DR of this PR would be
|
aloctavodia
left a comment
There was a problem hiding this comment.
A few small comments, overall seems good. Many small details that improve readability also some changes that I need to read with more care to understand them. I will try to keep reading tomorrow.
| sigma = pm.HalfNormal.dist(sigma=sigma, shape=rows) | ||
|
|
||
| # Obtain Cholesky factor for the covariance | ||
| lkj_decomp, corr, sigma = pm.LKJCholeskyCov( # pylint: disable=unused-variable |
There was a problem hiding this comment.
You are not using corr, right? then do :
lkj_decomp, _, sigma
There was a problem hiding this comment.
also can we use a different name for the returned sigma and the input sigma?
There was a problem hiding this comment.
I would like to use corr in the nearby future. I've been thinking we should report it even when independent priors are used. That's why it's there.
But in the meantime, I have no problem if you think the underscore is more appropriate
There was a problem hiding this comment.
And sigma... Well, they represent the same random variable in the model. The problem is the first one is a .dist, so I have to recover the one returned by lkjcholeskycov and add it to the trace.
I don't know if there are plans in pymc3 to allow a random variable in lkjcholeskycov, that would be the best solution I think
bambi/models.py
Outdated
| automatic_priors: str | ||
| An optional specification to compute/scale automatic priors. ``"default"`` means to use | ||
| Bambi's default method. ``"rstanarm"`` means to use default priors from the R rstanarm | ||
| library. The latter are available in more scenarios because they don't depend on MLE. |
There was a problem hiding this comment.
Can we detect when default Bambi priors fail and switch to rstanarm's priors?
What is the advantage of keep using Bambi defaults if they are more restricted?
There was a problem hiding this comment.
I'm going to change the defaults for the rstanarm inspired priors. This will make it simpler to implement t and beta families.
|
|
||
|
|
||
| def add_lkj(terms, eta=1): | ||
| # Parameters |
There was a problem hiding this comment.
I would make this a full comment in numpy style, that way it shows up under add_lkj.__doc__
| if self.model.family.name == "gaussian": | ||
| sigma = np.std(self.model.response.data) | ||
| self.model.response.prior.update(sigma=Prior("HalfStudentT", nu=4, sigma=sigma)) | ||
| # Add cases for other families |
There was a problem hiding this comment.
For example, the Gamma family has an auxiliary parameter alpha whose prior is HalfCauchy(beta=1). I left the comment to remember that it might be good to consider updating beta to another value based on the data, as with the sigma in the HalfStudentT prior above.
bambi/priors/scaler_mle.py
Outdated
| if self.mle is None: | ||
| self.fit_mle() | ||
|
|
||
| # Scale it |
There was a problem hiding this comment.
expand it to full name, makes comment easier to read in isolation
There was a problem hiding this comment.
What do you mean with full name? Something like self.fit_maximum_likeliihood_estimator? Or is it about the comment below?
| if set(nuisance_params).intersection(set(priors)): | ||
| return {k: priors[k] for k in nuisance_params if k in priors} | ||
| return {k: priors.pop(k) for k in nuisance_params if k in priors} | ||
| return None |
There was a problem hiding this comment.
What happens if none is returned to downstream call?
There was a problem hiding this comment.
Nothing. When None is returned it means the user didn't pass any prior for any parameter in the response distribution and there's no need to update them.
canyon289
left a comment
There was a problem hiding this comment.
Short review. Will do more indepth review in next 24 hours
Im sorry for missing this @mention. I get so many github emails things get lost. If Im not responding to a PR fast enough message me on slack, or even proactively message. That reduces chances I'll miss PRs tremendously |
Thanks for the feedback Ravin. I'll message on Slack next time then! :D |
|
I also missed more in depth review but will get it in this week :( |
|
I've just realized this PR will close #320 since we're changing default priors |
This PR aims to add alternative default priors that will be the default priors for those models where we lack statsmodels support. This new prior does not replace existing defaults (until we've evidence they're equivalent). I will be updating the following list of changes as I commit to this PR.
Changes
Model._match_derived_terms(). This was unused because categorical group-specific terms are indeed one term in the model and not several terms (as many as dummies in the encoding of the categorical variable) as it used to be before.PriorFactory._get_prior()into several methods with clearer names and goals. Also modifiedconfig.jsonas proposed in Use objects instead of arrays in the config.json of the priors #361.Prior._auto_scaleis nowPrior.auto_scale. It's bothering to add pylint exceptions all the time.PriorScaler2.Model.build()calls.Modelhas a new argument,priors_cor. It accepts dictionaries where keys are the names of the groups, and values are the eta parameter in the LKJ distribution for correlation matrices. If such a dictionary is present, priors for group-specific terms are a multivariate normal distribution with a non-zero correlation.