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

为何随机森林模型训练集预测AUC值极高?是否存在过拟合?

问题解答:训练集AUC=1的原因分析

核心结论

训练集AUC=1既不是代码操作错误,也不是严格意义上的“过拟合”,而是随机森林在训练数据上完全拟合的正常表现,尤其是你设置了nodesize=1的情况下。

具体原因拆解

1. 随机森林参数nodesize=1的影响

你选中的最优模型参数是ntrees=1000和nodesize=1,其中nodesize是随机森林中每棵树的叶子节点最小样本数。当nodesize=1时:

  • 每棵决策树会持续分裂,直到每个叶子节点只包含一个样本
  • 这意味着每棵树都能完全“记住”训练数据的所有样本特征和标签,集成后的随机森林自然能完美预测训练集,因此AUC=1是必然结果

2. 代码操作的注意点

你的代码没有语法错误,但存在一个关键的实践缺陷:

  • 未划分训练集和测试集:你直接用整个Sonar数据集训练模型,然后在同一个数据集上预测,得到的AUC=1只是模型对训练数据的拟合能力,完全不能反映模型的泛化性能
  • 交叉验证得到的ROC=0.953才是模型泛化能力的合理估计,这个数值说明模型在未见过的折叠数据上表现良好,并没有严重过拟合

另外,循环内重复设置set.seed(123)会导致每次训练的随机种子相同,可能降低结果的随机性,建议将种子设置放在循环外部。

验证建议

如果你想确认模型是否过拟合,需要:

  • 将Sonar数据集划分为训练集(比如70%)和测试集(30%)
  • 用训练集训练模型,然后在测试集上计算AUC
  • 如果测试集AUC远低于训练集的1.0,才说明模型存在过拟合

修正后的代码示例(划分训练测试集)

library(mlbench)
data(Sonar)
# 划分训练集和测试集
set.seed(1234)
train_idx <- createDataPartition(Sonar$Class, p = 0.7, list = FALSE)
train_data <- Sonar[train_idx, ]
test_data <- Sonar[-train_idx, ]

library(caret)
set.seed(1234)
cv_folds <- createFolds(train_data$Class, k = 10, returnTrain = TRUE)

ctrl <- trainControl(method = "cv",
                     number = 10,
                     search = 'grid',
                     classProbs = TRUE,
                     savePredictions = TRUE,
                     index = cv_folds,
                     summaryFunction = twoClassSummary) 
tuneGrid <- expand.grid(.mtry = c(1:10))
ntrees <- c(500, 1000, 1500, 2000, 2500)    
nodesize <- c(1,3,5,7,10)

params <- expand.grid(ntrees = ntrees,
                      nodesize = nodesize)

store_maxnode <- vector("list", nrow(params))
set.seed(123) # 种子放在循环外
for(i in 1:nrow(params)){
  nodesize_val <- params[i,2]
  ntree_val <- params[i,1]
  rf_model <- train(Class~.,
                    data = train_data, # 用训练集训练
                    method = "rf",
                    importance=TRUE,
                    metric = "ROC",
                    tuneGrid = tuneGrid,
                    trControl = ctrl,
                    ntree = ntree_val,
                    nodesize = nodesize_val)
  store_maxnode[[i]] <- rf_model
}
names(store_maxnode) <- paste("ntrees:", params$ntrees,
                              "nodesize:", params$nodesize)

tune_result<-lapply(store_maxnode, function(x) x$results[x$results$ROC == max(x$results$ROC),])
tune_result

# 保存最优模型并在测试集评估
best_model<-store_maxnode$`ntrees: 1000 nodesize: 1`
# 训练集预测
train_pred<-predict(best_model,newdata=train_data,type="prob")
train_df<-data.frame(pred=train_pred$R,origin=ifelse(train_data$Class=="R",1,0))
train_pred_obj <- ROCR::prediction(train_df[["pred"]],train_df[["origin"]])
train_auc <- ROCR::performance(train_pred_obj, measure = "auc")
cat("训练集AUC:", train_auc@y.values[[1]], "\n")

# 测试集预测
test_pred<-predict(best_model,newdata=test_data,type="prob")
test_df<-data.frame(pred=test_pred$R,origin=ifelse(test_data$Class=="R",1,0))
test_pred_obj <- ROCR::prediction(test_df[["pred"]],test_df[["origin"]])
test_auc <- ROCR::performance(test_pred_obj, measure = "auc")
cat("测试集AUC:", test_auc@y.values[[1]], "\n")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 21:23:09