-
Notifications
You must be signed in to change notification settings - Fork 49
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
Fix support for nnet:multinom
and mclogit::mblogit
multinomial models
#469
Comments
nnet:multinom
and 'mclogit::mblogit' multinomial modelsnnet:multinom
and mclogit::mblogit
multinomial models
Thanks a lot for the investigation, I really appreciate it!
|
Hi Vincent,
|
Thanks a lot for this! It's the start of semester for me, so things are especially busy, but I'll take a serious look at this as soon as I find time. Just to be clear on copyright issues, is any of this code lifted or "strongly inspired" by emmeans? The license is permissive, so it's not a problem, but I still need to take steps if that's the case. |
Hi Vincent! No worries - I know the feeling! :-) And no, nothing lifted from
I have to ask Russ Lenth how that works exactly... But I get the same result as with Only that last bit I mentioned was in
|
I re-read all this, and I'm not sure what the feature request is for |
Ha thanks! For
When using |
Got it. And what's the scientific case for these? Naively, my intuition is they the standard errors don't get the nice properties because we first estimated them on the response scale. And then we get something that is less natural to interpret than probabilities... |
Well I would like my emmeans to be calculated on the link / latent scale (where standard errors and confidence intervals would be symmetrical) and then have these backtransformed to the response / probability scale. Which is why I thought I would have to use EDIT: tried out your
|
For your last use case, a loop might be the only way to achieve this currently, but it is quite easy: library(nnet)
library(marginaleffects)
mod <- multinom(factor(gear) ~ mpg + hp, data = mtcars, trace = FALSE)
do.call("rbind", lapply(20:30, function(i)
transform(
comparisons(
mod,
newdata = datagrid(mpg = i, model = mod),
hypothesis = "pairwise",
type = "probs",
variables = "mpg"),
mpg = i))) SoftMax is a special function because it needs to normalize by response group. The library(mclogit)
library(dplyr)
mod <- mblogit(factor(gear) ~ mpg, data = mtcars, trace = FALSE)
sm <- function(x) exp(x) / sum(exp(x))
predictions(mod, type = "link") |>
group_by(rowid) |>
mutate_at(c("predicted", "conf.low", "conf.high"), sm) |>
dplyr::filter(rowid == 1) Which is equivalent to: p1 <- predict(mod, type = "link")
softMax(p1) |> head(1) |
What you are proposing for I'll keep thinking about this, but at the moment my intuition is that There is a lot of stuff in this thread, but to recap:
Am I missing anything? |
Hi Vincent, Many thanks for all your help! Only thing I still don't fully understand for Re supporting Regarding Ha, and don't know if anything had to be done for the |
Not sure, sorry. (Trying to build tools and avoid becoming a statistical consultant. 😉) The var-cov order is not a problem. Can you try |
Not sure this was clear in my previous post, but I did implement FYI, I do not plan to include a wide output argument. Imagine a case where we have 3 outcome levels, with fitted value, standard error, CI. Then, we need all these columns: predicted_level1 The names of the columns include two pieces of information: estimate type and level, which violates the "tidy" principle that most modern R packages work with. The long format also works with split-apply-combine paradigms ( |
Closing now to clean up the repo, but feel free to comment or open a new issue if things are not working as expected or if you have other feature requests. |
So as you will recall, #404, there was still a problem with the
nnet::multinom
predict method not supportingtype="link"
, and I think there is also a problem with thennet::mblogit
predict method withtype="link"
as that one now drops the first level of the response, whereas formarginaleffects
we would like all levels to come out.A solution to solve the
nnet:multinom
predict method lacking atype="link
"predict
method could be to create a wrapper method that calls the original method. For this we would also need to create a wrappermultinom
function in themarginaleffects
package, so that the correct package namespace is found. A sketch implementation I think would be (I also give the correct link & inverse link function for multinomial below, assuming eta and mu are predictions on the link and response scale, respectively, and have the different response levels in different columns - these were currently incorrect for bothmultinom
&mblogit
) :type_dictionary
referred to insanitize_type
will still have to be modifies though to reflect that type can be"response"
(or equivalently"probs"
) or"link"
(or equivalently"latent"
).For
predict.mblogit
we also have the problem thatpredict(fit_mblogit, type="link")
drops the first category (it normalizes the logits so that that level is zero, but doesn't explicitly return it). In the context ofmarginaleffects
we would like all response levels to come out, and have the logits normalized so that they sum to one (as withtype="latent"
in theemmeans
package). To change this behaviour we would also need to change the predict behaviour of that function, perhaps using something likeThe variance-covariance function returned by
mblogit
might also need checking - Russ Lenth alerted me that that one comes out in a non-standard order (in column-major order as opposed to row-major order for the variance-covariance matrix ofnnet::multinom
fits) & inemmeans
thevcov
matrix ofmblogit
objects is returned in a permuted form, see https://github.com/rvlenth/emmeans/blob/master/R/multinom-support.R:Would it be possible to reopen this issue so that these things could be resolved, and multinomial support in
marginaleffects
could be made fully functional?Originally posted by @tomwenseleers in #404 (comment)
The text was updated successfully, but these errors were encountered: