R语言决策树AUC交叉验证出现Y0[[v]]索引越界报错如何解决
问题原因与修复方案
核心报错诱因
你遇到的索引越界问题主要来自三处错误:
.doFit函数参数大小写定义错误:函数第一个参数定义为大写V,但内部同时用了大写V和小写v取值,调用时传入的是循环变量小写v,变量匹配混乱- 子函数未传入
y参数:主函数的y变量不会自动传入并行环境下的.doFit函数,导致列索引计算错误 - 缺少边界校验:如果数据集中某一类(0/1)的样本数量小于交叉验证折数
V,split生成的类折列表长度会小于V,直接取值就会触发越界
修复代码
1 修复.cvFolds函数,增加边界校验
.cvFolds <- function(Y, V) { # 提前校验类样本量,避免拆分后折数不足 n_zero <- sum(Y == 0) n_one <- sum(Y == 1) if (n_zero < V | n_one < V) { stop("0类或1类样本数量不能小于交叉验证折数V,请减小V或扩充数据集") } Y0 <- split(sample(which(Y == 0)), rep(1:V, length = n_zero)) Y1 <- split(sample(which(Y == 1)), rep(1:V, length = n_one)) folds <- vector("list", length = V) for (v in seq(V)) folds[[v]] <- c(Y0[[v]], Y1[[v]]) return(folds) }
2 修复.doFit函数的参数和变量引用
# 统一参数为小写v,新增y参数传入 .doFit <- function(v, folds, train, y) { set.seed(v) ycol <- which(names(train) == y) params <- list(x = train[-folds[[v]], -ycol], y = as.factor(train[-folds[[v]], ycol]), xtest = train[folds[[v]], -ycol]) fit <- do.call(randomForest, params) pred <- fit$test$votes[, 2] return(pred) }
3 修复主函数的子函数调用逻辑
iid_example <- function(train, y = "V1", V = 10, seed = 1) { set.seed(seed) folds <- .cvFolds(Y = train[, c(y)], V = V) # Generate CV predicted values cl <- makeCluster(detectCores()) registerDoParallel(cl) # 调用时传入y参数 predictions <- foreach(v = 1:V, .combine = "c", .packages = c("randomForest")) %dopar% .doFit(v, folds, train, y) stopCluster(cl) predictions[unlist(folds)] <- predictions # Get CV AUC runtime <- system.time(res <- ci.cvAUC(predictions = predictions, labels = train[, c(y)], folds = folds, confidence = 0.95)) print(runtime) return(res) }
使用说明
如果你的数据集正负样本数小于10,可以将调用时的V参数调整为更小的数值,比如5折交叉验证:
res <- iid_example(train = datos, y = "V1", V = 5, seed = 1)
内容的提问来源于stack exchange,提问作者Jesús Asdrúbal Molina Vízquez
相关产品推荐
相关产品推荐

