rf-finalize3

tidymodels
statlearning
template
string
Published

May 17, 2023

Aufgabe

Berechnen Sie ein prädiktives Modell (Random Forest) mit dieser Modellgleichung:

body_mass_g ~ . (Datensatz: palmerpenguins::penguins).

Zeigen Sie, welche Werte für mtry im Default von Tidymodels gesetzt werden!

Hinweise: - Tunen Sie alle Tuningparameter mit jeweils 3 Werten. - Verwenden Sie Kreuzvalidierung - Verwenden Sie Standardwerte, wo nicht anders angegeben. - Fixieren Sie Zufallszahlen auf den Startwert 42.











Lösung

Standard-Start

Zuererst der Standardablauf:

# Setup:
library(tidymodels)
── Attaching packages ────────────────────────────────────── tidymodels 1.1.1 ──
✔ broom        1.0.5     ✔ recipes      1.0.8
✔ dials        1.2.0     ✔ rsample      1.2.0
✔ dplyr        1.1.3     ✔ tibble       3.2.1
✔ ggplot2      3.4.4     ✔ tidyr        1.3.0
✔ infer        1.0.5     ✔ tune         1.1.2
✔ modeldata    1.2.0     ✔ workflows    1.1.3
✔ parsnip      1.1.1     ✔ workflowsets 1.0.1
✔ purrr        1.0.2     ✔ yardstick    1.2.0
── Conflicts ───────────────────────────────────────── tidymodels_conflicts() ──
✖ purrr::discard() masks scales::discard()
✖ dplyr::filter()  masks stats::filter()
✖ dplyr::lag()     masks stats::lag()
✖ recipes::step()  masks stats::step()
• Learn how to get started at https://www.tidymodels.org/start/
library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ forcats   1.0.0     ✔ readr     2.1.4
✔ lubridate 1.9.3     ✔ stringr   1.5.0
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ readr::col_factor() masks scales::col_factor()
✖ purrr::discard()    masks scales::discard()
✖ dplyr::filter()     masks stats::filter()
✖ stringr::fixed()    masks recipes::fixed()
✖ dplyr::lag()        masks stats::lag()
✖ readr::spec()       masks yardstick::spec()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(tictoc)  # Zeitmessung
set.seed(42)


# Data:
d_path <- "https://vincentarelbundock.github.io/Rdatasets/csv/palmerpenguins/penguins.csv"
d <- read_csv(d_path)
Rows: 344 Columns: 9
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (3): species, island, sex
dbl (6): rownames, bill_length_mm, bill_depth_mm, flipper_length_mm, body_ma...

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
# rm NA in the dependent variable:
d <- d %>% 
  drop_na(body_mass_g)


set.seed(42)
d_split <- initial_split(d)
d_train <- training(d_split)
d_test <- testing(d_split)


# model:
mod_rf <-
  rand_forest(mode = "regression",
           mtry = tune(),
           min_n = tune(),
           trees = tune())


# cv:
set.seed(42)
rsmpl <- vfold_cv(d_train)


# recipe:
rec_plain <- 
  recipe(body_mass_g ~  ., data = d_train) %>% 
  step_impute_bag(all_predictors())


# workflow:
wf1 <-
  workflow() %>% 
  add_model(mod_rf) %>% 
  add_recipe(rec_plain)

Tuninggrid

Welche Tuningparameter hat unser Workflow?

wf1_params_unclear <- 
  extract_parameter_set_dials(wf1)
wf1_params_unclear
Collection of 3 parameters for tuning

 identifier  type    object
       mtry  mtry nparam[?]
      trees trees nparam[+]
      min_n min_n nparam[+]

Model parameters needing finalization:
   # Randomly Selected Predictors ('mtry')

See `?dials::finalize` or `?dials::update.parameters` for more information.

Verlangt waren 3 Tuningparameterwerte pro Parameter:

my_grid <- grid_latin_hypercube(wf1_params_unclear, levels = 3)
Warning: `levels` is not an argument to `grid_latin_hypercube()`. Did you mean
`size`?
Error in `grid_latin_hypercube()`:
! These arguments contain unknowns: `mtry`.
ℹ See the `finalize()` function.
my_grid
Error in eval(expr, envir, enclos): object 'my_grid' not found

Tidymodels weiß nicht, welche Werte für mtry benutzt werden sollen, da dieser Wert abhängig ist von der Anzahl der Spalten des Datensatzes, und damit unabhängig vom Modell.

Die Ausgabe nparam[?] oben sagt uns, dass Tidymodels den Wertebereich des Tuningparameter nicht klären könnte, da er Daten abhängig ist.

Informieren wir also Tidymodels zu diesem Wertebereich:

wf1_params <- 
  wf1 %>% 
  extract_parameter_set_dials() %>% 
  update(mtry = finalize(mtry(), d_train))

wf1_params
Collection of 3 parameters for tuning

 identifier  type    object
       mtry  mtry nparam[+]
      trees trees nparam[+]
      min_n min_n nparam[+]

So, jetzt weiß Tidymodels, wie viele Werte für mtry benutzt werden können.

Wir können jetzt das Tuninggitter erstellen (das macht das Paket dials):

my_grid <- grid_latin_hypercube(wf1_params, size = 125)
my_grid %>% head()
# A tibble: 6 × 3
   mtry trees min_n
  <int> <int> <int>
1     1   105    11
2     5  1036    21
3     3   325    16
4     4  1375    28
5     6  1405    21
6     7   304    15

Wie viele verschiedene Werte gibt es in dem Tuningitter?

Schauen wir es uns mal an.

my_grid %>% 
  ggplot(aes(x = trees, y = mtry)) +
  geom_point()

Wir können das Tuninggitter auch selber erstellen:

my_grid <-
  grid_latin_hypercube(mtry(range = c(1, ncol(d_train)-1)),
                       trees(),
                       min_n(),
                       size = 60)
dim(my_grid)
[1] 60  3

Tuning/Fitting

# tuning:
tic()
wf1_fit <-
  wf1 %>% 
  tune_grid(
    grid = my_grid,
    resamples = rsmpl)
toc()
145.827 sec elapsed

Dann schauen wir uns das Ergebnisobjekt vom Tuning an.

wf1_fit %>% 
  collect_metrics() %>% 
  filter(.metric == "rmse") %>% 
  arrange(mtry)
# A tibble: 60 × 9
    mtry trees min_n .metric .estimator  mean     n std_err .config             
   <int> <int> <int> <chr>   <chr>      <dbl> <int>   <dbl> <chr>               
 1     1  1835    33 rmse    standard    332.    10    13.7 Preprocessor1_Model…
 2     1  1742    14 rmse    standard    316.    10    13.1 Preprocessor1_Model…
 3     1   510    29 rmse    standard    327.    10    14.1 Preprocessor1_Model…
 4     1   826     3 rmse    standard    310.    10    13.0 Preprocessor1_Model…
 5     2   672    15 rmse    standard    283.    10    11.2 Preprocessor1_Model…
 6     2   147    22 rmse    standard    287.    10    10.7 Preprocessor1_Model…
 7     2  1927     7 rmse    standard    283.    10    11.4 Preprocessor1_Model…
 8     2   386    23 rmse    standard    288.    10    11.9 Preprocessor1_Model…
 9     2    81    29 rmse    standard    292.    10    12.3 Preprocessor1_Model…
10     2   359     6 rmse    standard    283.    10    11.1 Preprocessor1_Model…
# ℹ 50 more rows

In der Hilfe ist zu lesen:

In some cases, the tuning parameter values depend on the dimensions of the data. For example, mtry in random forest models depends on the number of predictors. In this case, the default tuning parameter object requires an upper range. dials::finalize() can be used to derive the data-dependent parameters. Otherwise, a parameter set can be created (via dials::parameters()) and the dials update() function can be used to change the values. This updated parameter set can be passed to the function via the param_info argument.

Achtung: step_impute_knn scheint Probleme zu haben, wenn es Charakter-Variablen gibt.

Praktischerweise findet Tidymodels die Begrenzung von mtry selber heraus, wenn Sie kein Tuninggrid definieren. Das erkennen Sie daran, dass Tidymodels beim Tuning/Fitten die folgende Ausgabe zeigt:

i Creating pre-processing data to finalize unknown parameter: mtry.


Categories:

  • tidymodels
  • statlearning
  • template
  • string