This vignette will show the basics of the leadr workflow. To see how leadr supports more advanced ensemble model building, check out my Ensembles vignette.
leadr is designed to create one leaderboard per R project per dataset. Currently, the leaderboard works best placed at the project root, with any number of subdirectories to save the models.
library(purrr)
library(tidyverse)
library(caret)
library(leadr)Let’s build some models. We can easily build a list of models using purrr::map.
We can also purrr the models into our leaderboard. This time we use purrr::walk to update the leaderboard while returning quietly.
walk(models, board)
board()
#> # A tibble: 4 x 13
#> rank id dir model metric score public method num group index
#> <dbl> <id> <chr> <chr> <chr> <dbl> <dbl> <chr> <dbl> <dbl> <list>
#> 1 1. 2 models… rf Accura… 0.955 NA boot 25. 2. <list…
#> 2 2. 4 models… rf Accura… 0.950 NA boot 25. 4. <list…
#> 3 3. 3 models… rf Accura… 0.946 NA boot 25. 3. <list…
#> 4 4. 1 models… rf Accura… 0.942 NA boot 25. 1. <list…
#> # ... with 2 more variables: tune <list>, seeds <list>By default, board saves the models into a folder at the root of the project called models_one and returns a tibble that provides us with everything we want to know about the model.
The tibble gives us the ranking and metric score, as well as lists like tune, index, and seeds that allow us to exactly recreate the model.
Of course, fitting four random forest models on the same dataset isn’t very realistic. We’d like to fit a variety of models and compare the accuracy. Let’s use the index column of the leaderboard to fit a new model on the same bootstrap resamples as the first model.
first_id <- which(board()$id == 1)
control <- trainControl(index = board()$index[[first_id]])
model <- train(Species ~ ., data = iris, method = 'glmnet', trControl = control)
board(model)
#> # A tibble: 5 x 13
#> rank id dir model metric score public method num group index
#> <dbl> <id> <chr> <chr> <chr> <dbl> <dbl> <chr> <dbl> <dbl> <list>
#> 1 1. 2 models… rf Accur… 0.955 NA boot 25. 2. <list…
#> 2 2. 5 models… glmnet Accur… 0.952 NA boot 25. 1. <list…
#> 3 3. 4 models… rf Accur… 0.950 NA boot 25. 4. <list…
#> 4 4. 3 models… rf Accur… 0.946 NA boot 25. 3. <list…
#> 5 5. 1 models… rf Accur… 0.942 NA boot 25. 1. <list…
#> # ... with 2 more variables: tune <list>, seeds <list>caret has a nice set of functions to compare models trained on the same bootstrap or cross-validation index. To find these comparable models, we can filter on the group column and use leadr::to_list() to convert the filtered leaderboard to a list of models.
From there, we can compare models using the resamples family of caret functions:
results <- resamples(group)
summary(results)
#>
#> Call:
#> summary.resamples(object = results)
#>
#> Models: Model1, Model2
#> Number of resamples: 25
#>
#> Accuracy
#> Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
#> Model1 0.9107143 0.9433962 0.9473684 0.9516469 0.9655172 1.0000000 0
#> Model2 0.8928571 0.9298246 0.9433962 0.9416994 0.9629630 0.9814815 0
#>
#> Kappa
#> Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
#> Model1 0.8638794 0.9152452 0.9197047 0.9266939 0.9478886 1.0000000 0
#> Model2 0.8365759 0.8944444 0.9152452 0.9116796 0.9444444 0.9720352 0
modelCor(results)
#> Model1 Model2
#> Model1 1.0000000 0.6676862
#> Model2 0.6676862 1.0000000
splom(results)
leadr also has tools to help you evaluate model ranking as the leaderboard gets big. Let’s add a few more models:
models <- map(
rep("rf", 20),
~train(
Species ~ .,
data = iris
)
)
walk(models, board)
board()
#> # A tibble: 25 x 13
#> rank id dir model metric score public method num group index
#> <dbl> <id> <chr> <chr> <chr> <dbl> <dbl> <chr> <dbl> <dbl> <list>
#> 1 1. 25 models… rf Accur… 0.959 NA boot 25. 24. <list…
#> 2 2. 21 models… rf Accur… 0.959 NA boot 25. 20. <list…
#> 3 3. 6 models… rf Accur… 0.956 NA boot 25. 5. <list…
#> 4 4. 16 models… rf Accur… 0.955 NA boot 25. 15. <list…
#> 5 5. 2 models… rf Accur… 0.955 NA boot 25. 2. <list…
#> 6 6. 9 models… rf Accur… 0.953 NA boot 25. 8. <list…
#> 7 7. 7 models… rf Accur… 0.953 NA boot 25. 6. <list…
#> 8 8. 20 models… rf Accur… 0.953 NA boot 25. 19. <list…
#> 9 9. 17 models… rf Accur… 0.952 NA boot 25. 16. <list…
#> 10 10. 5 models… glmn… Accur… 0.952 NA boot 25. 1. <list…
#> # ... with 15 more rows, and 2 more variables: tune <list>, seeds <list>By default the tibble package prints at most 20 rows and only 10 rows for larger tibbles. With leadr::peak, we can peak at the ranking of the first model and those in the surrounding positions:
board() %>%
peak(1)
#> # A tibble: 10 x 13
#> rank id dir model metric score public method num group index
#> <dbl> <id> <chr> <chr> <chr> <dbl> <dbl> <chr> <dbl> <dbl> <list>
#> 1 16. 24 models… rf Accur… 0.950 NA boot 25. 23. <list…
#> 2 17. 19 models… rf Accur… 0.949 NA boot 25. 18. <list…
#> 3 18. 8 models… rf Accur… 0.949 NA boot 25. 7. <list…
#> 4 19. 11 models… rf Accur… 0.946 NA boot 25. 10. <list…
#> 5 20. 3 models… rf Accur… 0.946 NA boot 25. 3. <list…
#> 6 21. 10 models… rf Accur… 0.945 NA boot 25. 9. <list…
#> 7 22. 12 models… rf Accur… 0.944 NA boot 25. 11. <list…
#> 8 23. 1 models… rf Accur… 0.942 NA boot 25. 1. <list…
#> 9 24. 13 models… rf Accur… 0.939 NA boot 25. 12. <list…
#> 10 25. 18 models… rf Accur… 0.938 NA boot 25. 17. <list…
#> # ... with 2 more variables: tune <list>, seeds <list>We also peak at the last model ran:
board() %>%
peak(at_last())
#> # A tibble: 10 x 13
#> rank id dir model metric score public method num group index
#> <dbl> <id> <chr> <chr> <chr> <dbl> <dbl> <chr> <dbl> <dbl> <list>
#> 1 1. 25 models… rf Accur… 0.959 NA boot 25. 24. <list…
#> 2 2. 21 models… rf Accur… 0.959 NA boot 25. 20. <list…
#> 3 3. 6 models… rf Accur… 0.956 NA boot 25. 5. <list…
#> 4 4. 16 models… rf Accur… 0.955 NA boot 25. 15. <list…
#> 5 5. 2 models… rf Accur… 0.955 NA boot 25. 2. <list…
#> 6 6. 9 models… rf Accur… 0.953 NA boot 25. 8. <list…
#> 7 7. 7 models… rf Accur… 0.953 NA boot 25. 6. <list…
#> 8 8. 20 models… rf Accur… 0.953 NA boot 25. 19. <list…
#> 9 9. 17 models… rf Accur… 0.952 NA boot 25. 16. <list…
#> 10 10. 5 models… glmn… Accur… 0.952 NA boot 25. 1. <list…
#> # ... with 2 more variables: tune <list>, seeds <list>leadr::peak also takes a variable number of inputs. If we want to compare the last model to the first model, it will return the smallest tibble that contains both. If it is 20 rows or under, it will print the entire tibble.
board() %>%
peak(at_last(), 1)
#> # A tibble: 23 x 13
#> rank id dir model metric score public method num group index
#> <dbl> <id> <chr> <chr> <chr> <dbl> <dbl> <chr> <dbl> <dbl> <list>
#> 1 1. 25 models… rf Accur… 0.959 NA boot 25. 24. <list…
#> 2 2. 21 models… rf Accur… 0.959 NA boot 25. 20. <list…
#> 3 3. 6 models… rf Accur… 0.956 NA boot 25. 5. <list…
#> 4 4. 16 models… rf Accur… 0.955 NA boot 25. 15. <list…
#> 5 5. 2 models… rf Accur… 0.955 NA boot 25. 2. <list…
#> 6 6. 9 models… rf Accur… 0.953 NA boot 25. 8. <list…
#> 7 7. 7 models… rf Accur… 0.953 NA boot 25. 6. <list…
#> 8 8. 20 models… rf Accur… 0.953 NA boot 25. 19. <list…
#> 9 9. 17 models… rf Accur… 0.952 NA boot 25. 16. <list…
#> 10 10. 5 models… glmn… Accur… 0.952 NA boot 25. 1. <list…
#> # ... with 13 more rows, and 2 more variables: tune <list>, seeds <list>Thanks to pillar and crayon, leadr::peak also has special printing when used in a supported console. Here is an example of peak in the RStudio console. Notice that it highlights the peaked models in the console output.
