R语言KNN五折交叉验证报subscript out of bounds错误如何解决
错误根源
下标越界由两个核心问题导致:
- 交叉验证误差矩阵创建错误:你定义候选k为
k=3:10(共8个取值),创建ErrCV矩阵时直接将ncol参数设为向量k,R会默认取向量第一个值3,最终生成的ErrCV只有3列。后续循环k到410时,尝试给不存在的第410列赋值,直接触发越界。 - 索引不匹配:即使你把矩阵列数设为8,直接用k的实际值(3~10)作为列索引也会出现问题:第1个候选k=3对应矩阵第1列,但你会尝试写入第3列,导致索引错位、后续k=10时越界。
另有一个隐藏预处理问题:你没有将Caravan的第86列赋值给Purchase变量,直接使用train.Y=Purchase[-test]会触发对象不存在的报错。
修正方案
预处理阶段修正
standardized.X = scale(Caravan[, -86]) Purchase = Caravan[,86] # 补全Purchase变量赋值 var(standardized.X[,1]) var(standardized.X[,2]) test = 1:1000 train.X=standardized.X[-test ,] test.X=standardized.X[test ,] train.Y=Purchase[-test] test.Y=Purchase[test]
交叉验证阶段修正
set.seed(2001835) F <- 5 ntrain=nrow(train.X) folds <- cut(seq(1,ntrain), breaks = F, labels = FALSE) folds <- folds[sample(ntrain)] k_candidate = 3:10 # 重命名候选k向量,避免和索引变量混淆 ErrCV <- matrix(0, nrow=F, ncol= length(k_candidate)) # 列数设为候选k的总个数 colnames(ErrCV) = k_candidate # 绑定列名和k值,方便后续读取 for (f in 1:F) { retrainData <- which(folds != f) train.setX <- train.X[retrainData,] test.setX <- train.X[-retrainData,] train.setY <- train.Y[retrainData] test.setY <- train.Y[-retrainData] for(i in 1:length(k_candidate)){ k = k_candidate[i] # 模型拟合 knn.pred <- knn(train = train.setX, test = test.setX, cl = train.setY, k = k) # 误差写入对应索引位置 ErrCV[f,i]=mean(knn.pred != test.setY) } } CV <- apply(ErrCV, 2, mean) # 绘制误差曲线 plot(k_candidate, CV, type="l", xlab="K取值", ylab="5折交叉验证误差") # 输出最优K值 best_k = k_candidate[which.min(CV)] cat("最优K值为:", best_k)
内容的提问来源于stack exchange,提问作者xxxxx
相关产品推荐
相关产品推荐

