如何使用R caret包搭建基于LOOCV交叉验证的堆叠算法模型
问题根因
- 你手动构造的
model_these索引完全不符合trainControl的index参数要求:index的每个元素对应1个交叉验证折叠的训练集样本索引,LOOCV要求每个折叠的训练集仅排除1个验证样本,有多少训练样本就有多少个折叠。你当前的构造逻辑是每个折叠排除某一类别所有样本,导致每个折叠内的响应变量仅存在单一类别,ROSE类平衡采样无法执行,直接触发报错。 - 单类别训练集也无法计算二分类的ROC指标,因此后续出现重采样性能指标缺失的警告。
解决方法
1. 构造正确的LOOCV训练集索引
按照LOOCV的规则,每个折叠保留1个样本作为验证集,其余样本为训练集:
n <- nrow(train_set) # 每个元素为对应折叠的训练集索引 model_these <- lapply(1:n, function(i) (1:n)[-i]) names(model_these) <- paste0("Fold_", 1:n)
2. 修正训练控制参数
如果你的业务不需要特殊的折叠拆分规则,也可以直接去掉手动设置的index参数,caret会自动按照method="loocv"生成对应的折叠索引,无需手动构造。
如果需要保留ROSE类平衡采样,要确保所有训练折叠内都同时包含两个类别的样本,你的原始索引构造逻辑完全不满足这个前提,必须调整。
修正后完整代码示例
# Stacking Algorithms # 构造LOOCV对应训练集索引 n <- nrow(train_set) model_these <- lapply(1:n, function(i) (1:n)[-i]) names(model_these) <- paste0("Fold_", 1:n) control <- trainControl( sampling = "rose", method = "loocv", index = model_these, savePredictions = TRUE, classProbs = TRUE, summaryFunction = twoClassSummary ) algorithmList <- c('rpart', 'knn', 'nb') set.seed(123) # 替换为你自定义的随机种子 stack_models <- caretList( classes~., data = train_set, metric = "ROC", trControl = control, methodList = algorithmList )
额外注意
UCI森林火灾数据集原始目标为连续的过火面积,你做二分类转换时要注意类别分布,如果某类样本量极少,LOOCV的折叠仍可能出现训练集缺类的问题,这种场景建议关闭ROSE采样,改用类别权重调整来处理不平衡问题。
内容的提问来源于stack exchange,提问作者Milinda Arambawela
相关产品推荐
相关产品推荐

