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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 23:09:02