Настройка гиперпараметров с использованием пакета pure ranger в R

Мне нравится скорость пакета ranger для создания случайных моделей леса, но не вижу, как настроить mtry или количество деревьев. Я понимаю, что могу сделать это с помощью синтаксиса train () каретки, но я предпочитаю увеличение скорости за счет использования чистого рейнджера.

Вот мой пример создания базовой модели с использованием рейнджера (который отлично работает):

library(ranger)
data(iris)

fit.rf = ranger(
  Species ~ .,
  training_data = iris,
  num.trees = 200
)

print(fit.rf)

Глядя на официальную документацию по параметрам настройки, кажется, что функция csrf () может предоставлять возможность настраивать гиперпараметры, но я не могу понять синтаксис правильно:

library(ranger)
data(iris)

fit.rf.tune = csrf(
  Species ~ .,
  training_data = iris,
  params1 = list(num.trees = 25, mtry=4),
  params2 = list(num.trees = 50, mtry=4)
)

print(fit.rf.tune)

Результаты в:

Error in ranger(Species ~ ., training_data = iris, num.trees = 200) : 
  unused argument (training_data = iris)

И я бы предпочел настроиться с помощью обычного (читай: не-csrf) алгоритма RF, который предоставляет рейнджер. Любая идея относительно решения настройки гиперпараметров для любого пути в рейнджере? Спасибо!


person Levi Thatcher    schedule 29.05.2016    source источник


Ответы (5)


Думаю, есть как минимум две ошибки:

Во-первых, функция ranger не имеет параметра с именем training_data. Ваше сообщение об ошибке Error in ranger(Species ~ ., training_data = iris, num.trees = 200) : unused argument (training_data = iris) относится именно к этому. Вы можете увидеть это, если посмотрите на ?ranger или args(ranger).

Во-вторых, функция csrf, с другой стороны, имеет training_data в качестве входных данных, но также требует test_data. Самое главное, что эти два аргумента не имеют значений по умолчанию, что означает, что вы должны их указать. Следующее работает без проблем:

fit.rf = ranger(
  Species ~ ., data = iris,
  num.trees = 200
)

fit.rf.tune = csrf(
Species ~ .,
training_data = iris,
test_data = iris,
params1 = list(num.trees = 25, mtry=4),
params2 = list(num.trees = 50, mtry=4)
)

Здесь я только что предоставил iris как обучающий, так и тестовый набор данных. Очевидно, вы не захотите делать это в своем реальном приложении. Кроме того, обратите внимание, что ranger также принимает num.trees и mtry в качестве входных данных, так что вы можете попробовать настроить их там.

person coffeinjunky    schedule 29.05.2016
comment
Отличная информация, спасибо! Насколько вам известно, в рейнджере нет маршрута, отличного от csrf, для настройки гиперпараметров? Кроме того, Чжэюань, я изначально спросил, доступна ли опция без csrf (и не только для исправления для документированной реализации csrf). - person Levi Thatcher; 30.05.2016
comment
Очень щедро, ребята, спасибо. Просто примечание, coffeinjunky - хотя в опубликованном мною сообщении об ошибке говорилось, что я использовал функцию рейнджера, я фактически использовал функцию csrf (не уверен, что вы хотите отредактировать свой ответ). Я напишу об этом Марвину Райту (сопровождающему) по электронной почте. Спасибо еще раз! - person Levi Thatcher; 30.05.2016
comment
Кроме того, coffeinjunky, если вы редактируете, не могли бы вы добавить пример синтаксиса param1, param2 для настройки с помощью функции ranger? Спасибо! - person Levi Thatcher; 30.05.2016
comment
Просто добавьте num.trees=5 или любой другой номер, или mtry=5 или любой другой номер к своему звонку. Как в ranger(Species ~ ., data = iris, num.trees = 200, mtry=5) - person coffeinjunky; 30.05.2016

Чтобы ответить на мой (неясный) вопрос, очевидно, что у рейнджера нет встроенной функции CV / GridSearch. Однако вот как вы настраиваете гиперпараметры с помощью рейнджера (через поиск по сетке) вне каретки. Спасибо Марвину Райту (сопровождающему рейнджера) за код. Оказалось, что каретка CV с рейнджером была для меня медленной, потому что я использовал интерфейс формулы (чего следует избегать).

ptm <- proc.time()
library(ranger)
library(mlr)

# Define task and learner
task <- makeClassifTask(id = "iris",
                        data = iris,
                        target = "Species")

learner <- makeLearner("classif.ranger")

# Choose resampling strategy and define grid
rdesc <- makeResampleDesc("CV", iters = 5)
ps <- makeParamSet(makeIntegerParam("mtry", 3, 4),
                   makeDiscreteParam("num.trees", 200))

# Tune
res = tuneParams(learner, task, rdesc, par.set = ps,
           control = makeTuneControlGrid())

# Train on entire dataset (using best hyperparameters)
lrn = setHyperPars(makeLearner("classif.ranger"), par.vals = res$x)
m = train(lrn, iris.task)

print(m)
print(proc.time() - ptm) # ~6 seconds

Для любопытных эквивалент каретки:

ptm <- proc.time()
library(caret)
data(iris)

grid <-  expand.grid(mtry = c(3,4))

fitControl <- trainControl(method = "CV",
                           number = 5,
                           verboseIter = TRUE)

fit = train(
  x = iris[ , names(iris) != 'Species'],
  y = iris[ , names(iris) == 'Species'],
  method = 'ranger',
  num.trees = 200,
  tuneGrid = grid,
  trControl = fitControl
)
print(fit)
print(proc.time() - ptm) # ~2.4 seconds

В целом, каретка - это самый быстрый способ выполнить поиск по сетке с помощью ranger, если вы используете интерфейс без формул.

person Levi Thatcher    schedule 15.06.2016
comment
Спасибо за эти решения. Быстрый вопрос, можно ли включить список гиперпараметров num.tree в сетку поиска? - person philiporlando; 30.01.2019

Обратите внимание, что mlr по умолчанию отключает внутреннее распараллеливание рейнджера. Установите гиперпараметр num.threads на количество ядер, доступных для mlr увеличения:

learner <- makeLearner("classif.ranger", num.threads = 4)

В качестве альтернативы можно запустить параллельный бэкэнд через

parallelStartMulticore(4) # linux/osx
parallelStartSocket(4)    # windows

перед вызовом tuneParams для распараллеливания настройки.

person Michel    schedule 31.01.2018

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

hyper_grid <- expand.grid(
  mtry       = 1:4,
  node_size  = 1:3,
  num.trees = seq(50,500,50),
  OOB_RMSE   = 0
)

system.time(
  for(i in 1:nrow(hyper_grid)) {
    # train model
    rf <- ranger(
      formula        = Species ~ .,
      data           = iris,
      num.trees      = hyper_grid$num.trees[i],
      mtry           = hyper_grid$mtry[i],
      min.node.size  = hyper_grid$node_size[i],
      importance = 'impurity')
    # add OOB error to grid
    hyper_grid$OOB_RMSE[i] <- sqrt(rf$prediction.error)
  })
user  system elapsed 
3.17    0.19    1.36

nrow(hyper_grid) # 120 models
position = which.min(hyper_grid$OOB_RMSE)
head(hyper_grid[order(hyper_grid$OOB_RMSE),],5)
     mtry node_size num.trees     OOB_RMSE
6     2         2        50 0.1825741858
23    3         3       100 0.1825741858
3     3         1        50 0.2000000000
11    3         3        50 0.2000000000
14    2         1       100 0.2000000000

# fit best model
rf.model <- ranger(Species ~ .,data = iris, num.trees = hyper_grid$num.trees[position], importance = 'impurity', probability = FALSE, min.node.size = hyper_grid$node_size[position], mtry = hyper_grid$mtry[position])
rf.model
Ranger result

Call:
 ranger(Species ~ ., data = iris, num.trees = hyper_grid$num.trees[position], importance = "impurity", probability = FALSE, min.node.size = hyper_grid$node_size[position], mtry = hyper_grid$mtry[position]) 

    Type:                             Classification 
Number of trees:                  50 
Sample size:                      150 
Number of independent variables:  4 
Mtry:                             2 
Target node size:                 2 
Variable importance mode:         impurity 
Splitrule:                        gini 
OOB prediction error:             5.33 % 

Надеюсь, это вам поможет.

person Rafael Díaz    schedule 24.09.2018

Также существует пакет tuneRanger R, который специально разработан для настройки рейнджера и использует предопределенные параметры настройки, гиперпараметр. пространства и интеллектуальная настройка с использованием нестандартных наблюдений.

Обратите внимание, что случайный лес - это не алгоритм, настройка которого обычно имеет большое значение. Но обычно это может немного улучшить производительность.

person PhilippPro    schedule 03.08.2020