使用LOOCV实现kknn分类报错及LOOCV正确性咨询
kknn留一交叉验证(LOOCV)报错及实现问题
问题背景
你有一份用于kknn分类的样本数据(V4为响应变量,需分类为0或1),尝试通过for循环结合LOOCV构建k=3的模型,但运行代码时出现错误:
Error in model.frame.default(formula, data = train) :
invalid type (list) for variable 'train_data_response'
原始代码如下:
library(kknn) data <- data.frame( V1=c(1.2, 2.5, 3.1, 4.8, 5.2), V2=c(0.7, 1.8, 2.3, 3.9, 4.1), V3=c(2.3, 3.7, 1.8, 4.2, 5.5), V4= c(0, 1, 0, 1, 0) )
for (i in 1:nrow(data)) { train_data <- data[-i, 1:3] train_data_response <- data.frame(data[-i, 4]) colnames(train_data_response) <- "Response" test_set <- data[i, 3] model <- kknn(formula=train_data_response ~ ., data.frame(train_data), data.frame(test_set), k=3, scale=TRUE) }
错误原因分析
公式参数使用错误:
kknn的formula参数需要是标准公式对象(如响应列 ~ .),你直接将train_data_response(一个数据框,属于list类型)作为公式左侧,R会把它当作变量名查找,因此抛出"invalid type (list)"错误。kknn确实支持数据框输入,但公式必须引用数据框内的列名,而非直接传入数据框对象。测试集维度不匹配:
你提取的test_set只取了第3列(V3),但训练集包含V1-V3三个特征列,特征维度不一致会导致模型无法正常计算距离。
修正后的代码
以下是修复错误并完善LOOCV逻辑的代码:
library(kknn) data <- data.frame( V1=c(1.2, 2.5, 3.1, 4.8, 5.2), V2=c(0.7, 1.8, 2.3, 3.9, 4.1), V3=c(2.3, 3.7, 1.8, 4.2, 5.5), V4= c(0, 1, 0, 1, 0) ) # 初始化向量存储每次LOOCV的预测结果 predictions <- numeric(nrow(data)) for (i in 1:nrow(data)) { # 构造训练集:保留除第i行外的所有数据(含特征和响应变量) train_data <- data[-i, ] # 构造测试集:保留第i行的所有特征列(V1-V3) test_set <- data[i, 1:3] # 正确调用kknn:公式引用训练集中的响应列V4,训练数据传完整的train_data model <- kknn(formula = V4 ~ ., train = train_data, test = test_set, k=3, scale=TRUE) # 提取预测类别(kknn返回的fitted.values是概率,用round转换为0/1分类) predictions[i] <- round(model$fitted.values) } # 输出结果 cat("LOOCV预测结果:", predictions, "\n") cat("真实响应值:", data$V4, "\n") cat("LOOCV分类准确率:", mean(predictions == data$V4), "\n")
LOOCV实现的正确性说明
手动循环的逻辑是正确的:
你采用的"每次留一行作为测试集,其余作为训练集"的思路完全符合LOOCV的定义,修正后可以正常完成交叉验证流程。更简洁的替代方案:
kknn包提供了cv.kknn()函数,可以直接实现交叉验证(包括LOOCV),无需手动编写循环,示例代码如下:# 直接调用cv.kknn实现LOOCV(kcv设为样本量nrow(data)) cv_result <- cv.kknn(V4 ~ ., data = data, kcv = nrow(data), k = 3, scale = TRUE) # 计算准确率 cv_accuracy <- mean(round(cv_result$prob) == data$V4) cat("cv.kknn实现的LOOCV准确率:", cv_accuracy, "\n")
内容的提问来源于stack exchange,提问作者myts999
相关产品推荐
相关产品推荐

