R语言实现k折交叉验证验证薪资分组下身高分位数预测准确率
R 实现k折交叉验证保留所有迭代结果的方案
核心解决思路:提前初始化结果存储容器,每次迭代将当前折的计算结果写入容器对应位置,避免循环内重复赋值覆盖历史结果。
完整可运行代码示例
# 0. 模拟示例数据集(替换为你自己的真实数据即可) set.seed(123) # 固定随机种子保证结果可复现 df <- data.frame( Height = rnorm(1000, mean = 170, sd = 10), Salary = rnorm(1000, mean = 15000, sd = 5000) ) # 1. 配置k折参数 k <- 5 # 这里设置为5折,可自行修改为你需要的折数 folds <- sample(cut(seq(nrow(df)), breaks = k, labels = FALSE)) # 生成折的编号 # 初始化结果存储容器:每一行存1折的结果 result_df <- data.frame( fold = integer(k), accuracy = numeric(k) ) # 2. 循环遍历每一个折 for (i in 1:k) { # 拆分训练集、测试集 train_idx <- which(folds != i) train_data <- df[train_idx, ] test_data <- df[-train_idx, ] # 2.1 训练集计算Salary分位数断点 salary_breaks <- quantile(train_data$Salary, probs = c(0, 0.33, 0.66, 0.99, 1)) # 训练集给Salary分组 train_data$salary_group <- cut(train_data$Salary, breaks = salary_breaks, include.lowest = TRUE) # 计算每个分组的Height 80分位数 group_height_p80 <- aggregate(Height ~ salary_group, data = train_data, FUN = quantile, probs = 0.8) # 2.2 测试集复用训练集的断点分组 test_data$salary_group <- cut(test_data$Salary, breaks = salary_breaks, include.lowest = TRUE) # 测试集匹配对应分组的Height 80分位数 test_data <- merge(test_data, group_height_p80, by = "salary_group", suffixes = c("", "_p80")) # 计算当前折的准确率:Height低于对应分组p80的样本占比 current_acc <- mean(test_data$Height < test_data$Height_p80, na.rm = TRUE) # 关键:把当前折结果存入结果容器,不要覆盖 result_df$fold[i] <- i result_df$accuracy[i] <- current_acc } # 3. 输出所有迭代结果+平均准确率 print("所有折的准确率结果:") print(result_df) print(paste0(k, "折交叉验证平均准确率:", round(mean(result_df$accuracy), 4)))
常见错误说明
你之前循环只能保留最后一次结果,大概率是犯了以下两种错误之一:
- 没有提前初始化结果容器,每次循环都重新创建结果对象,覆盖了之前的内容
- 没有给结果容器指定索引位置写入,每次都直接给整个对象赋值,仅保留最后一次计算值
内容的提问来源于stack exchange,提问作者stats_noob
相关产品推荐
相关产品推荐

