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

广义线性混合模型交叉验证报data[[cat_col]]各ID内取值需恒定如何解决

问题描述

尝试使用groupdata2和cvms包对广义线性混合模型执行5折交叉验证,运行代码如下:

data <- groupdata2::fold(detect, k = 5,
                            cat_col = 'outcome',
                            id_col = 'bird') %>% 
                            arrange(.folds)

cvms::cross_validate(
data,
"outcome ~ sex  + year + season + (1 | bird) + (1 | obsname)",
family="binomial",
fold_cols = ".folds",
control = NULL,
REML = FALSE)

运行后收到报错:

Error in groupdata2::fold(detect, k = 4, cat_col = "outcome", id_col = "bird") %>%  : 
  1 assertions failed:
 * The value in 'data[[cat_col]]' must be constant within each ID.

包文档给出的解释为:要求同一个ID对应的分类标签取值恒定,避免同一ID被分到多个折叠,该逻辑适用于诊断结果固定的参与者类场景。但当前数据为鸟类重观测数据,outcome是每次调查的观测结果,同一个鸟类ID会出现不同的outcome取值,属于合理场景,需要绕过该限制。

可复现示例代码如下:

bird <- c(1,1,1,1,1,2,2,2,2,2,3,3,3,3,3)
outcome <- c(0,1,1,1,0,0,0,1,0,1,0,1,0,0,1)
df <- data.frame(bird, outcome)
df$outcome <- as.factor(df$outcome)
df$bird <- as.factor(df$bird)

data <- groupdata2::fold(df, k = 5,
cat_col = 'outcome',
id_col = 'bird') %>% 
arrange(.folds)
解决方案
  • 方案1:删除cat_col参数(仅保留按ID分组折叠)
    groupdata2::fold要求cat_col取值同ID恒定的前提是同时指定了cat_col和id_col,如果不需要严格保证每个折叠的outcome类别比例平衡,仅需要保证同一个鸟类ID的所有观测不被拆分到不同折叠,直接删除cat_col参数即可。
    注意:k的取值不能超过数据中独立鸟类ID的数量,示例数据中仅3个鸟类ID,k最多取3:
# 示例运行代码
data <- groupdata2::fold(df, k = 3, id_col = 'bird') %>% 
  arrange(.folds)
  • 方案2:自定义分层折叠(兼顾ID不拆分+outcome比例平衡)
    如果需要同时满足「同一ID不拆分」和「各折叠outcome比例接近总体」的要求,可以先按鸟类ID分组,统计每个ID的outcome分布,再手动将ID分配到不同折叠,保证各折叠的总outcome比例接近,之后为每个ID对应的所有行统一打上折叠标签即可,生成的.folds列可以直接传入cvms使用。
  • 方案3:换用rsample包实现分组交叉验证
    rsample包的group_vfold_cv()函数原生支持按分组变量拆分数据,不会要求同一个分组的标签恒定,更适合当前场景,拆分后生成的折叠可以直接转换为cvms要求的格式使用:
library(rsample)
library(dplyr)

# 按bird分组做3折交叉验证
splits <- group_vfold_cv(df, group = bird, v = 3)

# 转换为带.folds列的数据集
df_with_folds <- df %>%
  mutate(.folds = NA_integer_)
for (i in 1:nrow(splits)) {
  test_ids <- assessment(splits$splits[[i]])$bird %>% unique()
  df_with_folds$.folds[df_with_folds$bird %in% test_ids] <- i
}
注意事项
  • 含有随机效应的混合模型交叉验证必须保证同一个分组ID(此处为bird)的所有观测完全属于训练集或完全属于测试集,避免数据泄露导致模型性能高估。
  • 交叉验证的折数k最大不能超过独立分组ID的总数,否则无法实现完整分组拆分。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 21:45:04