如何在rjags中获取后验预测分布?模型适配疑问
问题解答
1. 为什么示例中使用dt()函数?
t分布(dt())的尾部比正态分布更厚重,当数据中存在异常值时,用t分布建模(或做后验预测)比正态分布更鲁棒,能降低极端值对模型的影响。如果你的观测数据有明显的离群点,用t分布替代正态分布会更合适;若数据分布接近正态,用正态分布(dnorm())也完全可行。
2. 后验预测代码中XXX、YYY的取值及dt()是否合适?
首先要明确:你的原始观测数据(y)是对数转换后的lRR还是原始尺度的RR?结合你的模型代码,这里的逻辑需要调整:
情况1:你的y是对数转换后的lRR(和模型中lRR[i]对应)
如果直接模拟对数尺度的后验预测值,若想用t分布,代码应该是:
# 先给自由度设定先验(放在模型的priors部分) df ~ dgamma(2, 0.1) # 常用的弱信息先验,也可以固定为5/10等数值 for(i in 1:Ndata){ pRR[i] <- alpha[i] * SS[i] * exp(-1*beta[i]*SS[i]); # 模拟对数尺度的预测值 yrep[i] ~ dt(log(pRR[i]) - (pow(sigmaObs,2)/2), pow(sigmaObs,-2), df); }
此时XXX是精度pow(sigmaObs,-2),YYY是自由度df。注意:JAGS中dt()的参数顺序是dt(location, precision, df),即位置(均值)、精度(1/方差)、自由度。
情况2:你的y是原始尺度的RR(即观测数据是未转换的RR)
原始RR是正数值,直接用t分布不合适(t分布允许负值),应该先在对数尺度模拟,再转换回原始尺度:
# 若用正态分布(和原模型一致) for(i in 1:Ndata){ pRR[i] <- alpha[i] * SS[i] * exp(-1*beta[i]*SS[i]); lRR_rep[i] ~ dnorm(log(pRR[i]) - (pow(sigmaObs,2)/2), pow(sigmaObs,-2)); yrep[i] <- exp(lRR_rep[i]); } # 若想用鲁棒的t分布处理异常值 df ~ dgamma(2, 0.1) for(i in 1:Ndata){ pRR[i] <- alpha[i] * SS[i] * exp(-1*beta[i]*SS[i]); lRR_rep[i] ~ dt(log(pRR[i]) - (pow(sigmaObs,2)/2), pow(sigmaObs,-2), df); yrep[i] <- exp(lRR_rep[i]); }
你的现有代码问题
你直接对yP[i]用dt(pRR[i], XXX, YYY)是不合适的:
pRR[i]是原始RR的期望值,但原始RR是正的,t分布可能生成负值,不符合数据实际意义;- 原模型是对对数尺度的响应建模,后验预测需要和原模型的观测过程对应,不能直接在原始尺度用t分布。
3. 生成y vs yrep的图
当你得到后验预测样本yrep后,可以用R包快速绘制对比图:
library(bayesplot) ppc_dens_overlay(y, yrep) # 观测值和预测值的密度叠加图 ppc_hist(y, yrep[1:50, ]) # 前50组预测值和观测值的直方图对比
内容的提问来源于stack exchange,提问作者vermicellion
相关产品推荐
相关产品推荐

