You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

不使用caret的随机森林回归训练验证测试及参数调优疑问

随机森林超参数调优疑问与代码分析

我把数据集拆分为70%训练集、15%验证集和15%测试集,在超参数调优阶段存在疑惑,担心操作有误,以下是我的随机森林回归代码:

1. 训练阶段

初始训练

rf_model <- ranger(y ~.,
                   data = train ,  # 注:原代码笔误将data写为date,已修正
                   num.trees = 500,
                   mtry = 5,
                   min.node.size = 100,
                   importance = "impurity")

训练集评估

pred_rf <- predict(rf_model,train)
pred_rf <- data.frame(pred = pred_rf, obs = train$y)
RMSE_rf <- RMSE(pred_rf$pred, pred_rf$obs)
R2_rf   <- (cor(pred_rf$pred, pred_rf$obs)) ^2  # 注:原代码笔误将cor写为color,已修正

2. 参数优化阶段

构建参数网格

hyper_grid <- expand.grid(mtry = seq(3, 12, by = 4),
                          sample_size = c(0.5,1),
                          min.node.size = seq(20, 500, by = 100),
                          MSE = as.numeric(NA),
                          R2 = as.numeric(NA),
                          OOB_RMSE = as.numeric(NA)
)

基于OOB误差搜索最优模型

for (i in 1:nrow(hyper_grid)) {
  model <- ranger(formula = y ~ .,
                  data = train,  # 注:原代码笔误将data写为date,已修正
                  num.trees = 500,
                  mtry = hyper_grid$mtry[i],
                  sample.fraction = hyper_grid$sample_size[i],
                  min.node.size = hyper_grid$min.node.size[i],
                  importance = "impurity",
                  replace = TRUE,
                  oob.error = TRUE,
                  verbose = TRUE
  )           

  hyper_grid$OOB_RMSE[i] <- sqrt(model$prediction.error)    
  hyper_grid[i, "MSE"] <- model$prediction.error
  hyper_grid[i, "R2"] <- model$r.squared
  hyper_grid[i, "OOB_RMSE"] <- sqrt(model$prediction.error)
}

选择并构建最终模型

x <- hyper_grid[which.min(hyper_grid$OOB_RMSE), ]
rf_fit_model <- ranger(formula = y ~ .,
                       data = train,  # 注:原代码笔误将data写为date,已修正
                       num.trees = 100,
                       mtry = x$mtry,
                       sample.fraction = x$sample_size,
                       min.node.size = x$min.node.size,
                       oob.error = TRUE,
                       verbose = TRUE,
                       importance = "impurity"
)

验证集评估

rf_predict_val <- predict(rf_fit_model, validation)
rf_predict_val <- as.data.frame(rf_predict_val[1])
names(rf_predict_val) <- "pred"
rf_predict_val <- data.frame(pred = rf_predict_val, obs = validation$y)
RMSE_rf_fit <- RMSE(rf_predict_val$pred, rf_predict_val$obs)  # 注:原代码缺少括号,已修正语法
R2_rf_fit <- (cor(rf_predict_val$pred, rf_predict_val$obs)) ^ 2

核心疑问

  1. 是否需要用测试集重复评估?
  2. 目前的验证集是不是没发挥有效作用?
  3. 因为caret的交叉验证运行极慢,所以想手动实现调优,当前的做法是否正确?

对比用的caret代码(运行极慢)

ctrl <- trainControl(method = "repeatedcv", 
                     repeats = 10)

grid <- expand.grid(interaction.depth = seq(1, 7, by = 2),
                    n.trees = 1000,
                    shrinkage = c(0.01,0.1),
                    n.minobsinnode = 50)

gbmTune <- train(y ~ ., data = train,
                 method = "gbm",
                 tuneGrid = grid,
                 verbose = TRUE,
                 trControl = ctrl)

解答

1. 测试集必须用,且仅用一次

测试集是完全独立的“未知数据模拟”,用来给出模型最终的无偏性能结果。你当前仅用验证集评估,调优过程已间接用到验证集信息,最终必须用测试集做确认,避免过拟合到验证集。

2. 验证集的作用可优化

你现在仅用验证集评估最终模型,其实可以把它作为参数筛选的辅助依据:比如在OOB误差最小的前3组参数里,选验证集RMSE最低的组合,这样能降低OOB偶然最优的风险,但注意不要反复用验证集调参,否则会过拟合验证集。

3. 手动实现的做法可行,但需优化细节

  • 先修正代码里的语法笔误(data/date、cor/color、RMSE调用括号),否则代码无法正常运行。
  • 保持树的数量一致:参数搜索用了500棵树,最终模型却只用100棵,会导致性能下降,建议统一为500或1000棵。
  • 避免过拟合OOB:如果参数网格较大,可能出现OOB误差偶然最优的情况,结合验证集结果筛选更稳妥。
  • 替代caret的快速交叉验证:如果觉得caret慢,可手动在训练集内部做3-5折交叉验证,取平均性能选参数,比repeatedcv快很多,也比仅用OOB更可靠。

内容的提问来源于stack exchange,提问作者j_3265

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 21:20:51