Как использовать значения expand.grid для запуска различных комбинаций гиперпараметров модели для рейнджера в R - PullRequest
0 голосов
/ 31 марта 2020

Я видел различные сообщения о том, как выбрать независимые переменные для модели с помощью expand.grid, а затем создать формулу на основе этого выбора. Однако я заранее готовлю свои входные таблицы и сохраняю их в виде списка.

library(ranger)
data(iris)
Input_list <- list(iris1 = iris, iris2 = iris)  # let's assume these are different input tables

Мне довольно интересно попробовать все возможные комбинации гиперпараметров для данного алгоритма (здесь: Случайный лес, использующий ranger) для моего списка входных таблиц. Для настройки сетки я делаю следующее:

hyper_grid <- expand.grid(
  Input_table = names(Input_list),
  Trees = c(10, 20),
  Importance = c("none", "impurity"),
  Classification = TRUE,
  Repeats = 1:5,
  Target = "Species")

> head(hyper_grid)
  Input_table Trees Importance Classification Repeats  Target
1       iris1    10       none           TRUE       1 Species
2       iris2    10       none           TRUE       1 Species
3       iris1    20       none           TRUE       1 Species
4       iris2    20       none           TRUE       1 Species
5       iris1    10   impurity           TRUE       1 Species
6       iris2    10   impurity           TRUE       1 Species

Мой вопрос: как лучше всего передать эти значения в модель? В настоящее время я использую for loop:

for (i in 1:nrow(hyper_grid)) {
  RF_train <- ranger(
    dependent.variable.name = hyper_grid[i, "Target"], 
    data = Input_list[[hyper_grid[i, "Input_table"]]],  # referring to the named object in the list
    num.trees = hyper_grid[i, "Trees"], 
    importance = hyper_grid[i, "Importance"], 
    classification = hyper_grid[i, "Classification"])  # otherwise regression is performed
  print(RF_train)
}

итерацию по каждой строке сетки. Но для начала я должен сказать модели сейчас, является ли это классификацией или регрессией. Я предполагаю, что коэффициент Species преобразуется в цифры c уровней факторов, поэтому регрессия происходит по умолчанию. Есть ли способ предотвратить это, а также использовать, например, apply для этой роли? Этот способ итерации также приводит к беспорядочным вызовам функций:

Call:
 ranger(dependent.variable.name = hyper_grid[i, "Target"], data = Input_list[[hyper_grid[i,      "Input_table"]]], num.trees = hyper_grid[i, "Trees"], importance = hyper_grid[i,      "Importance"], classification = hyper_grid[i, "Classification"])

Во-вторых: в действительности выходные данные модели тогда явно не распечатываются, но я сразу фиксирую важные результаты (в основном RF_train$confusion.matrix) и запишите результаты в расширенную версию hyper_grid в той же строке с входными параметрами. Является ли это представление дорогостоящим? Потому что, если я сохраню объекты рейнджера, у меня возникнут проблемы с памятью.

Спасибо!

1 Ответ

1 голос
/ 31 марта 2020

Я думаю, что лучше всего обернуть обучение и извлечь нужные значения в функцию. Точки (...) необходимы для использования с приведенной ниже функцией purrr::pmap.

fit_and_extract_metrics <- function(Target, Input_table, Trees, Importance, Classification, ...) {
  RF_train <- ranger(
    dependent.variable.name = Target, 
    data = Input_list[[Input_table]],  # referring to the named object in the list
    num.trees = Trees, 
    importance = Importance, 
    classification = Classification)  # otherwise regression is performed

  data.frame(Prediction_error = RF_train$prediction.error,
             True_positive = RF_train$confusion.matrix[1])
}

Затем вы можете добавить результаты в виде столбца, сопоставив строки, например, purrr::pmap:

hyper_grid$res <- purrr::pmap(hyper_grid, fit_and_extract_metrics)

При таком сопоставлении функция применяется строка за строкой, поэтому вы не должны сталкиваться с проблемами с памятью.

Результатом purrr::pmap является список, что означает, что столбец res содержит список для каждой строки. Это можно отменить, используя tidyr::unnest, чтобы распространить элементы этого списка по всему фрейму данных.

tidyr::unnest(hyper_grid, res)

Я думаю, что этот подход очень элегантен, но требует некоторых знаний tidyverse . Я очень рекомендую эту книгу , если вы хотите узнать больше об этом. Глава 25 (Многие модели) описывает подход, аналогичный тому, который я здесь использую.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...