我正在尝试使用 kfold CV 作为评估使用 brms 运行的模型的一种方法,我觉得我错过了一些东西。作为一个可重复的示例,我的数据被构造为取决于个人长度的二进制响应 (0, 1)。下面是一些代码,用于生成和绘制与我正在使用的数据类似的数据:
library(brms)
library(tidyverse)
library(loo)
length <- seq(0, 100, by = 1)
n_fish_per_length <- 10
a0 <- -48
a1 <- 2
a2 <- -0.02
prob <- plogis(a0 + a1 * length + a2 * length^2)
plot(length, prob , type = 'l')
sim_data <-
expand_grid(fish_id = seq_len(n_fish_per_length),
length = length) %>%
mutate(prob_use = plogis(a0 + a1 * length + a2 * length^2)) %>%
mutate(is_carp = rbinom(n = n(), size = 1, prob= prob_use))
ggplot(sim_data, aes(x = length, y = is_carp)) +
geom_jitter(width = 0, height = 0.05) +
geom_smooth(method = "glm", formula = y ~ x + I(x^2),
method.args = list(family = binomial(link = "logit")))
然后我使用 brms 来运行我的模型。
Bayes_Model_Binary <- brm(formula = is_carp ~ length + I(length^2),
data=sim_data,
family = bernoulli(link = "logit"),
warmup = 2500,
iter = 5000,
chains = 4,
inits= "0",
cores=4,
seed = 123)
summary(Bayes_Model_Binary)
我想使用 kfold CV 来评估模型。我可以使用这样的东西:
kfold(Bayes_Model_Binary, K = 10, chains = 1, save_fits = T)
但我的数据中的响应高度不平衡(~18% = 1,~82% = 0),我的阅读表明我需要使用分层 kfold cv 来解释这一点。如果我使用:
sim_data$fold <- kfold_split_stratified(K = 10, x = sim_data$is_carp)
数据按照我期望的方式拆分,但我不确定从这里开始推进 CV 流程的最佳方法是什么。我看到这篇文章https://mc-stan.org/loo/articles/loo2-elpd.html,但我不确定如何修改它以使用 brmsfit 对象。或者,我似乎应该能够使用:
kfold(Bayes_Model_Binary, K = 10, folds = 'stratified', group = sim_data$is_carp)
但这会引发错误。可能是因为 is_carp 是模型中的响应而不是预测变量。在这种情况下,我的小组会是什么?我在这里遗漏/误解了某些东西吗?我假设这里有一个非常简单的解决方案,我可以忽略但感谢任何想法。