Different objectives in `parsnip::boost_tree()`

Hi,

If I am using parsnip::boost_tree() to run an xgboost, and I want to use a different objective function (e.g. objective=reg:tweedie), is there a way to do that?

I received an error when I tried to run the following:

library(parsnip)
boost_tree() %>%
    set_engine("xgboost") %>% 
    set_mode("regression") %>%
    update(parameters = list(objective = "reg:tweedie"))
Error: At least one argument is not a main argument: `objective`

Thanks!

1 Like

I don't think this is possible currently from looking at this code. You could suggest it as a feature request in an issue in the repo to check first if they would approve of it as a good idea

1 Like

I just created a PR for this (see temporary install directions below). You would pass it in by itself (i.e., not in a list):

# remotes::install_github("tidymodels/parsnip@xgb-objective")

library(tidymodels)
#> ── Attaching packages ────────────────────────────────────── tidymodels 0.1.2 ──
#> ✓ broom     0.7.3           ✓ recipes   0.1.15.9000
#> ✓ dials     0.0.9.9000      ✓ rsample   0.0.8.9000 
#> ✓ dplyr     1.0.2           ✓ tibble    3.0.4      
#> ✓ ggplot2   3.3.3           ✓ tidyr     1.1.2      
#> ✓ infer     0.5.3           ✓ tune      0.1.2.9000 
#> ✓ modeldata 0.1.0.9000      ✓ workflows 0.2.1      
#> ✓ parsnip   0.1.4.9000      ✓ yardstick 0.0.7.9000 
#> ✓ purrr     0.3.4
#> ── Conflicts ───────────────────────────────────────── tidymodels_conflicts() ──
#> x purrr::discard() masks scales::discard()
#> x dplyr::filter()  masks stats::filter()
#> x dplyr::lag()     masks stats::lag()
#> x recipes::step()  masks stats::step()

spec <- 
  boost_tree() %>%
  set_engine("xgboost", objective = "reg:pseudohubererror") %>% 
  set_mode("regression") 

xgb_fit <- spec %>% fit(mpg ~ ., data = mtcars)
xgb_fit$fit$params$objective
#> [1] "reg:pseudohubererror"

Created on 2021-01-14 by the reprex package (v0.3.0)

3 Likes

Thanks!

Will this work also for objectives that don't start with reg or binary? (e.g. count:poisson or survival:cox?)

Yes(ish). It should so long as it receives the right data in the right format. Poisson should be fine but we're not ready to accept Surv() object just yet (if it uses those). We are just passing objective along to xgb.train().

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.