排查KNN最优k值查找for循环代码的计算错误
排查KNN最优k值代码中的问题
看起来你在调优KNN的k值时遇到了结果不正确的问题,我帮你梳理下代码里的几个关键问题:
- 初始化错误:你写了
bestaccuracy = 0 bestaccuracy,这是语法错误;而且bestk没有提前初始化,第一次赋值时可能会报错或者得到不可预期的结果。应该明确初始化这两个变量。 - 随机种子位置错误:把
set.seed(1)放在for循环内部,会导致每次循环都重置随机种子,这样每个k对应的交叉验证划分都是完全一样的,这会让你的交叉验证结果失去统计意义,无法正确比较不同k值的性能。应该把种子设置放在循环外面。 - 冗余的条件判断:你写了两次
if(bestaccuracy < knn.cvac.accuracy),完全可以合并成一次,同时更新bestk和bestaccuracy,让代码更简洁。 - k值范围可能不合理:设置
n.folds <- 100意味着你要测试k从1到100,但KNN的k值过大时模型会过于平滑,且如果k超过训练集样本数的一半,实际意义不大。通常建议测试较小的奇数(避免分类平局),比如1到21之间的奇数。
修正后的代码
# Tune the value of K using K-Fold Cross Validation bestaccuracy <- 0 bestk <- 1 # 提前初始化bestk n.folds <- 21 # 调整为更合理的k值范围 set.seed(1) # 随机种子放在循环外,保证交叉验证划分的一致性 for (k in 1:n.folds) { knn.cvac <- knn.cv(train = x.australian.stan, cl = y.australian, k = k) knn.cvac.table <- table(knn.cvac, y.australian) knn.cvac.accuracy <- sum(diag(knn.cvac.table)) / sum(knn.cvac.table) # 合并条件判断,同时更新最优k和对应准确率 if (bestaccuracy < knn.cvac.accuracy) { bestk <- k bestaccuracy <- knn.cvac.accuracy } } print(bestk) print(bestaccuracy)
额外优化:可视化k值与准确率的关系
你可以新增代码记录每个k的准确率,通过绘图直观观察最优k的变化趋势:
# 新增向量存储每个k对应的准确率 accuracy_list <- c() set.seed(1) for (k in 1:n.folds) { knn.cvac <- knn.cv(train = x.australian.stan, cl = y.australian, k = k) knn.cvac.table <- table(knn.cvac, y.australian) acc <- sum(diag(knn.cvac.table)) / sum(knn.cvac.table) accuracy_list <- c(accuracy_list, acc) if (bestaccuracy < acc) { bestk <- k bestaccuracy <- acc } } # 绘制k值调优曲线 plot(1:n.folds, accuracy_list, type = "b", xlab = "k值", ylab = "交叉验证准确率", main = "KNN k值调优曲线") points(bestk, bestaccuracy, col = "red", pch = 19) text(bestk, bestaccuracy, labels = paste("最优k=", bestk), pos = 4)
内容的提问来源于stack exchange,提问作者datagekko
相关产品推荐
相关产品推荐

