From 20d5ba412f5897f7b88e2bb3d160ab6e7a8bb64d Mon Sep 17 00:00:00 2001 From: Max Kuhn Date: Mon, 10 May 2021 21:02:22 -0400 Subject: [PATCH 1/8] prototype of changes for #431 --- R/linear_reg.R | 15 ++++++++++++--- man/linear_reg.Rd | 37 ++++++++++++++++++++++++++++--------- man/rmd/linear-reg.Rmd | 28 ++++++++++++++++++++-------- 3 files changed, 60 insertions(+), 20 deletions(-) diff --git a/R/linear_reg.R b/R/linear_reg.R index f3137ef19..7f268a8fb 100644 --- a/R/linear_reg.R +++ b/R/linear_reg.R @@ -107,13 +107,22 @@ translate.linear_reg <- function(x, engine = x$engine, ...) { x <- translate.default(x, engine, ...) if (engine == "glmnet") { - # See discussion in https://github.com/tidymodels/parsnip/issues/195 - x$method$fit$args$lambda <- NULL + if (any(names(x$eng_args) == "path_values")) { + # Since we decouple the parsnip `penalty` argument from being the same + # as the glmnet `lambda` value, this allows users to set the path + # differently from the default that glmnet uses. See + # https://github.com/tidymodels/parsnip/issues/431 + x$method$fit$args$lambda <- x$eng_args$path_values + x$eng_args$path_values <- NULL + x$method$fit$args$path_values <- NULL + } else { + # See discussion in https://github.com/tidymodels/parsnip/issues/195 + x$method$fit$args$lambda <- NULL + } # Since the `fit` information is gone for the penalty, we need to have an # evaluated value for the parameter. x$args$penalty <- rlang::eval_tidy(x$args$penalty) } - x } diff --git a/man/linear_reg.Rd b/man/linear_reg.Rd index 53057d647..41c7f6546 100644 --- a/man/linear_reg.Rd +++ b/man/linear_reg.Rd @@ -99,15 +99,34 @@ call. For this type of model, the template of the fit calls are below. ## family = "gaussian") } -For \code{glmnet} models, the full regularization path is always fit -regardless of the value given to \code{penalty}. Also, there is the option to -pass multiple values (or no values) to the \code{penalty} argument. When -using the \code{predict()} method in these cases, the return value depends on -the value of \code{penalty}. When using \code{predict()}, only a single value of -the penalty can be used. When predicting on multiple penalties, the -\code{multi_predict()} function can be used. It returns a tibble with a list -column called \code{.pred} that contains a tibble with all of the penalty -results. +\code{linear_reg()} requires a single value for the \code{penalty} argument (a +number or \code{tune()}). Despite this, the full regularization path is +always fit regardless of the value given to \code{penalty}. To pass in a +custom sequence of values for \code{lambda}, use the argument \code{path_values} +in \code{set_engine()}. This will assign the value of the glmnet \code{lambda} +parameter without disturbing the value given in \code{linear_reg(penalty)}. +For example:\if{html}{\out{
}}\preformatted{linear_reg(penalty = .1) \%>\% + set_engine("glmnet", path_values = c(0, 10^seq(-10, 1, length.out = 20))) \%>\% + set_mode("regression") \%>\% + translate() +}\if{html}{\out{
}}\preformatted{## Linear Regression Model Specification (regression) +## +## Main Arguments: +## penalty = 0.1 +## +## Computational engine: glmnet +## +## Model fit template: +## glmnet::glmnet(x = missing_arg(), y = missing_arg(), weights = missing_arg(), +## lambda = c(0, 10^seq(-10, 1, length.out = 20)), family = "gaussian") +} + +When using \code{predict()}, the single penalty value used for prediction is +the one given to \code{linear_reg()}. + +To predict on multiple penalties, the \code{multi_predict()} function can be +used. It returns a tibble with a list column called \code{.pred} that +contains a tibble with all of the penalty results. } \subsection{stan}{\if{html}{\out{
}}\preformatted{linear_reg() \%>\% diff --git a/man/rmd/linear-reg.Rmd b/man/rmd/linear-reg.Rmd index 03f1da44e..67f1cb5a0 100644 --- a/man/rmd/linear-reg.Rmd +++ b/man/rmd/linear-reg.Rmd @@ -23,14 +23,26 @@ linear_reg() %>% translate() ``` -For `glmnet` models, the full regularization path is always fit regardless of the -value given to `penalty`. Also, there is the option to pass multiple values (or -no values) to the `penalty` argument. When using the `predict()` method in these -cases, the return value depends on the value of `penalty`. When using -`predict()`, only a single value of the penalty can be used. When predicting on -multiple penalties, the `multi_predict()` function can be used. It returns a -tibble with a list column called `.pred` that contains a tibble with all of the -penalty results. +`linear_reg()` requires a single value for the `penalty` argument (a number +or `tune()`). Despite this, the full regularization path is always fit +regardless of the value given to `penalty`. To pass in a custom sequence of +values for `lambda`, use the argument `path_values` in `set_engine()`. This +will assign the value of the glmnet `lambda` parameter without disturbing +the value given in `linear_reg(penalty)`. For example: + +```{r glmnet-path} +linear_reg(penalty = .1) %>% + set_engine("glmnet", path_values = c(0, 10^seq(-10, 1, length.out = 20))) %>% + set_mode("regression") %>% + translate() +``` + +When using `predict()`, the single penalty value used for prediction is the one +given to `linear_reg()`. + +To predict on multiple penalties, the `multi_predict()` function can be used. +It returns a tibble with a list column called `.pred` that contains a tibble +with all of the penalty results. ## stan From 9ddb7ac96834397ac7ab00adb6091af94047923b Mon Sep 17 00:00:00 2001 From: Max Kuhn Date: Tue, 11 May 2021 13:02:06 -0400 Subject: [PATCH 2/8] further changes for #431 --- NEWS.md | 18 ++++++++++--- R/logistic_reg.R | 20 +++++++++----- R/multinom_reg.R | 23 +++++++++++++++- man/contr_one_hot.Rd | 10 ++++--- man/linear_reg.Rd | 7 +++-- man/logistic_reg.Rd | 42 +++++++++++++++++++++++------- man/multinom_reg.Rd | 42 +++++++++++++++++++++++------- man/rmd/linear-reg.Rmd | 6 +++-- man/rmd/logistic-reg.Rmd | 32 ++++++++++++++++------- man/rmd/multinom-reg.Rmd | 32 ++++++++++++++++------- tests/testthat/test_linear_reg.R | 13 +++++++++ tests/testthat/test_logistic_reg.R | 19 +++++++++++--- tests/testthat/test_multinom_reg.R | 13 +++++++++ 13 files changed, 217 insertions(+), 60 deletions(-) diff --git a/NEWS.md b/NEWS.md index 4dcde5106..3ed053f79 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,21 +1,33 @@ # parsnip (development version) -* `generics::required_pkgs()` was extended for `parsnip` objects. - -* The `liquidSVM` engine for `svm_rbf()` was deprecated due to that package's removal from CRAN. (#425) +## Model Specification Changes * A new linear SVM model `svm_linear()` is now available with the `LiblineaR` engine (#424) and the `kernlab` engine (#438), and the `LiblineaR` engine is available for `logistic_reg()` as well (#429). These models can use sparse matrices via `fit_xy()` (#447) and have a `tidy` method (#474). +* For models with `glmnet` engines: + + - A single value is required for `penalty` (either a single numeric value or a value of `tune()`) (#481) + - A special argument called `path_values` can be used to set the `lambda` path is a specific set of numbers (independent of the value of `penalty`). A pure ridge regression models (i.e., `mixture = 1`) will generate incorrect values if the path does not include zero. See issue #431. + +* The `liquidSVM` engine for `svm_rbf()` was deprecated due to that package's removal from CRAN. (#425) + * New model specification `survival_reg()` for the new mode `"censored regression"` (#444). `surv_reg()` is now soft-deprecated (#448). * New model specification `proportional_hazards()` for the `"censored regression"` mode (#451). +## Other Changes + * Re-licensed package from GPL-2 to MIT. See [consent from copyright holders here](https://github.com/tidymodels/parsnip/issues/462). * `set_mode()` now checks if `mode` is compatible with the model class, similar to `new_model_spec()` (@jtlandis, #467). * Re-organized model documentation for `update` methods (#479). + + +* `generics::required_pkgs()` was extended for `parsnip` objects. + + # parsnip 0.1.5 diff --git a/R/logistic_reg.R b/R/logistic_reg.R index 4d7b2d3ab..57805661b 100644 --- a/R/logistic_reg.R +++ b/R/logistic_reg.R @@ -108,10 +108,19 @@ translate.logistic_reg <- function(x, engine = x$engine, ...) { arg_vals <- x$method$fit$args arg_names <- names(arg_vals) - if (engine == "glmnet") { - # See discussion in https://github.com/tidymodels/parsnip/issues/195 - arg_vals$lambda <- NULL + if (any(names(x$eng_args) == "path_values")) { + # Since we decouple the parsnip `penalty` argument from being the same + # as the glmnet `lambda` value, this allows users to set the path + # differently from the default that glmnet uses. See + # https://github.com/tidymodels/parsnip/issues/431 + x$method$fit$args$lambda <- x$eng_args$path_values + x$eng_args$path_values <- NULL + x$method$fit$args$path_values <- NULL + } else { + # See discussion in https://github.com/tidymodels/parsnip/issues/195 + x$method$fit$args$lambda <- NULL + } # Since the `fit` information is gone for the penalty, we need to have an # evaluated value for the parameter. x$args$penalty <- rlang::eval_tidy(x$args$penalty) @@ -133,11 +142,8 @@ translate.logistic_reg <- function(x, engine = x$engine, ...) { rlang::abort("For the LiblineaR engine, mixture must be 0 or 1.") } } - + x$method$fit$args <- arg_vals } - - x$method$fit$args <- arg_vals - x } diff --git a/R/multinom_reg.R b/R/multinom_reg.R index b799000e1..6ba4e6d26 100644 --- a/R/multinom_reg.R +++ b/R/multinom_reg.R @@ -96,7 +96,28 @@ print.multinom_reg <- function(x, ...) { } #' @export -translate.multinom_reg <- translate.linear_reg +translate.multinom_reg <- function(x, engine = x$engine, ...) { + x <- translate.default(x, engine, ...) + + if (engine == "glmnet") { + if (any(names(x$eng_args) == "path_values")) { + # Since we decouple the parsnip `penalty` argument from being the same + # as the glmnet `lambda` value, this allows users to set the path + # differently from the default that glmnet uses. See + # https://github.com/tidymodels/parsnip/issues/431 + x$method$fit$args$lambda <- x$eng_args$path_values + x$eng_args$path_values <- NULL + x$method$fit$args$path_values <- NULL + } else { + # See discussion in https://github.com/tidymodels/parsnip/issues/195 + x$method$fit$args$lambda <- NULL + } + # Since the `fit` information is gone for the penalty, we need to have an + # evaluated value for the parameter. + x$args$penalty <- rlang::eval_tidy(x$args$penalty) + } + x +} # ------------------------------------------------------------------------------ diff --git a/man/contr_one_hot.Rd b/man/contr_one_hot.Rd index df945bebd..a8c21d593 100644 --- a/man/contr_one_hot.Rd +++ b/man/contr_one_hot.Rd @@ -39,14 +39,16 @@ levels(penguins$species) }\if{html}{\out{
}}\preformatted{## [1] "Biscoe" "Dream" "Torgersen" }\if{html}{\out{
}}\preformatted{model.matrix(~ species + island, data = penguins) \%>\% colnames() -}\if{html}{\out{
}}\preformatted{## [1] "(Intercept)" "speciesChinstrap" "speciesGentoo" "islandDream" "islandTorgersen" +}\if{html}{\out{}}\preformatted{## [1] "(Intercept)" "speciesChinstrap" "speciesGentoo" "islandDream" +## [5] "islandTorgersen" } For a formula with no intercept, the first factor is expanded to indicators for \emph{all} factor levels but all other factors are expanded to all but one (as above):\if{html}{\out{
}}\preformatted{model.matrix(~ 0 + species + island, data = penguins) \%>\% colnames() -}\if{html}{\out{
}}\preformatted{## [1] "speciesAdelie" "speciesChinstrap" "speciesGentoo" "islandDream" "islandTorgersen" +}\if{html}{\out{}}\preformatted{## [1] "speciesAdelie" "speciesChinstrap" "speciesGentoo" "islandDream" +## [5] "islandTorgersen" } For inference, this hybrid encoding can be problematic. @@ -59,8 +61,8 @@ options(contrasts = new_contr) model.matrix(~ species + island, data = penguins) \%>\% colnames() -}\if{html}{\out{}}\preformatted{## [1] "(Intercept)" "speciesAdelie" "speciesChinstrap" "speciesGentoo" "islandBiscoe" -## [6] "islandDream" "islandTorgersen" +}\if{html}{\out{}}\preformatted{## [1] "(Intercept)" "speciesAdelie" "speciesChinstrap" "speciesGentoo" +## [5] "islandBiscoe" "islandDream" "islandTorgersen" }\if{html}{\out{
}}\preformatted{options(contrasts = old_contr) }\if{html}{\out{
}} diff --git a/man/linear_reg.Rd b/man/linear_reg.Rd index 41c7f6546..e15c13470 100644 --- a/man/linear_reg.Rd +++ b/man/linear_reg.Rd @@ -107,7 +107,6 @@ in \code{set_engine()}. This will assign the value of the glmnet \code{lambda} parameter without disturbing the value given in \code{linear_reg(penalty)}. For example:\if{html}{\out{
}}\preformatted{linear_reg(penalty = .1) \%>\% set_engine("glmnet", path_values = c(0, 10^seq(-10, 1, length.out = 20))) \%>\% - set_mode("regression") \%>\% translate() }\if{html}{\out{
}}\preformatted{## Linear Regression Model Specification (regression) ## @@ -121,6 +120,11 @@ For example:\if{html}{\out{
}}\preformatted{linear_reg(penalty = . ## lambda = c(0, 10^seq(-10, 1, length.out = 20)), family = "gaussian") } +When fitting a pure ridge regression model (i.e., \code{penalty = 0}), we +\emph{strongly suggest} that you pass in a vector for \code{path_values} that +includes zero. See \href{https://github.com/tidymodels/parsnip/issues/431}{issue #431} for a +discussion. + When using \code{predict()}, the single penalty value used for prediction is the one given to \code{linear_reg()}. @@ -131,7 +135,6 @@ contains a tibble with all of the penalty results. \subsection{stan}{\if{html}{\out{
}}\preformatted{linear_reg() \%>\% set_engine("stan") \%>\% - set_mode("regression") \%>\% translate() }\if{html}{\out{
}}\preformatted{## Linear Regression Model Specification (regression) ## diff --git a/man/logistic_reg.Rd b/man/logistic_reg.Rd index fc05bb5ff..778c2032b 100644 --- a/man/logistic_reg.Rd +++ b/man/logistic_reg.Rd @@ -88,7 +88,6 @@ call. For this type of model, the template of the fit calls are below. \subsection{glmnet}{\if{html}{\out{
}}\preformatted{logistic_reg() \%>\% set_engine("glmnet") \%>\% - set_mode("classification") \%>\% translate() }\if{html}{\out{
}}\preformatted{## Logistic Regression Model Specification (classification) ## @@ -99,15 +98,38 @@ call. For this type of model, the template of the fit calls are below. ## family = "binomial") } -For \code{glmnet} models, the full regularization path is always fit -regardless of the value given to \code{penalty}. Also, there is the option to -pass multiple values (or no values) to the \code{penalty} argument. When -using the \code{predict()} method in these cases, the return value depends on -the value of \code{penalty}. When using \code{predict()}, only a single value of -the penalty can be used. When predicting on multiple penalties, the -\code{multi_predict()} function can be used. It returns a tibble with a list -column called \code{.pred} that contains a tibble with all of the penalty -results. +\code{logistic_reg()} requires a single value for the \code{penalty} argument (a +number or \code{tune()}). Despite this, the full regularization path is +always fit regardless of the value given to \code{penalty}. To pass in a +custom sequence of values for \code{lambda}, use the argument \code{path_values} +in \code{set_engine()}. This will assign the value of the glmnet \code{lambda} +parameter without disturbing the value given in \code{logistic_reg(penalty)}. +For example:\if{html}{\out{
}}\preformatted{logistic_reg(penalty = .1) \%>\% + set_engine("glmnet", path_values = c(0, 10^seq(-10, 1, length.out = 20))) \%>\% + translate() +}\if{html}{\out{
}}\preformatted{## Logistic Regression Model Specification (classification) +## +## Main Arguments: +## penalty = 0.1 +## +## Computational engine: glmnet +## +## Model fit template: +## glmnet::glmnet(x = missing_arg(), y = missing_arg(), weights = missing_arg(), +## lambda = c(0, 10^seq(-10, 1, length.out = 20)), family = "binomial") +} + +When fitting a pure ridge regression model (i.e., \code{penalty = 0}), we +\emph{strongly suggest} that you pass in a vector for \code{path_values} that +includes zero. See \href{https://github.com/tidymodels/parsnip/issues/431}{issue #431} for a +discussion. + +When using \code{predict()}, the single penalty value used for prediction is +the one given to \code{logistic_reg()}. + +To predict on multiple penalties, the \code{multi_predict()} function can be +used. It returns a tibble with a list column called \code{.pred} that +contains a tibble with all of the penalty results. } \subsection{LiblineaR}{\if{html}{\out{
}}\preformatted{logistic_reg() \%>\% diff --git a/man/multinom_reg.Rd b/man/multinom_reg.Rd index feb930900..d6b142d0d 100644 --- a/man/multinom_reg.Rd +++ b/man/multinom_reg.Rd @@ -69,7 +69,6 @@ Engines may have pre-set default arguments when executing the model fit call. For this type of model, the template of the fit calls are below. \subsection{glmnet}{\if{html}{\out{
}}\preformatted{multinom_reg() \%>\% set_engine("glmnet") \%>\% - set_mode("classification") \%>\% translate() }\if{html}{\out{
}}\preformatted{## Multinomial Regression Model Specification (classification) ## @@ -80,15 +79,38 @@ call. For this type of model, the template of the fit calls are below. ## family = "multinomial") } -For \code{glmnet} models, the full regularization path is always fit -regardless of the value given to \code{penalty}. Also, there is the option to -pass multiple values (or no values) to the \code{penalty} argument. When -using the \code{predict()} method in these cases, the return value depends on -the value of \code{penalty}. When using \code{predict()}, only a single value of -the penalty can be used. When predicting on multiple penalties, the -\code{multi_predict()} function can be used. It returns a tibble with a list -column called \code{.pred} that contains a tibble with all of the penalty -results. +\code{multinom_reg()} requires a single value for the \code{penalty} argument (a +number or \code{tune()}). Despite this, the full regularization path is +always fit regardless of the value given to \code{penalty}. To pass in a +custom sequence of values for \code{lambda}, use the argument \code{path_values} +in \code{set_engine()}. This will assign the value of the glmnet \code{lambda} +parameter without disturbing the value given in \code{multinom_reg(penalty)}. +For example:\if{html}{\out{
}}\preformatted{multinom_reg(penalty = .1) \%>\% + set_engine("glmnet", path_values = c(0, 10^seq(-10, 1, length.out = 20))) \%>\% + translate() +}\if{html}{\out{
}}\preformatted{## Multinomial Regression Model Specification (classification) +## +## Main Arguments: +## penalty = 0.1 +## +## Computational engine: glmnet +## +## Model fit template: +## glmnet::glmnet(x = missing_arg(), y = missing_arg(), weights = missing_arg(), +## lambda = c(0, 10^seq(-10, 1, length.out = 20)), family = "multinomial") +} + +When fitting a pure ridge regression model (i.e., \code{penalty = 0}), we +\emph{strongly suggest} that you pass in a vector for \code{path_values} that +includes zero. See \href{https://github.com/tidymodels/parsnip/issues/431}{issue #431} for a +discussion. + +When using \code{predict()}, the single penalty value used for prediction is +the one given to \code{multinom_reg()}. + +To predict on multiple penalties, the \code{multi_predict()} function can be +used. It returns a tibble with a list column called \code{.pred} that +contains a tibble with all of the penalty results. } \subsection{nnet}{\if{html}{\out{
}}\preformatted{multinom_reg() \%>\% diff --git a/man/rmd/linear-reg.Rmd b/man/rmd/linear-reg.Rmd index 67f1cb5a0..8f86ea011 100644 --- a/man/rmd/linear-reg.Rmd +++ b/man/rmd/linear-reg.Rmd @@ -33,10 +33,13 @@ the value given in `linear_reg(penalty)`. For example: ```{r glmnet-path} linear_reg(penalty = .1) %>% set_engine("glmnet", path_values = c(0, 10^seq(-10, 1, length.out = 20))) %>% - set_mode("regression") %>% translate() ``` +When fitting a pure ridge regression model (i.e., `penalty = 0`), we _strongly +suggest_ that you pass in a vector for `path_values` that includes zero. See +[issue #431](https://github.com/tidymodels/parsnip/issues/431) for a discussion. + When using `predict()`, the single penalty value used for prediction is the one given to `linear_reg()`. @@ -49,7 +52,6 @@ with all of the penalty results. ```{r stan-reg} linear_reg() %>% set_engine("stan") %>% - set_mode("regression") %>% translate() ``` diff --git a/man/rmd/logistic-reg.Rmd b/man/rmd/logistic-reg.Rmd index 656e24f70..a8b21e4f8 100644 --- a/man/rmd/logistic-reg.Rmd +++ b/man/rmd/logistic-reg.Rmd @@ -20,18 +20,32 @@ logistic_reg() %>% ```{r glmnet-csl} logistic_reg() %>% set_engine("glmnet") %>% - set_mode("classification") %>% translate() ``` -For `glmnet` models, the full regularization path is always fit regardless of the -value given to `penalty`. Also, there is the option to pass multiple values (or -no values) to the `penalty` argument. When using the `predict()` method in these -cases, the return value depends on the value of `penalty`. When using -`predict()`, only a single value of the penalty can be used. When predicting on -multiple penalties, the `multi_predict()` function can be used. It returns a -tibble with a list column called `.pred` that contains a tibble with all of the -penalty results. +`logistic_reg()` requires a single value for the `penalty` argument (a number +or `tune()`). Despite this, the full regularization path is always fit +regardless of the value given to `penalty`. To pass in a custom sequence of +values for `lambda`, use the argument `path_values` in `set_engine()`. This +will assign the value of the glmnet `lambda` parameter without disturbing +the value given in `logistic_reg(penalty)`. For example: + +```{r glmnet-path} +logistic_reg(penalty = .1) %>% + set_engine("glmnet", path_values = c(0, 10^seq(-10, 1, length.out = 20))) %>% + translate() +``` + +When fitting a pure ridge regression model (i.e., `penalty = 0`), we _strongly +suggest_ that you pass in a vector for `path_values` that includes zero. See +[issue #431](https://github.com/tidymodels/parsnip/issues/431) for a discussion. + +When using `predict()`, the single penalty value used for prediction is the one +given to `logistic_reg()`. + +To predict on multiple penalties, the `multi_predict()` function can be used. +It returns a tibble with a list column called `.pred` that contains a tibble +with all of the penalty results. ## LiblineaR diff --git a/man/rmd/multinom-reg.Rmd b/man/rmd/multinom-reg.Rmd index 5d08847d2..870eff1aa 100644 --- a/man/rmd/multinom-reg.Rmd +++ b/man/rmd/multinom-reg.Rmd @@ -11,18 +11,32 @@ For this type of model, the template of the fit calls are below. ```{r glmnet-cls} multinom_reg() %>% set_engine("glmnet") %>% - set_mode("classification") %>% translate() ``` -For `glmnet` models, the full regularization path is always fit regardless of the -value given to `penalty`. Also, there is the option to pass multiple values (or -no values) to the `penalty` argument. When using the `predict()` method in these -cases, the return value depends on the value of `penalty`. When using -`predict()`, only a single value of the penalty can be used. When predicting on -multiple penalties, the `multi_predict()` function can be used. It returns a -tibble with a list column called `.pred` that contains a tibble with all of the -penalty results. +`multinom_reg()` requires a single value for the `penalty` argument (a number +or `tune()`). Despite this, the full regularization path is always fit +regardless of the value given to `penalty`. To pass in a custom sequence of +values for `lambda`, use the argument `path_values` in `set_engine()`. This +will assign the value of the glmnet `lambda` parameter without disturbing +the value given in `multinom_reg(penalty)`. For example: + +```{r glmnet-path} +multinom_reg(penalty = .1) %>% + set_engine("glmnet", path_values = c(0, 10^seq(-10, 1, length.out = 20))) %>% + translate() +``` + +When fitting a pure ridge regression model (i.e., `penalty = 0`), we _strongly +suggest_ that you pass in a vector for `path_values` that includes zero. See +[issue #431](https://github.com/tidymodels/parsnip/issues/431) for a discussion. + +When using `predict()`, the single penalty value used for prediction is the one +given to `multinom_reg()`. + +To predict on multiple penalties, the `multi_predict()` function can be used. +It returns a tibble with a list column called `.pred` that contains a tibble +with all of the penalty results. ## nnet diff --git a/tests/testthat/test_linear_reg.R b/tests/testthat/test_linear_reg.R index 4c0617cec..a94bf17fe 100644 --- a/tests/testthat/test_linear_reg.R +++ b/tests/testthat/test_linear_reg.R @@ -159,6 +159,19 @@ test_that('engine arguments', { ) ) + # For issue #431 + with_path <- + linear_reg(penalty = 1) %>% + set_engine("glmnet", path_values = 4:2) %>% + translate() + expect_equal( + names(with_path$method$fit$args), + c("x", "y", "weights", "lambda", "family") + ) + expect_equal( + rlang::eval_tidy(with_path$method$fit$args$lambda), + 4:2 + ) }) diff --git a/tests/testthat/test_logistic_reg.R b/tests/testthat/test_logistic_reg.R index b19806dae..5a3842b84 100644 --- a/tests/testthat/test_logistic_reg.R +++ b/tests/testthat/test_logistic_reg.R @@ -147,7 +147,7 @@ test_that('primary arguments', { ) ) - penalty_v <- logistic_reg(penalty = varying()) + penalty_v <- logistic_reg(penalty = 1) penalty_v_glmnet <- translate(penalty_v %>% set_engine("glmnet")) penalty_v_liblinear <- translate(penalty_v %>% set_engine("LiblineaR")) penalty_v_spark <- translate(penalty_v %>% set_engine("spark")) @@ -164,7 +164,7 @@ test_that('primary arguments', { x = expr(missing_arg()), y = expr(missing_arg()), wi = expr(missing_arg()), - cost = new_empty_quosure(varying()), + cost = new_empty_quosure(1), verbose = FALSE ) ) @@ -173,7 +173,7 @@ test_that('primary arguments', { x = expr(missing_arg()), formula = expr(missing_arg()), weight_col = expr(missing_arg()), - reg_param = new_empty_quosure(varying()), + reg_param = new_empty_quosure(1), family = "binomial" ) ) @@ -245,6 +245,19 @@ test_that('engine arguments', { ) ) + # For issue #431 + with_path <- + logistic_reg(penalty = 1) %>% + set_engine("glmnet", path_values = 4:2) %>% + translate() + expect_equal( + names(with_path$method$fit$args), + c("x", "y", "weights", "lambda", "family") + ) + expect_equal( + rlang::eval_tidy(with_path$method$fit$args$lambda), + 4:2 + ) }) diff --git a/tests/testthat/test_multinom_reg.R b/tests/testthat/test_multinom_reg.R index a373159b6..bd387153c 100644 --- a/tests/testthat/test_multinom_reg.R +++ b/tests/testthat/test_multinom_reg.R @@ -73,6 +73,19 @@ test_that('engine arguments', { ) ) + # For issue #431 + with_path <- + multinom_reg(penalty = 1) %>% + set_engine("glmnet", path_values = 4:2) %>% + translate() + expect_equal( + names(with_path$method$fit$args), + c("x", "y", "weights", "lambda", "family") + ) + expect_equal( + rlang::eval_tidy(with_path$method$fit$args$lambda), + 4:2 + ) }) From 1fb798852ff2a874b3073f9b51239309fddb0075 Mon Sep 17 00:00:00 2001 From: Max Kuhn Date: Tue, 11 May 2021 14:45:04 -0400 Subject: [PATCH 3/8] check values first (and evaluate them) --- R/linear_reg.R | 2 +- R/logistic_reg.R | 2 +- R/misc.R | 6 ++++-- R/multinom_reg.R | 1 + 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/R/linear_reg.R b/R/linear_reg.R index c04704c07..a4ff6b304 100644 --- a/R/linear_reg.R +++ b/R/linear_reg.R @@ -107,6 +107,7 @@ translate.linear_reg <- function(x, engine = x$engine, ...) { x <- translate.default(x, engine, ...) if (engine == "glmnet") { + check_glmnet_penalty(x) if (any(names(x$eng_args) == "path_values")) { # Since we decouple the parsnip `penalty` argument from being the same # as the glmnet `lambda` value, this allows users to set the path @@ -122,7 +123,6 @@ translate.linear_reg <- function(x, engine = x$engine, ...) { # Since the `fit` information is gone for the penalty, we need to have an # evaluated value for the parameter. x$args$penalty <- rlang::eval_tidy(x$args$penalty) - check_glmnet_penalty(x) } x } diff --git a/R/logistic_reg.R b/R/logistic_reg.R index 14bd12558..de98224c1 100644 --- a/R/logistic_reg.R +++ b/R/logistic_reg.R @@ -109,6 +109,7 @@ translate.logistic_reg <- function(x, engine = x$engine, ...) { arg_names <- names(arg_vals) if (engine == "glmnet") { + check_glmnet_penalty(x) if (any(names(x$eng_args) == "path_values")) { # Since we decouple the parsnip `penalty` argument from being the same # as the glmnet `lambda` value, this allows users to set the path @@ -124,7 +125,6 @@ translate.logistic_reg <- function(x, engine = x$engine, ...) { # Since the `fit` information is gone for the penalty, we need to have an # evaluated value for the parameter. x$args$penalty <- rlang::eval_tidy(x$args$penalty) - check_glmnet_penalty(x) } if (engine == "LiblineaR") { diff --git a/R/misc.R b/R/misc.R index 2332e6afc..be7fc42f4 100644 --- a/R/misc.R +++ b/R/misc.R @@ -324,10 +324,12 @@ stan_conf_int <- function(object, newdata) { } check_glmnet_penalty <- function(x) { - if (length(x$args$penalty) != 1) { + pen <- rlang::eval_tidy(x$args$penalty) + + if (length(pen) != 1) { rlang::abort(c( "For the glmnet engine, `penalty` must be a single number (or a value of `tune()`).", - glue::glue("There are {length(x$args$penalty)} values for `penalty`."), + glue::glue("There are {length(pen)} values for `penalty`."), "To try multiple values for total regularization, use the tune package.", "To predict multiple penalties, use `multi_predict()`" )) diff --git a/R/multinom_reg.R b/R/multinom_reg.R index 6ba4e6d26..50a6ccf1e 100644 --- a/R/multinom_reg.R +++ b/R/multinom_reg.R @@ -100,6 +100,7 @@ translate.multinom_reg <- function(x, engine = x$engine, ...) { x <- translate.default(x, engine, ...) if (engine == "glmnet") { + check_glmnet_penalty(x) if (any(names(x$eng_args) == "path_values")) { # Since we decouple the parsnip `penalty` argument from being the same # as the glmnet `lambda` value, this allows users to set the path From 235387553ccf57864598266bd4b845a847f5a689 Mon Sep 17 00:00:00 2001 From: Julia Silge Date: Tue, 11 May 2021 15:36:26 -0600 Subject: [PATCH 4/8] Update NEWS --- NEWS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 3ed053f79..eb5f02f19 100644 --- a/NEWS.md +++ b/NEWS.md @@ -7,7 +7,7 @@ * For models with `glmnet` engines: - A single value is required for `penalty` (either a single numeric value or a value of `tune()`) (#481) - - A special argument called `path_values` can be used to set the `lambda` path is a specific set of numbers (independent of the value of `penalty`). A pure ridge regression models (i.e., `mixture = 1`) will generate incorrect values if the path does not include zero. See issue #431. + - A special argument called `path_values` can be used to set the `lambda` path as a specific set of numbers (independent of the value of `penalty`). A pure ridge regression models (i.e., `mixture = 1`) will generate incorrect values if the path does not include zero. See issue #431. * The `liquidSVM` engine for `svm_rbf()` was deprecated due to that package's removal from CRAN. (#425) From a5fc49b8d46671a17a20320156892fc337bcab69 Mon Sep 17 00:00:00 2001 From: Julia Silge Date: Tue, 11 May 2021 15:52:41 -0600 Subject: [PATCH 5/8] Clarify comment for FUTURE ME --- R/linear_reg.R | 4 ++-- R/logistic_reg.R | 4 ++-- R/multinom_reg.R | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/R/linear_reg.R b/R/linear_reg.R index a4ff6b304..187c52fcc 100644 --- a/R/linear_reg.R +++ b/R/linear_reg.R @@ -110,8 +110,8 @@ translate.linear_reg <- function(x, engine = x$engine, ...) { check_glmnet_penalty(x) if (any(names(x$eng_args) == "path_values")) { # Since we decouple the parsnip `penalty` argument from being the same - # as the glmnet `lambda` value, this allows users to set the path - # differently from the default that glmnet uses. See + # as the glmnet `lambda` value, `path_values` allows users to set the + # path differently from the default that glmnet uses. See # https://github.com/tidymodels/parsnip/issues/431 x$method$fit$args$lambda <- x$eng_args$path_values x$eng_args$path_values <- NULL diff --git a/R/logistic_reg.R b/R/logistic_reg.R index de98224c1..44d70f3e6 100644 --- a/R/logistic_reg.R +++ b/R/logistic_reg.R @@ -112,8 +112,8 @@ translate.logistic_reg <- function(x, engine = x$engine, ...) { check_glmnet_penalty(x) if (any(names(x$eng_args) == "path_values")) { # Since we decouple the parsnip `penalty` argument from being the same - # as the glmnet `lambda` value, this allows users to set the path - # differently from the default that glmnet uses. See + # as the glmnet `lambda` value, `path_values` allows users to set the + # path differently from the default that glmnet uses. See # https://github.com/tidymodels/parsnip/issues/431 x$method$fit$args$lambda <- x$eng_args$path_values x$eng_args$path_values <- NULL diff --git a/R/multinom_reg.R b/R/multinom_reg.R index 50a6ccf1e..c9b30b3ec 100644 --- a/R/multinom_reg.R +++ b/R/multinom_reg.R @@ -103,8 +103,8 @@ translate.multinom_reg <- function(x, engine = x$engine, ...) { check_glmnet_penalty(x) if (any(names(x$eng_args) == "path_values")) { # Since we decouple the parsnip `penalty` argument from being the same - # as the glmnet `lambda` value, this allows users to set the path - # differently from the default that glmnet uses. See + # as the glmnet `lambda` value, `path_values` allows users to set the + # path differently from the default that glmnet uses. See # https://github.com/tidymodels/parsnip/issues/431 x$method$fit$args$lambda <- x$eng_args$path_values x$eng_args$path_values <- NULL From 40101e0217f46c42f71172241a594df428e82548 Mon Sep 17 00:00:00 2001 From: Julia Silge Date: Tue, 11 May 2021 15:53:23 -0600 Subject: [PATCH 6/8] Edits for clarity in docs --- man/linear_reg.Rd | 22 +++++++++++----------- man/logistic_reg.Rd | 22 +++++++++++----------- man/multinom_reg.Rd | 22 +++++++++++----------- man/rmd/linear-reg.Rmd | 20 ++++++++++---------- man/rmd/logistic-reg.Rmd | 21 +++++++++++---------- man/rmd/multinom-reg.Rmd | 22 ++++++++++++---------- 6 files changed, 66 insertions(+), 63 deletions(-) diff --git a/man/linear_reg.Rd b/man/linear_reg.Rd index f12123ff3..29c7cefb7 100644 --- a/man/linear_reg.Rd +++ b/man/linear_reg.Rd @@ -100,12 +100,12 @@ call. For this type of model, the template of the fit calls are below. ## family = "gaussian") } -\code{linear_reg()} requires a single value for the \code{penalty} argument (a -number or \code{tune()}). Despite this, the full regularization path is -always fit regardless of the value given to \code{penalty}. To pass in a -custom sequence of values for \code{lambda}, use the argument \code{path_values} -in \code{set_engine()}. This will assign the value of the glmnet \code{lambda} -parameter without disturbing the value given in \code{linear_reg(penalty)}. +The glmnet engine requires a single value for the \code{penalty} argument (a +number or \code{tune()}), but the full regularization path is always fit +regardless of the value given to \code{penalty}. To pass in a custom sequence +of values for glmnet’s \code{lambda}, use the argument \code{path_values} in +\code{set_engine()}. This will assign the value of the glmnet \code{lambda} +parameter without disturbing the value given of \code{linear_reg(penalty)}. For example:\if{html}{\out{
}}\preformatted{linear_reg(penalty = .1) \%>\% set_engine("glmnet", path_values = c(0, 10^seq(-10, 1, length.out = 20))) \%>\% translate() @@ -126,12 +126,12 @@ When fitting a pure ridge regression model (i.e., \code{penalty = 0}), we includes zero. See \href{https://github.com/tidymodels/parsnip/issues/431}{issue #431} for a discussion. -When using \code{predict()}, the single penalty value used for prediction is -the one given to \code{linear_reg()}. +When using \code{predict()}, the single \code{penalty} value used for prediction +is the one specified in \code{linear_reg()}. -To predict on multiple penalties, the \code{multi_predict()} function can be -used. It returns a tibble with a list column called \code{.pred} that -contains a tibble with all of the penalty results. +To predict on multiple penalties, use the \code{multi_predict()} function. +This function returns a tibble with a list column called \code{.pred} +containing all of the penalty results. } \subsection{stan}{\if{html}{\out{
}}\preformatted{linear_reg() \%>\% diff --git a/man/logistic_reg.Rd b/man/logistic_reg.Rd index 52fe7d340..2859d9f9f 100644 --- a/man/logistic_reg.Rd +++ b/man/logistic_reg.Rd @@ -100,12 +100,12 @@ call. For this type of model, the template of the fit calls are below. ## family = "binomial") } -\code{logistic_reg()} requires a single value for the \code{penalty} argument (a -number or \code{tune()}). Despite this, the full regularization path is -always fit regardless of the value given to \code{penalty}. To pass in a -custom sequence of values for \code{lambda}, use the argument \code{path_values} -in \code{set_engine()}. This will assign the value of the glmnet \code{lambda} -parameter without disturbing the value given in \code{logistic_reg(penalty)}. +The glmnet engine requires a single value for the \code{penalty} argument (a +number or \code{tune()}), but the full regularization path is always fit +regardless of the value given to \code{penalty}. To pass in a custom sequence +of values for glmnet’s \code{lambda}, use the argument \code{path_values} in +\code{set_engine()}. This will assign the value of the glmnet \code{lambda} +parameter without disturbing the value given of \code{logistic_reg(penalty)}. For example:\if{html}{\out{
}}\preformatted{logistic_reg(penalty = .1) \%>\% set_engine("glmnet", path_values = c(0, 10^seq(-10, 1, length.out = 20))) \%>\% translate() @@ -126,12 +126,12 @@ When fitting a pure ridge regression model (i.e., \code{penalty = 0}), we includes zero. See \href{https://github.com/tidymodels/parsnip/issues/431}{issue #431} for a discussion. -When using \code{predict()}, the single penalty value used for prediction is -the one given to \code{logistic_reg()}. +When using \code{predict()}, the single \code{penalty} value used for prediction +is the one specified in \code{logistic_reg()}. -To predict on multiple penalties, the \code{multi_predict()} function can be -used. It returns a tibble with a list column called \code{.pred} that -contains a tibble with all of the penalty results. +To predict on multiple penalties, use the \code{multi_predict()} function. +This function returns a tibble with a list column called \code{.pred} +containing all of the penalty results. } \subsection{LiblineaR}{\if{html}{\out{
}}\preformatted{logistic_reg() \%>\% diff --git a/man/multinom_reg.Rd b/man/multinom_reg.Rd index 1d8139ac2..6d9ba5fcc 100644 --- a/man/multinom_reg.Rd +++ b/man/multinom_reg.Rd @@ -82,12 +82,12 @@ call. For this type of model, the template of the fit calls are below. ## family = "multinomial") } -\code{multinom_reg()} requires a single value for the \code{penalty} argument (a -number or \code{tune()}). Despite this, the full regularization path is -always fit regardless of the value given to \code{penalty}. To pass in a -custom sequence of values for \code{lambda}, use the argument \code{path_values} -in \code{set_engine()}. This will assign the value of the glmnet \code{lambda} -parameter without disturbing the value given in \code{multinom_reg(penalty)}. +The glmnet engine requires a single value for the \code{penalty} argument (a +number or \code{tune()}), but the full regularization path is always fit +regardless of the value given to \code{penalty}. To pass in a custom sequence +of values for glmnet’s \code{lambda}, use the argument \code{path_values} in +\code{set_engine()}. This will assign the value of the glmnet \code{lambda} +parameter without disturbing the value given of \code{multinom_reg(penalty)}. For example:\if{html}{\out{
}}\preformatted{multinom_reg(penalty = .1) \%>\% set_engine("glmnet", path_values = c(0, 10^seq(-10, 1, length.out = 20))) \%>\% translate() @@ -108,12 +108,12 @@ When fitting a pure ridge regression model (i.e., \code{penalty = 0}), we includes zero. See \href{https://github.com/tidymodels/parsnip/issues/431}{issue #431} for a discussion. -When using \code{predict()}, the single penalty value used for prediction is -the one given to \code{multinom_reg()}. +When using \code{predict()}, the single \code{penalty} value used for prediction +is the one specified in \code{multinom_reg()}. -To predict on multiple penalties, the \code{multi_predict()} function can be -used. It returns a tibble with a list column called \code{.pred} that -contains a tibble with all of the penalty results. +To predict on multiple penalties, use the \code{multi_predict()} function. +This function returns a tibble with a list column called \code{.pred} +containing all of the penalty results. } \subsection{nnet}{\if{html}{\out{
}}\preformatted{multinom_reg() \%>\% diff --git a/man/rmd/linear-reg.Rmd b/man/rmd/linear-reg.Rmd index 062da1e74..dbef43a45 100644 --- a/man/rmd/linear-reg.Rmd +++ b/man/rmd/linear-reg.Rmd @@ -21,12 +21,12 @@ linear_reg(penalty = 0.1) %>% translate() ``` -`linear_reg()` requires a single value for the `penalty` argument (a number -or `tune()`). Despite this, the full regularization path is always fit +The glmnet engine requires a single value for the `penalty` argument (a number +or `tune()`), but the full regularization path is always fit regardless of the value given to `penalty`. To pass in a custom sequence of -values for `lambda`, use the argument `path_values` in `set_engine()`. This -will assign the value of the glmnet `lambda` parameter without disturbing -the value given in `linear_reg(penalty)`. For example: +values for glmnet's `lambda`, use the argument `path_values` in `set_engine()`. +This will assign the value of the glmnet `lambda` parameter without disturbing +the value given of `linear_reg(penalty)`. For example: ```{r glmnet-path} linear_reg(penalty = .1) %>% @@ -38,12 +38,12 @@ When fitting a pure ridge regression model (i.e., `penalty = 0`), we _strongly suggest_ that you pass in a vector for `path_values` that includes zero. See [issue #431](https://github.com/tidymodels/parsnip/issues/431) for a discussion. -When using `predict()`, the single penalty value used for prediction is the one -given to `linear_reg()`. +When using `predict()`, the single `penalty` value used for prediction is the +one specified in `linear_reg()`. -To predict on multiple penalties, the `multi_predict()` function can be used. -It returns a tibble with a list column called `.pred` that contains a tibble -with all of the penalty results. +To predict on multiple penalties, use the `multi_predict()` function. +This function returns a tibble with a list column called `.pred` containing +all of the penalty results. ## stan diff --git a/man/rmd/logistic-reg.Rmd b/man/rmd/logistic-reg.Rmd index 14e707074..174183546 100644 --- a/man/rmd/logistic-reg.Rmd +++ b/man/rmd/logistic-reg.Rmd @@ -22,12 +22,12 @@ logistic_reg(penalty = 0.1) %>% translate() ``` -`logistic_reg()` requires a single value for the `penalty` argument (a number -or `tune()`). Despite this, the full regularization path is always fit +The glmnet engine requires a single value for the `penalty` argument (a number +or `tune()`), but the full regularization path is always fit regardless of the value given to `penalty`. To pass in a custom sequence of -values for `lambda`, use the argument `path_values` in `set_engine()`. This -will assign the value of the glmnet `lambda` parameter without disturbing -the value given in `logistic_reg(penalty)`. For example: +values for glmnet's `lambda`, use the argument `path_values` in `set_engine()`. +This will assign the value of the glmnet `lambda` parameter without disturbing +the value given of `logistic_reg(penalty)`. For example: ```{r glmnet-path} logistic_reg(penalty = .1) %>% @@ -39,12 +39,13 @@ When fitting a pure ridge regression model (i.e., `penalty = 0`), we _strongly suggest_ that you pass in a vector for `path_values` that includes zero. See [issue #431](https://github.com/tidymodels/parsnip/issues/431) for a discussion. -When using `predict()`, the single penalty value used for prediction is the one -given to `logistic_reg()`. +When using `predict()`, the single `penalty` value used for prediction is the +one specified in `logistic_reg()`. + +To predict on multiple penalties, use the `multi_predict()` function. +This function returns a tibble with a list column called `.pred` containing +all of the penalty results. -To predict on multiple penalties, the `multi_predict()` function can be used. -It returns a tibble with a list column called `.pred` that contains a tibble -with all of the penalty results. ## LiblineaR diff --git a/man/rmd/multinom-reg.Rmd b/man/rmd/multinom-reg.Rmd index 624591ac9..878c1eb4c 100644 --- a/man/rmd/multinom-reg.Rmd +++ b/man/rmd/multinom-reg.Rmd @@ -14,12 +14,13 @@ multinom_reg(penalty = 0.1) %>% translate() ``` -`multinom_reg()` requires a single value for the `penalty` argument (a number -or `tune()`). Despite this, the full regularization path is always fit +The glmnet engine requires a single value for the `penalty` argument (a number +or `tune()`), but the full regularization path is always fit regardless of the value given to `penalty`. To pass in a custom sequence of -values for `lambda`, use the argument `path_values` in `set_engine()`. This -will assign the value of the glmnet `lambda` parameter without disturbing -the value given in `multinom_reg(penalty)`. For example: +values for glmnet's `lambda`, use the argument `path_values` in `set_engine()`. +This will assign the value of the glmnet `lambda` parameter without disturbing +the value given of `multinom_reg(penalty)`. For example: + ```{r glmnet-path} multinom_reg(penalty = .1) %>% @@ -31,12 +32,13 @@ When fitting a pure ridge regression model (i.e., `penalty = 0`), we _strongly suggest_ that you pass in a vector for `path_values` that includes zero. See [issue #431](https://github.com/tidymodels/parsnip/issues/431) for a discussion. -When using `predict()`, the single penalty value used for prediction is the one -given to `multinom_reg()`. +When using `predict()`, the single `penalty` value used for prediction is the +one specified in `multinom_reg()`. + +To predict on multiple penalties, use the `multi_predict()` function. +This function returns a tibble with a list column called `.pred` containing +all of the penalty results. -To predict on multiple penalties, the `multi_predict()` function can be used. -It returns a tibble with a list column called `.pred` that contains a tibble -with all of the penalty results. ## nnet From 4f04f775e8e71a83cd79d6f87657739a32a4ade4 Mon Sep 17 00:00:00 2001 From: Julia Silge Date: Wed, 12 May 2021 09:25:08 -0600 Subject: [PATCH 7/8] Use linear_reg translate for multinom_reg for now --- R/multinom_reg.R | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/R/multinom_reg.R b/R/multinom_reg.R index c9b30b3ec..b799000e1 100644 --- a/R/multinom_reg.R +++ b/R/multinom_reg.R @@ -96,29 +96,7 @@ print.multinom_reg <- function(x, ...) { } #' @export -translate.multinom_reg <- function(x, engine = x$engine, ...) { - x <- translate.default(x, engine, ...) - - if (engine == "glmnet") { - check_glmnet_penalty(x) - if (any(names(x$eng_args) == "path_values")) { - # Since we decouple the parsnip `penalty` argument from being the same - # as the glmnet `lambda` value, `path_values` allows users to set the - # path differently from the default that glmnet uses. See - # https://github.com/tidymodels/parsnip/issues/431 - x$method$fit$args$lambda <- x$eng_args$path_values - x$eng_args$path_values <- NULL - x$method$fit$args$path_values <- NULL - } else { - # See discussion in https://github.com/tidymodels/parsnip/issues/195 - x$method$fit$args$lambda <- NULL - } - # Since the `fit` information is gone for the penalty, we need to have an - # evaluated value for the parameter. - x$args$penalty <- rlang::eval_tidy(x$args$penalty) - } - x -} +translate.multinom_reg <- translate.linear_reg # ------------------------------------------------------------------------------ From 8ff0a28e322ed4a2759e5c75c698b6e52aa51601 Mon Sep 17 00:00:00 2001 From: Julia Silge Date: Wed, 12 May 2021 09:25:21 -0600 Subject: [PATCH 8/8] Update NEWS --- NEWS.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NEWS.md b/NEWS.md index eb5f02f19..e0c9193ac 100644 --- a/NEWS.md +++ b/NEWS.md @@ -6,8 +6,8 @@ * For models with `glmnet` engines: - - A single value is required for `penalty` (either a single numeric value or a value of `tune()`) (#481) - - A special argument called `path_values` can be used to set the `lambda` path as a specific set of numbers (independent of the value of `penalty`). A pure ridge regression models (i.e., `mixture = 1`) will generate incorrect values if the path does not include zero. See issue #431. + - A single value is required for `penalty` (either a single numeric value or a value of `tune()`) (#481). + - A special argument called `path_values` can be used to set the `lambda` path as a specific set of numbers (independent of the value of `penalty`). A pure ridge regression models (i.e., `mixture = 1`) will generate incorrect values if the path does not include zero. See issue #431 for discussion (#486). * The `liquidSVM` engine for `svm_rbf()` was deprecated due to that package's removal from CRAN. (#425)