使用R中的纯游侠包进行超参数调整

Lev*_*her 8 model r random-forest hyperparameters

喜欢随机森林模型创建的游侠包的速度,但无法看到如何调整mtry或树的数量.我意识到我可以通过插入符号的train()语法来实现这一点,但我更喜欢使用纯粹的游侠来提高速度.

这是我使用游侠创建基本模型的例子(效果很好):

library(ranger)
data(iris)

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

print(fit.rf)
Run Code Online (Sandbox Code Playgroud)

查看调优选项的官方文档,似乎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)
Run Code Online (Sandbox Code Playgroud)

结果是:

Error in ranger(Species ~ ., training_data = iris, num.trees = 200) : 
  unused argument (training_data = iris)
Run Code Online (Sandbox Code Playgroud)

而且我更愿意使用常规(读取:非csrf)rf算法游侠提供.对于游侠中任何一条路径的超参数调整解决方案有任何想法吗?谢谢!

Lev*_*her 13

为了回答我(不清楚)的问题,显然游侠没有内置的CV/GridSearch功能.但是,这里是你如何使用插入符号外的游侠(通过网格搜索)进行超参数调整.感谢Marvin Wright(游侠的维护者)代码.因为我使用的是公式界面(应该避免使用),因此使用游侠的插入符号对我来说很慢.

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
Run Code Online (Sandbox Code Playgroud)

对于好奇,相当于插入符号

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
Run Code Online (Sandbox Code Playgroud)

总的来说,如果使用非公式接口,插入符号是使用游侠进行网格搜索的最快方法.


cof*_*nky 6

我认为至少有两个错误:

首先,该函数ranger没有调用参数training_data.您的错误消息Error in ranger(Species ~ ., training_data = iris, num.trees = 200) : unused argument (training_data = iris)指的是那个.你可以看到当你看到?rangerargs(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)
)
Run Code Online (Sandbox Code Playgroud)

在这里,我刚刚提供iris了培训和测试数据集.您显然不希望在实际应用程序中这样做.此外,需要注意的是ranger还需要num.treesmtry作为输入,所以你可以尝试调整它.