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

如何用ranger包计算随机森林中MSE最低的树的数量?

问题描述

我正在遵循一个随机森林示例,想要把randomForest包的代码转换成ranger包的等价代码。原randomForest代码如下:

# default RF model
m1 <- randomForest(
  formula = Sale_Price ~ .,
  data    = ames_train
)

# number of trees with lowest MSE
btree <- which.min(m1$mse)

使用ranger包时,无法直接获取MSE最低的树的数量,该如何计算并把结果存入btree变量?

我的测试代码如下:

library(rsample)      # data splitting 
library(randomForest) # basic implementation
library(ranger)       # a faster implementation of randomForest

set.seed(123)
ames_split <- initial_split(AmesHousing::make_ames(), prop = .7)
ames_train <- training(ames_split)
ames_test  <- testing(ames_split)

# for reproduciblity
set.seed(123)

# default RF model
m1 <- randomForest(
  formula = Sale_Price ~ .,
  data    = ames_train
)

# the equivalent in ranger
m1 <- ranger(
      formula = Sale_Price ~ .,
      data    = ames_train
    )

# number of trees with lowest MSE (randomForest package)
btree <- which.min(m1$mse)

根据ranger文档说明:

prediction.error: 整体袋外预测误差。分类任务为准确率(错误分类观测的比例),概率估计为Brier分数,回归任务为均方误差(MSE),生存分析为1减去Harrell's C-index。

我尝试了以下代码,但结果明显不对:

m1 <- ranger(
  formula = Sale_Price ~ .,
  data    = ames_train
)

# number of trees with highest r2
btree = which.max(m1$prediction.error)
print(btree)

输出结果:

[1] 1

解决方案

问题核心是:ranger默认仅返回最终的整体OOB MSE,不会保存每棵树逐步累积的MSE序列。要实现和randomForest相同的功能,需要在训练时开启相关参数,手动计算每增加一棵树后的累积OOB MSE。

具体实现代码

set.seed(123)
# 训练ranger模型时开启袋内样本记录,树数量与randomForest默认一致(500)
m1_ranger <- ranger(
  formula = Sale_Price ~ .,
  data    = ames_train,
  keep.inbag = TRUE,
  predict.all = TRUE,
  num.trees = 500
)

# 提取每棵树的预测值、袋内样本标记,以及真实房价
tree_preds <- m1_ranger$predictions
inbag_counts <- m1_ranger$inbag.counts
actual_prices <- ames_train$Sale_Price

# 初始化累积预测和、OOB样本计数、MSE存储向量
cumulative_pred_sum <- numeric(nrow(ames_train))
oob_tree_count <- numeric(nrow(ames_train))
cumulative_mse <- numeric(500)

for (k in 1:500) {
  # 获取当前树的OOB样本索引
  oob_idx <- inbag_counts[[k]] == 0
  # 更新OOB样本的预测和与计数
  cumulative_pred_sum[oob_idx] <- cumulative_pred_sum[oob_idx] + tree_preds[oob_idx, k]
  oob_tree_count[oob_idx] <- oob_tree_count[oob_idx] + 1
  
  # 计算当前累积的OOB预测均值(避免除以0)
  avg_pred <- ifelse(oob_tree_count > 0, cumulative_pred_sum / oob_tree_count, NA)
  # 计算当前累积MSE
  cumulative_mse[k] <- mean((actual_prices - avg_pred)^2, na.rm = TRUE)
}

# 找到MSE最小的树数量
btree <- which.min(cumulative_mse)
print(btree)

关键说明

  • keep.inbag = TRUE:让ranger保存每棵树的袋内样本计数,用于识别OOB样本
  • predict.all = TRUE:返回每个样本在每棵树上的预测值,用于逐步累积计算
  • 循环中逐棵树更新OOB样本的预测均值,计算对应MSE,最终通过which.min找到最优树数量

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 00:35:22