train 函数中未使用的参数

unused argument in train function

大家好

我在使用 RF 超参数调整时遇到代码问题。算法(模拟退火)给出了 4000 的 RMSE 值。我不确定它是从哪里执行这个计算的,因为在代码中我没有指定任何 grid/values?代码如下,最初是为 SVM 编写的,但我为 RF 进行了编辑。

svm_obj <- function(param, maximize = FALSE) {
  mod <- train(Effort ~ ., data = tr,
               method = "rf",
               preProc = c("center", "scale", "zv"),
               metric = "MAE",
               trControl = ctrl,
               tuneGrid = data.frame(mtry = 10^(param[1])))
               ##, sigma = 10^(param[2])))
  if(maximize)
    -getTrainPerf(mod)[, "TrainRMSE"] else
      getTrainPerf(mod)[, "TrainRMSE"]
}

## Simulated annealing from base R
set.seed(45642)
san_res <- optim(par = c(0), fn = svm_obj, method = "SANN",
                 control = list(maxit = 10))

The answer I get is: $value
[1] 4487.821

$counts
function gradient 
      10       NA 

$convergence
[1] 0

$message
NULL

嗯,我不知道你用什么值来调用你的函数,所以很难发现错误。

但是,mtry 是一个需要介于 1 和列数之间的值,而在我看来您可能将其设置为 10 的某次幂 - 这很可能超出范围 :)

mtry是rf用来分裂树的变量个数,不能大于预测变量的列数。

让我们做一个不起作用的模型:

  mod <- train(Effort ~ ., data = tr,
               method = "rf",
               preProc = c("center", "scale", "zv"),
               metric = "RMSE",
               trControl = ctrl,
               tuneGrid = data.frame(mtry = ncol(tr)+1)
               )

您看到一条警告:

There were 11 warnings (use warnings() to see them)

和结果,和最终模型不一致:

mod$results

 mtry     RMSE  Rsquared      MAE   RMSESD RsquaredSD     MAESD
1   12 2.203626 0.9159377 1.880211 0.979291  0.1025424 0.7854203

 mod$finalModel

Call:
 randomForest(x = x, y = y, mtry = param$mtry)
               Type of random forest: regression
                     Number of trees: 500
No. of variables tried at each split: 10

          Mean of squared residuals: 6.088637
                    % Var explained: 82.7

因此,尽管您指定了 mtry=12,但默认的 randomForest 函数会将其降低到 10,这是合理的。但是如果你在 optim 上尝试这个,你永远不会得到有意义的东西,一旦你超过 ncol(tr)-1.

如果你没有那么多变量,使用tuneLength或者指定mtry来使用会容易很多。让我们从您期望的结果开始,只需指定 mtry:

library(caret)
library(randomForest)

ctrl = trainControl(method="cv",repeats=3)
#use mtcars
tr = mtcars
# set mpg to be Effort so your function works
colnames(tr)[1] = "Effort"

TG =  data.frame(mtry=1:10)
mod <- train(Effort ~ ., data = tr,
               method = "rf",
               preProc = c("center", "scale", "zv"),
               metric = "RMSE",
               trControl = ctrl,
               tuneGrid = TG)

mod$results
   mtry     RMSE  Rsquared      MAE   RMSESD RsquaredSD    MAESD
1     1 2.725944 0.8895202 2.384232 1.350958  0.1592133 1.183400
2     2 2.498627 0.9012830 2.192391 1.276950  0.1375281 1.200895
3     3 2.506250 0.8849148 2.168141 1.229709  0.1562686 1.173904
4     4 2.503700 0.8891134 2.170633 1.249049  0.1478276 1.168831
5     5 2.480846 0.8837597 2.148329 1.250889  0.1540574 1.191068
6     6 2.459317 0.8872104 2.126315 1.196187  0.1554423 1.128351
7     7 2.493736 0.8736399 2.165258 1.158384  0.1766644 1.082568
8     8 2.530672 0.8768546 2.199941 1.224193  0.1681286 1.127467
9     9 2.547422 0.8757422 2.196878 1.222921  0.1704655 1.130261
10   10 2.514791 0.8720315 2.184602 1.224944  0.1740556 1.093184

也许像 6 这样的东西是你能得到的最好的 mtry。

@Javed @Wolf

请注意,id 确实对调整 mtry 有意义。 mtry 将影响您种植的树之间的相关性(因此模型的方差),并且它是非常特定于问题的,因此最佳值可能会根据您拥有的特征数量和它们之间的相关性而变化。 然而,调整与偏差相关的超参数(最大深度和其他 stopping/pruning 规则)是毫无用处的。这需要很多时间,而且效果往往不显着。