-
-
Notifications
You must be signed in to change notification settings - Fork 125
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
Design how we're going to extend Bambi #544
Comments
Imo I think non linear models given its effort should be lowest priority |
I agree. It would be a lot of work without knowing if it will work. |
One route to nonlinear models (and perhaps some of the other items on your exciting list) would be to make a "transcompiler" similar to the request in #539 ; I could imagine using this in an exploratory research workflow to start with a linear model, generate python code for it, and then iteratively modifying the autogenerated code to include nonlinear elements. |
I wonder if defining the non-linear function in Aesara could help us to get the necessary information in a general way (@ricardoV94, @rlouf). |
You can definitely analyze any |
Other than the technical implementation frankly I dont think itll be all that usefull and theres not a huge userbase for it. If people want non linear models they can just use PyMC to code those up. The other use cases imo are much easier to implement in Bambi and will have a wider userbase. |
I like your proposed API for censored data. Very clean. |
I have new ideas for distributional models Instead of this formula = bmb.formula(
"y ~ a + b",
"sigma ~ a",
)
priors = {
"a": bmb.Prior("Normal", mu=0, sigma=1),
"b": bmb.Prior("Normal", mu=0, sigma=1),
"sigma_Intercept": bmb.Prior("Normal", mu=0, sigma=1),
"sigma_x": bmb.Prior("Normal", mu=0, sigma=1)
}
link = {"mu": "identity", "sigma": "log"}
model = bmb.Model(formula, data, priors, link) have this (notice the priors) formula = bmb.formula(
"y ~ a + b",
"sigma ~ a",
)
priors = {
"y": {
"a": bmb.Prior("Normal", mu=0, sigma=1),
"b": bmb.Prior("Normal", mu=0, sigma=1),
},
"sigma": {
"Intercept": bmb.Prior("Normal", mu=0, sigma=1),
"a": bmb.Prior("Normal", mu=0, sigma=1)
}
}
link = {"mu": "identity", "sigma": "log"}
model = bmb.Model(formula, data, priors, link) It adds more structure and prevents us from having to parse strings to decide to which response the prior corresponds to. Also, This does open new questions though. For example
|
Nice. I like that structure - very clear. Distributional models are a very
cool addition!
…On Sat, Oct 22, 2022 at 15:08 Tomás Capretto ***@***.***> wrote:
I have new ideas for *distributional models*
Instead of this
formula = bmb.formula(
"y ~ a + b",
"sigma ~ a",
)priors = {
"a": bmb.Prior("Normal", mu=0, sigma=1),
"b": bmb.Prior("Normal", mu=0, sigma=1),
"sigma_Intercept": bmb.Prior("Normal", mu=0, sigma=1),
"sigma_x": bmb.Prior("Normal", mu=0, sigma=1)
}link = {"mu": "identity", "sigma": "log"}model = bmb.Model(formula, data, priors, link)
have *this* (notice the priors)
formula = bmb.formula(
"y ~ a + b",
"sigma ~ a",
)priors = {
"y": {
"a": bmb.Prior("Normal", mu=0, sigma=1),
"b": bmb.Prior("Normal", mu=0, sigma=1),
},
"sigma": {
"Intercept": bmb.Prior("Normal", mu=0, sigma=1),
"a": bmb.Prior("Normal", mu=0, sigma=1)
}
}link = {"mu": "identity", "sigma": "log"}model = bmb.Model(formula, data, priors, link)
It adds more structure and prevents us from having to parse strings to
decide to which response the prior corresponds to. Also, "_" is very
common in variable names, so it's highly likely we get it wrong.
—
Reply to this email directly, view it on GitHub
<#544 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AH3QQVY2LAPXLAPSQZY5YBLWEQ3SZANCNFSM53HNB7OQ>
.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***>
|
I would like to chime in on the nonlinear models front. At least for people in my research field this would be a very welcome feature. Computational cognitive models are often nonlinear (and sometimes distributional). Popular examples of the latter are things like drift diffusion models, but I most commonly work with univariate psychometric functions of the form where While it's true that one can build these models by hand in PyMC, the convenience of a wrapper package like I've previously used
The
Please let me know if this would be of further interest. |
@tomwallis first of all thanks a lot for chiming in! We're really close to having distributional models! I need some extra time to polish the details #607 and then we're done :) For the non-linear part, I still anticipate non-trivial problems. I'm not saying it's impossible at all though. I'm already aware of the syntax to specify non-linear parameters in For example, let's say we have the expression But anyway, thanks a lot for your input, I'm really happy to see there are more people interested in this feature. I will be pinging you when I start working on it if you want :) |
To get nonlinear terms working I think we need to do the following
|
Thanks @tomicapretto for your positive reply! Yes, please ping me back when you start to invest time. |
These look like nice features indeed! If you have any questions about brms' internal structure and procedures of representing some of the more advanced models, please let me know. |
@paul-buerkner definitely I would love it! How would you prefer to do it? I could...
I think that for specific technical questions an issue may be a good alternative (since it's also public). But if at some point the conversation turns to other broader topics such as design choices, we could have a meeting. What do you think? |
Opening issues here in the bambi repo and tagging me sounds good. And I agree we can have a meeting at some point if we feel it could be useful. |
@paul-buerkner here's my first question :) What's the difference between a "Distributional model" and a "GAMLSS" (Generalized additive model for location, scale and shape? I took the name "Distributional models" from brms. But as far as I understand they are very close to GAMLSS, perhaps the difference is in the GAM part, and the distributional model doesn't necessarily imply GAMs? Or is there another more significant difference? Thanks! |
the two terms mean in essence the same in practical use but the term
distributional models is somewhat more general. brms' distributional models
can do more flexible stuff that "just" GAMs for multiple distributional
parameters (e.g., explicit nonlinear models) hence I prefer that term.
Tomás Capretto ***@***.***> schrieb am Do., 5. Jan. 2023,
19:47:
… @paul-buerkner <https://github.com/paul-buerkner> here's my first
question :)
What's the difference between a "Distributional model" and a "GAMLSS"
(Generalized additive model for location, scale and shape? I took the name
"Distributional models" from brms. But as far as I understand they are very
close to GAMLSS, perhaps the difference is in the GAM part, and the
distributional model doesn't necessarily imply GAMs? Or is there another
more significant difference?
Thanks!
—
Reply to this email directly, view it on GitHub
<#544 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ADCW2ACQXPCXD5MRYRZYTG3WQ4JLLANCNFSM53HNB7OQ>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
Regarding naming conventions for terms in distributional models, someone pointed me via e-mail that {param}__{term} may be a better alternative than {param}_{term}. I'm citing the arguments: "It might sound negligible but having it as a convention can be very powerful in the future. My position for the moment is "I understand the point, and while I don't have a strong opinion about the existing solution, I don't see it as a very large problem either.". I share the small chat here so anyone can share their thoughts |
1 similar comment
Regarding naming conventions for terms in distributional models, someone pointed me via e-mail that {param}__{term} may be a better alternative than {param}_{term}. I'm citing the arguments: "It might sound negligible but having it as a convention can be very powerful in the future. My position for the moment is "I understand the point, and while I don't have a strong opinion about the existing solution, I don't see it as a very large problem either.". I share the small chat here so anyone can share their thoughts |
@paul-buerkner I have some extra questions, now about GAMs :) Let's take the following example library(brms)
pisa <- readr::read_csv("https://raw.githubusercontent.com/m-clark/generalized-additive-models/master/data/pisasci2006.csv")
code <- make_stancode(Overall ~ 1 + s(Income, bs = "cr"), data = pisa)
data <- make_standata(Overall ~ 1 + s(Income, bs = "cr"), data = pisa)
brm_gam <- brm(Overall ~ 1 + s(Income, bs = "cr"), data = pisa)
mgcv_gam <- mgcv::gam(Overall ~ 1 + s(Income, bs = "cr"), data = pisa) Below, the summaries of
The Stan code produced is // generated with brms 2.18.0
functions {
}
data {
int<lower=1> N; // total number of observations
vector[N] Y; // response variable
// data for splines
int Ks; // number of linear effects
matrix[N, Ks] Xs; // design matrix for the linear effects
// data for spline s(Income, bs = "cr")
int nb_1; // number of bases
int knots_1[nb_1]; // number of knots
// basis function matrices
matrix[N, knots_1[1]] Zs_1_1;
int prior_only; // should the likelihood be ignored?
}
transformed data {
}
parameters {
real Intercept; // temporary intercept for centered predictors
vector[Ks] bs; // spline coefficients
// parameters for spline s(Income, bs = "cr")
// standarized spline coefficients
vector[knots_1[1]] zs_1_1;
real<lower=0> sds_1_1; // standard deviations of spline coefficients
real<lower=0> sigma; // dispersion parameter
}
transformed parameters {
// actual spline coefficients
vector[knots_1[1]] s_1_1;
real lprior = 0; // prior contributions to the log posterior
// compute actual spline coefficients
s_1_1 = sds_1_1 * zs_1_1;
lprior += student_t_lpdf(Intercept | 3, 488, 50.4);
lprior += student_t_lpdf(sds_1_1 | 3, 0, 50.4)
- 1 * student_t_lccdf(0 | 3, 0, 50.4);
lprior += student_t_lpdf(sigma | 3, 0, 50.4)
- 1 * student_t_lccdf(0 | 3, 0, 50.4);
}
model {
// likelihood including constants
if (!prior_only) {
// initialize linear predictor term
vector[N] mu = rep_vector(0.0, N);
mu += Intercept + Xs * bs + Zs_1_1 * s_1_1;
target += normal_lpdf(Y | mu, sigma);
}
// priors including constants
target += lprior;
target += std_normal_lpdf(zs_1_1);
}
generated quantities {
// actual population-level intercept
real b_Intercept = Intercept;
} I would like to check the following
Again, thanks a lot for brms and your help! |
The following is a list of features we're missing (or covering only partially) in Bambi
The last three points (survival/censored, ordinal, and zero/zero-one inflated) are covered by the first points (distributional and multivariate) if we implement them appropriately. The third point, non-linear models, is a separate problem. I'll try to add a couple of things I've been thinking about lately.
Distributional models
Some API proposals
bmb.formula()
. There's an open discussion in Add Bambi formula object #423.{param}_{term}
such assigma_x
.link
argument inModel
now.I haven't thought much more about the implementation details, where other concerns may appear. For the moment, I think it's good to discuss about the API we want. Any objections, any suggestions, any drawbacks I'm not seeing?
Multivariate models
We currently support some multivariate families, such as
"categorical"
and"multinomial"
. I feel we should think more about the implementation. I think we could make it more general so we don't need to handle all cases as special cases. With that said, I think there are other things to discuss.note the last alternative allows for different predictors to be included in each case.
I'm not an expert in this area but I have the feeling that things can get very complex very quickly. And I'm not sure if this is a highly required feature.
For now, I tend to think we should have minimum support that allows people and us to explore the possibilities available as well as refine the API.
Non-linear models
This has been discussed a little here #448. I think it's a very nice to have feature but I don't have it solved in my mind yet. The only thing I have are some API proposals, but I don't see how to implement them without a huge effort.
First:
But this comes with a major problem, how do we override the meaning of the
*
operator in the formula syntax? If we pass something like that to formulae, it won't multiply things byb1
orb2
, it will try to construct full interaction terms between the operands. I like how this approach looks but it would require a huge amount of effort to parse terms and parameters.Another alternative would be to use a function.
This would work on the formulae side, but again we would need to do parsing stuff to grab the non-linear relationship between the parameters (
b1
andb2
) and the predictorx
. How do we handle arbitrarily complex functions? I'm not sure.Survival models/Models with censored data.
#543 adds support for survival analysis with right-censored data. One drawback of the proposal is that
family="exponential"
always implies right-censored data. I think we should have something more general.I imagine all the following cases working
The challenge is that
censored()
should be a function that returns an array-like structure (soformulae
knows how to handle it) with some attribute that enables Bambi to figure out the characteristics of the censoring. I'm not sure how to implement this but I know it's feasible.Ordinal models and Zero and Zero-One inflated models.
I think these ones come almost for free if we do a good job with the tasks above.
The text was updated successfully, but these errors were encountered: