如何从JagsUI并行模型链用rjags提取WAIC?并行多单链共存可行吗?
问题背景
我用JagsUI批量运行大量单预测器和多预测器模型,通过autojags()让模型收敛。需要用WAIC做模型选择,但JagsUI不支持输出WAIC,尝试用rjags的jags.samples()提取WAIC时,只有非并行运行的模型能成功,耗时太长无法满足批量需求。
核心疑问
- 是否可以从JagsUI并行运行的模型中选取单链,用
jags.samples()提取WAIC?
尝试代码:
报错:samples <- jags.samples(mod_jagsUI$model$cluster1, c("WAIC","deviance"), type = "mean", n.iter = 1000, n.burnin = 100, n.thin = 1)Error in FUN(X[[i]], ...) : JAGS model must be recompiled - 是否可以同时并行运行一个3链模型和一个单独的1链模型?
解决方案
针对疑问1:直接从并行模型提取WAIC所需数据(无需单独调用jags.samples)
报错原因是并行运行的Jags链在子进程中,主进程无法直接访问子进程的模型状态,因此会要求重新编译。更高效的方式是在Jags模型代码中预先定义log似然变量,通过JagsUI提取这些变量后手动计算WAIC:
- 在你的Jags模型代码里添加log似然的计算(根据你的模型分布调整,以下为正态分布示例):
model { # 原有模型代码... # 计算每个观测的log似然 for (i in 1:N) { log_lik[i] <- dnorm(y[i], mu[i], tau, log=TRUE) } } - 运行JagsUI时,把
log_lik加入parameters.to.save:mod <- jags(data = data_list, model.file = "your_model.jags", parameters.to.save = c("mu", "log_lik"), # 加入log_lik n.chains = 3, parallel = TRUE, autojags = TRUE) - 提取所有链的
log_lik样本,用loo包计算WAIC:library(loo) # 整理log似然为矩阵:每行对应一个观测,每列对应一个MCMC样本 log_lik_matrix <- do.call(rbind, lapply(mod$samples$log_lik, t)) # 计算WAIC waic_result <- waic(log_lik_matrix)
这种方法不需要单独调用jags.samples,并行运行的模型也能直接提取数据,效率更高。
针对疑问2:同时并行运行多链模型和单链模型
可以实现,但没必要(上述方法已能解决WAIC需求)。如果一定要这么做,可通过parallel包管理并行任务,将不同模型分配到不同核心:
library(parallel) library(JagsUI) # 创建核心集群(假设用4个核心,3链占3个,单链占1个) cl <- makeCluster(4) # 导出任务所需的变量和模型代码 clusterExport(cl, c("data_list", "your_model.jags")) # 并行运行两个模型 results <- parLapply(cl, list(list(n.chains=3), list(n.chains=1)), function(params) { jags(data = data_list, model.file = "your_model.jags", parameters.to.save = c("mu", "log_lik"), n.chains = params$n.chains, parallel = FALSE, # 每个任务内部不并行,由外部集群调度 autojags = TRUE) }) # 关闭集群 stopCluster(cl) # 分别获取结果 mod_3chains <- results[[1]] mod_1chain <- results[[2]]
不过这种方式会占用更多核心资源,且不如直接提取log似然计算WAIC高效。
内容的提问来源于stack exchange,提问作者madip
相关产品推荐
相关产品推荐

