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

使用perry包对嵌套奶牛数据做分组10折交叉验证的折分配问题

解决按奶牛ID分组的10折交叉验证折分配问题

问题根源排查

出现部分观测Fold值为0的核心原因,大概率是BTN1列存在格式问题(如数值型ID、NA值),或是cvFolds的grouping参数输入不符合要求。

解决方案

方案1:预处理ID列后重新调用cvFolds

  1. 确保BTN1为因子/字符类型(避免数值型ID被误判):
# 检查ID列类型
str(df$BTN1)
# 若为数值型,转换为因子
df$BTN1 <- as.factor(df$BTN1)
  1. 检查并清理NA值:
# 统计NA数量
sum(is.na(df$BTN1))
# 删除含NA的观测(或根据业务逻辑补全)
df <- df[!is.na(df$BTN1), ]
  1. 正确调用cvFolds,grouping参数传入全量观测对应的BTN1向量:
library(perry)
set.seed(123) # 固定随机种子保证结果可重复
cv_result <- cvFolds(nrow(df), K = 10, grouping = df$BTN1)
# 将折号映射回原数据集
df$Fold <- cv_result$which

方案2:手动生成分组折号(更稳定可控)

如果cvFolds的分组逻辑仍有问题,可手动实现按ID分配折号:

  1. 提取所有唯一奶牛ID:
unique_btns <- unique(df$BTN1)
  1. 给唯一ID分配10折(支持按农场分层抽样,适配嵌套结构):
set.seed(123)
# 基础分配:均匀拆分ID到10折
fold_ids <- sample(rep(1:10, length.out = length(unique_btns)))
# 若需按农场分层:先按农场分组,再在每个农场内拆分ID
# fold_ids <- df %>% distinct(BTN1, farm_id) %>% group_by(farm_id) %>% mutate(Fold = sample(rep(1:10, length.out = n()))) %>% pull(Fold)
  1. 建立ID与折号的映射关系,合并回原数据集:
fold_map <- data.frame(BTN1 = unique_btns, Fold = fold_ids)
df <- merge(df, fold_map, by = "BTN1", all.x = TRUE)

关键注意事项

  • cvFolds的grouping参数必须是与观测行数一致的向量,每个元素对应当前观测的分组ID,不能只传入唯一ID列表
  • 同一奶牛的所有观测会被分配到同一折,彻底避免信息泄露

内容的提问来源于stack exchange,提问作者ILo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 05:24:56