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

使用caret训练MLP模型出现重采样性能指标缺失值的报错问题

报错触发核心原因

这个提示本质是交叉验证过程中,部分折上的模型训练失败,输出了非数值类的预测结果(NaN/Inf),导致无法计算对应折的RMSE性能值,最终触发caret的缺失值警告。结合你编写的代码,具体触发点有三个:

  • 神经网络适配的输入尺度不匹配:caret内置的mlp方法底层是调用nnet包实现的,nnet本身不会自动对输入特征做标准化处理。而Boston数据集的特征量纲差异极大(比如税价值域是200-700,一氧化氮浓度值域是0.3-0.8),大尺度输入很容易导致网络权重更新溢出,生成NaN输出,无法计算性能指标。
  • 回归任务的参数传递失效:你代码中写的linOut = T本身是nnet包用来开启线性输出(适配连续值回归)的参数,但因为没有和必要的训练参数绑定传递,很多时候这个参数不会被底层正确接收,导致MLP默认用sigmoid输出层把结果压在(0,1)区间。训练过程中权重更新容易发散,最终在部分交叉折上生成无法计算的无效输出。
  • 调参和训练逻辑疏漏:你的调参网格只设置了隐藏层节点数size,但caret内置mlp方法的必填调参维度包含权重衰减decay,参数缺失会导致部分折的模型初始化失败;同时训练时直接传入了全量Boston数据集,之前做的训练/测试分区完全没生效,逻辑上存在冗余。
可直接落地的解决步骤

按照以下顺序调整代码,就能从根源上消除这个警告:

  • 补上特征预处理配置:在train函数中加入preProcess = c("center", "scale"),在每次交叉折训练前自动对输入特征做中心化、标准化,统一特征尺度,避免网络权重溢出。
  • 修正参数传递逻辑:通过函数参数传递通道把linOut = TRUE、最大迭代次数maxit = 200等底层训练参数传给nnet,保证回归任务的线性输出层正常生效,同时给够迭代次数让模型收敛。
  • 完善调参网格:把权重衰减参数decay加入调参范围,稳定不同交叉折上的训练过程,降低发散概率。
  • 修复训练集引用错误:把之前拆分得到的训练子集传入train函数,避免数据泄露和冗余计算。
  • 固定随机种子:在训练前设置随机种子,避免初始权重随机选择导致的偶发训练发散。

调整后的可运行代码参考:

library(datasets)
library(MASS)
library(caret)

# 固定随机种子
set.seed(123)
# 生成分区索引
DP = caret::createDataPartition(Boston$medv, p=0.75, list = FALSE)
train = Boston[DP, ]
test = Boston[-DP, ]

# 训练MLP模型
mlp = caret::train(
  medv ~ .,
  data = train,
  method = "mlp",
  trControl = trainControl(method = "cv", number = 3),
  # 补全调参网格,加入权重衰减
  tuneGrid = expand.grid(size = 1:3, decay = c(0, 0.01, 0.1)),
  # 加入标准化预处理
  preProcess = c("center", "scale"),
  # 传递底层nnet的训练参数
  linOut = TRUE,
  maxit = 200,
  metric = "RMSE"
)

# 测试集预测
Yp = predict(mlp, newdata = test[, 1:13])

按照上述调整后,交叉验证的每一个折都能正常完成训练、输出有效预测值、计算得到有效RMSE,不会再弹出“存在缺失的重采样性能值”的警告。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.22 09:45:04