R 中的随机森林回归器模型



我目前正在使用Python进行随机森林回归器模型:

rfr = RandomForestRegressor(random_state=42)
param_grid = {'bootstrap': [True],
'max_depth': [10, 30, 50],
'n_estimators': [200, 400, 600]}
CV = RandomizedSearchCV(estimator = rfr, param_distributions = param_grid, n_iter = 5, cv = 5, verbose=2, random_state=42, n_jobs = -1)
CV.fit(x_train, y_train)
print('best model:', CV.best_params_,'nbest score: %.2f' % CV.best_score_)

如何在 R 中重新编码它们?特别是对于 RFR、param_grid 和 CV?

你最好的选择将是caret包。这个包实际上没有模型,它就像一个框架。例如,训练caret模型时,默认模型来自randomForest::randomForest

不需要或建议进行编码。我不知道有任何模型需要您在 R 中编码分类数据。但是,确保数据中的数据类型正确始终很重要。

使用这些方法没有实例化。

以下是您需要查看的一些关键功能以及caret库中的原因。

  • createDataPartition:拆分数据;训练/测试/验证(随心所欲)
  • train:训练模型
  • trainControl:用于设置是否要引导,交叉验证,重复交叉验证(以及更多),要执行的操作次数以及重复次数。
  • modelLookup:这将告诉您想要可以为您选择的模型类型设置控件。例如,如果你想使用randomForest::randomForestmodelLookup告诉我们你只能网格mtry;如果你使用ranger::ranger(另一个库的随机森林),modelLookup告诉我们你可以网格mtrysplitrulemin.node.size。(这两种随机森林模型都适用于分类和回归。

有一个很棒的数字手册caret,但它有点过时了(我相信现在有更多的模型;我认为也有一些不同的默认值)。你可以在这里找到它。

我将在我的示例中使用ranger。 在ranger模型中:

  • n_estimators相当于num.trees
  • max_depth相当于max.depth

此外,当方法设置为ranger时,可以将?ranger::ranger帮助中显示的所有参数添加到train()

运行此代码时,无需调用库ranger,但必须安装包。

从一些数据和数据准备开始(任意选择)。

library(tidyverse)
library(caret)
data("midwest")
midwest <- midwest[, c(3:6, 17:20, 27)] %>% 
mutate(state = factor(state), inmetro = factor(inmetro))

现在,我将拆分数据以分离 70/30 的验证集。

# by setting a char/factor field, it's automatically stratified
set.seed(35)
tr <- createDataPartition(midwest$state, p = .7, list = F)

我将向您展示如何使用modelLookup来查找要使用的模型。例如,如果您想查看哪些模型使用了包含单词"深度"的参数。(模型可以是基于决策树的、神经网络或任何其他类型的模型;假设从来都不安全!)

modelLookup() %>% 
filter(str_detect(parameter, "depth"))
#          model         parameter              label forReg forClass probModel
# 1          ada          maxdepth     Max Tree Depth  FALSE     TRUE      TRUE
# 2       AdaBag          maxdepth     Max Tree Depth  FALSE     TRUE      TRUE
# 3  AdaBoost.M1          maxdepth     Max Tree Depth  FALSE     TRUE      TRUE
# 4   blackboost          maxdepth     Max Tree Depth   TRUE     TRUE      TRUE
# 5      bstTree          maxdepth     Max Tree Depth   TRUE     TRUE     FALSE
# 6       ctree2          maxdepth     Max Tree Depth   TRUE     TRUE      TRUE
# 7    deepboost        tree_depth         Tree Depth  FALSE     TRUE     FALSE
# 8          gbm interaction.depth     Max Tree Depth   TRUE     TRUE      TRUE
# 9      gbm_h2o         max_depth     Max Tree Depth   TRUE     TRUE      TRUE
# 10         pre          maxdepth     Max Tree Depth   TRUE     TRUE      TRUE
# 11      rFerns             depth         Fern Depth  FALSE     TRUE     FALSE
# 12     rfRules          maxdepth Maximum Rule Depth   TRUE     TRUE     FALSE
# 13      rpart2          maxdepth     Max Tree Depth   TRUE     TRUE      TRUE
# 14     xgbDART         max_depth     Max Tree Depth   TRUE     TRUE      TRUE
# 15     xgbTree         max_depth     Max Tree Depth   TRUE     TRUE      TRUE 
# forReg means for regression; forClass means for classification; prob means probability

正如我所说,我将使用ranger.

modelLookup("ranger")
#    model     parameter                         label forReg forClass probModel
# 1 ranger          mtry #Randomly Selected Predictors   TRUE     TRUE      TRUE
# 2 ranger     splitrule                Splitting Rule   TRUE     TRUE      TRUE
# 3 ranger min.node.size             Minimal Node Size   TRUE     TRUE      TRUE 

使用此信息,我可以创建我的调优网格。

tG <- expand.grid(mtry = c(3, 4, 6),                       # variables to split
splitrule = c("extratrees", "variance"), # model training btw splits
min.node.size = c(3, 5, 7))              # min qty obs at each node

我将设置重复的交叉验证。

# establish how to train
tC <- trainControl(method = "repeatedcv", repeats = 5)

是时候训练模型了。我想指出的是,我在train中记录参数的方式部分与train函数记录的内容有关,但参数

# using formula (that's tilde period comma to say 'and everything else')
set.seed(35)
fit <- train(poptotal~.,  
data = midwest[tr, ], tuneGrid = tG, trControl = tC,
method = "ranger", importance = "permutation", 
scale.permutation.importance = T)
# Random Forest 
# 
# 309 samples
#   8 predictor
# 
# No pre-processing
# Resampling: Cross-Validated (10 fold, repeated 5 times) 
# Summary of sample sizes: 281, 278, 277, 277, 277, 278, ... 
# Resampling results across tuning parameters:
# 
#   mtry  splitrule   min.node.size  RMSE       Rsquared   MAE     
#   3     extratrees  3               97994.57  0.9540533  23562.39
#   3     extratrees  5               99066.61  0.9523176  24111.05
#   3     extratrees  7               99757.54  0.9495842  24535.54
#   3     variance    3              114908.64  0.8855597  28326.62
#   3     variance    5              116839.06  0.8762747  28883.57
#   3     variance    7              116378.17  0.8766985  29118.59
#   4     extratrees  3               92825.54  0.9693964  20950.30
#   4     extratrees  5               93879.65  0.9677459  21342.85
#   4     extratrees  7               94963.99  0.9653268  21856.72
#   4     variance    3              108533.52  0.9188248  25262.68
#   4     variance    5              111004.38  0.9047721  26059.75
#   4     variance    7              111046.46  0.9068934  26089.53
#   6     extratrees  3               89392.68  0.9779004  18832.46
#   6     extratrees  5               90215.15  0.9764424  19059.87
#   6     extratrees  7               91033.46  0.9753090  19408.73
#   6     variance    3              101022.50  0.9531625  21934.87
#   6     variance    5              100856.81  0.9541640  21965.35
#   6     variance    7              102664.47  0.9506119  22347.86
# 
# RMSE was used to select the optimal model using the smallest value.
# The final values used for the model were mtry = 6, splitrule = extratrees and min.node.size = 3. 

我可以在没有所有额外信息的情况下对此模型的性能进行排队,查看 Ranger 如何对结果进行评分,并查看验证集上的预测。

p.tr <- predict.train(fit)                   # collect predicted values
postResample(p.tr, midwest[tr, ]$poptotal)   # calculate metrics
#         RMSE     Rsquared          MAE 
# 9.928424e+04 9.710269e-01 7.736478e+03  
fit$finalModel # DRASTICALLY different; these metrics are based on OOB!
# validation data
p.ts <- predict(fit, midwest[-tr, ])        # collect predicted values
postResample(p.ts, midwest[-tr, ]$poptotal) # calculate metrics
#         RMSE     Rsquared          MAE 
# 5.844063e+04 9.528124e-01 1.561766e+04  


----其他解释----

围绕函数的其他解释以及它们与 Python 等效项的关系。

createDataPartititiontrain_test_split

如我的示例所示使用createDataPartition时,它将返回将为训练样本保留的行索引值列表。它不返回四个单独的列表或向量,只返回一个。(不像train_test_split)

我用于createDataPartion的参数是数据向量,分区百分比,并且我想要一个向量,而不是返回的列表。

对于数据向量,最简单的方法是使用数据集的列。但是,长度与整个数据集中的行数相同的向量将执行相同的操作。

当我编写midwest[tr, ]时,我根据createDataPartition的输出选择了数据集中的特定行。

就您的调用而言:test_inds = createDataPartition(y= 1:length(y), p = 0.2, list = F)(从删除不必要的内容开始)。

现在,如果您有一个数据框(大多数模型都需要),则没有理由在数据框中拆分XY。如果这样做,则不能将formula用作参数。但是,如果您想完成额外的工作,则可以。如果你这样做,那么而不是formula,你需要参数xy

使用上面的示例数据,我可以写

fitr <- train(x = midwest[tr, -3], y = midwest[tr, ]$poptotal, method = "ranger")

使用您评论中的示例,使用我示例中的相同模型,您将编写

fitr <- train(x = X_train, y = y_train, method = "ranger")

如果你有一个数据集,df1如下所示:

#            y        x1        x2       x3
# 1  -1.395833 10.707157 5903.8725 0.500412
# 2  -1.955195 10.144033 1836.2500 0.501276
# 3  -2.174564 10.501878 4371.2319 0.499002
# 4   3.147530  8.838499 1783.0806 0.500391
# 5  -4.119006  7.927986 2463.0425 0.500571
# 6  -3.706576  7.608005  878.8885 0.500297
# 7  -0.525999 11.299934 3388.3888 0.497471
# 8  -0.517687 11.473103 5006.4363 0.497595
# 9   4.250880 10.151943 5366.0677 0.499125
# 10  1.530718 11.688670 3097.4672 0.500691 

使用代码中的分区(其中p = .2),设置为test_inds,假设它返回了一个带有c(1, 2, 4, 8)的向量

set.seed(34)
test_inds <- createDataPartition(df1$x1, p = .2, list = F)

现在当我使用时,df1[-test_inds, ]我会删除行

#            y        x1        x2       x3
# 3  -2.174564 10.501878 4371.2319 0.499002
# 5  -4.119006  7.927986 2463.0425 0.500571
# 6  -3.706576  7.608005  878.8885 0.500297
# 7  -0.525999 11.299934 3388.3888 0.497471
# 9   4.250880 10.151943 5366.0677 0.499125
# 10  1.530718 11.688670 3097.4672 0.500691 

如果我想像你一样拆分它,我可以。

X_train <- df1[-test_inds, -1]
Y_train <- df1[-test_inds, 1]

创建Y_train的另一种方法:

Y_train <- df1[-test_inds, ]$y # same as other Y_train, different way of coding

这些train函数调用是相同的

fit <- train(y~., data = df1[-test_inds, ]) 
fit1 <- train(y ~ . , data = df1[-test_inds, ])
fit2 <- train(y~., data = df1, subset = -test_inds)
fit3 <- train(y ~ x1 + x2 + x3, data = df1[-test_inds, ]) 
fit4 <- train(x = df1[-test_inds, -1], y = df1[-test_inds, 1])
fit5 <- train(x = df1[ , -1], y = df1$y, subset = -test_inds)
fit6 <- train(x = df1[ , -1], y = df1[ , 1], subset = -test_inds)
fit7 <- train(x = X_train, y = Y_train)

如果要测试这些,下面是重新创建df1的代码

df1 <- structure(list(
y = c(-1.395833, -1.955195, -2.174564, 3.14753, -4.119006, 
-3.706576, -0.525999, -0.517687, 4.25088, 1.530718), 
x1 = c(10.707157, 10.144033, 10.501878, 8.838499, 7.927986, 
7.608005, 11.299934, 11.473103, 10.151943, 11.68867), 
x2 = c(5903.872547, 1836.24996, 4371.231904, 1783.080566, 2463.042469, 
878.888451, 3388.388772, 5006.436295, 5366.067723, 3097.467151), 
x3 = c(0.500412, 0.501276, 0.499002, 0.500391, 0.500571, 
0.500297, 0.497471, 0.497595, 0.499125, 0.500691)),
class = "data.frame", row.names = c(NA, -10L))

测试时,必须在每个模型之间设置种子。如果将方法设置为ranger,则可以在train中使用seed中的参数。

例如:

fit <- train(y~., data = df1[-test_inds, ], method = "ranger", seed = 35) 

set.seed(35)
fit <- train(y~., data = df1[-test_inds, ]) 

set.seed(35)
fit <- train(y~., data = df1[-test_inds, ]) 
set.seed(35)
fit1 <- train(y ~ . , data = df1[-test_inds, ])
set.seed(35)
fit2 <- train(y~., data = df1, subset = -test_inds)
set.seed(35)
fit3 <- train(y ~ x1 + x2 + x3, data = df1[-test_inds, ]) 
set.seed(35)
fit4 <- train(x = df1[-test_inds, -1], y = df1[-test_inds, 1])
set.seed(35)
fit5 <- train(x = df1[ , -1], y = df1$y, subset = -test_inds)
set.seed(35)
fit6 <- train(x = df1[ , -1], y = df1[ , 1], subset = -test_inds)
set.seed(35)
fit7 <- train(x = X_train, y = Y_train)
fit$results
#   mtry     RMSE  Rsquared      MAE   RMSESD RsquaredSD    MAESD
# 1    2 3.637085 0.8258667 3.413510 1.326739  0.3020918 1.274708
# 2    3 3.730395 0.8297140 3.481763 1.378773  0.2605953 1.345170 
fit1$results
#   mtry     RMSE  Rsquared      MAE   RMSESD RsquaredSD    MAESD
# 1    2 3.637085 0.8258667 3.413510 1.326739  0.3020918 1.274708
# 2    3 3.730395 0.8297140 3.481763 1.378773  0.2605953 1.345170 
fit2$results
#   mtry     RMSE  Rsquared      MAE   RMSESD RsquaredSD    MAESD
# 1    2 3.637085 0.8258667 3.413510 1.326739  0.3020918 1.274708
# 2    3 3.730395 0.8297140 3.481763 1.378773  0.2605953 1.345170 
fit3$results
#   mtry     RMSE  Rsquared      MAE   RMSESD RsquaredSD    MAESD
# 1    2 3.637085 0.8258667 3.413510 1.326739  0.3020918 1.274708
# 2    3 3.730395 0.8297140 3.481763 1.378773  0.2605953 1.345170 
fit4$results
#   mtry     RMSE  Rsquared      MAE   RMSESD RsquaredSD    MAESD
# 1    2 3.637085 0.8258667 3.413510 1.326739  0.3020918 1.274708
# 2    3 3.730395 0.8297140 3.481763 1.378773  0.2605953 1.345170 

如果你不使用参数method,默认值是method = "rf",这与method = "ranger"不同,所以它们不会等价

相关内容

  • 没有找到相关文章

最新更新