我一直试图将平滑处理纳入我创建的runjags模型中,该模型用于建模海鸟洞穴数量和整个岛屿的分布。我设法通过从模型输出中提取计数数据以及x和y坐标并使用此页面上的JAGAM教程来http://www.petrkeil.com/?p=2385
生成一些平滑代码我认为我可以通过将平滑处理合并到锯齿模型中来改善模型性能,但是我对此却一无所知。您能为我提供如何实现这一目标的任何指示吗?
我在下面附加了一部分runjags代码和JAGAM输出。
runjags代码:
let popViewController = CreateNoticePopupViewController()
JAGAM输出:
for(i in 1:K) {
S1[i]~dpois(lambda1[i])
SS1[i]~dpois(lambda1[i])
lambda1[i]<-exp(a0+
a1*Tussac[i]+
a2*normalise_DEM_aspect[i]+
a3*normalise_DEM_slope[i]+
a4*Tussac[i]*normalise_DEM_aspect[i]+
a5*Tussac[i]*normalise_DEM_slope[i]+
a6*normalise_sentinel1[i]+
a7*normalise_setinel3[i]+
a8*normalise_sentinel4[i]+
a9*normalise_sentinel5[i]+
a10*normalise_sentinel8[i]+
a11*normalise_sentinel10[i]+
a12*S2[i])
}
样本数据:
readLines("jagam.bug")
"model {"
" eta <- X %*% b ## linear predictor"
" for (i in 1:n) { mu[i] <- exp(eta[i]) } ## expected response"
" for (i in 1:n) { y[i] ~ dpois(mu[i]) } ## response "
" ## Parametric effect priors CHECK tau=1/35^2 is appropriate!"
" for (i in 1:1) { b[i] ~ dnorm(0,0.00083) }"
" ## prior for s(x,y)... "
" K1 <- S1[1:29,1:29] * lambda[1] + S1[1:29,30:58] * lambda[2]"
" b[2:30] ~ dmnorm(zero[2:30],K1) "
" ## smoothing parameter priors CHECK..."
" for (i in 1:2) {"
" lambda[i] ~ dgamma(.05,.005)"
" rho[i] <- log(lambda[i])"
" }"
"}"
答案 0 :(得分:0)
这是一个很好的问题,并且是一个很好的主意,可以使用jagam的输出(极其有用)在您的模型中添加GAM术语。在您的情况下,我建议您使用jagam仅生成GAM术语,而不生成其他内容(甚至不截取),然后将jagam模型输出的相关部分复制/粘贴到您现有的模型代码中,如下所示:以及从jagam获取X数据变量并将其用作数据。举一个例子最容易证明这一点:
首先使用单个线性项X1和单个非线性项X2(在这种情况下是多项式,但这无关紧要)来模拟一些数据:
library('runjags')
library('mgcv')
set.seed(2018-09-06)
N <- 100
dataset <- data.frame(X1 = runif(N,-1,1), X2 = runif(N,-1,1))
dataset$ll <- with(dataset, 1 + 0.15*X1 + 0.25*X2 - 0.2*X2^2 + 0.15*X2^3 + rnorm(N,0,0.1))
dataset$Y <- rpois(N, exp(dataset$ll))
# Non-linear relationship with log lambda:
with(dataset, plot(X2, ll))
然后运行jagam BUT,请确保在右侧指定0 +,以排除拦截项:
# Get the JAGAM stuff excluding intercept:
jd <- jagam(Y ~ 0 + s(X2), data=dataset, file='jagam.txt',
sp.prior="gamma",diagonalize=TRUE,family='poisson')
或者,您可以在此处保留拦截项并将其从模型中删除。这样我们得到了一个jagam.txt文件,如下所示:
model {
eta <- X %*% b ## linear predictor
for (i in 1:n) { mu[i] <- exp(eta[i]) } ## expected response
for (i in 1:n) { y[i] ~ dpois(mu[i]) } ## response
## prior for s(X2)...
for (i in 1:8) { b[i] ~ dnorm(0, lambda[1]) }
for (i in 9:9) { b[i] ~ dnorm(0, lambda[2]) }
## smoothing parameter priors CHECK...
for (i in 1:2) {
lambda[i] ~ dgamma(.05,.005)
rho[i] <- log(lambda[i])
}
}
您可以删除第一行和最后一行,以及以for(i:n中的i)开头的两行,因为我们将自己复制这些行。现在,复制文件的所有剩余内容,并仅使用线性预测变量(和/或随机效应或其他任何形式)进入您的(非GAM)模型-例如:
model <- 'model{
for(i in 1:N){
log(mean[i]) <- intercept + coef*X1[i]
Y[i] ~ dpois(mean[i])
}
# Our priors:
intercept ~ dnorm(0, 10^-6)
coef ~ dnorm(0, 10^-6)
#data# N, X1, Y
#monitor# intercept, coef
}'
然后将您复制的GAM位粘贴到末尾,这样您将获得:
model <- 'model{
for(i in 1:N){
log(mean[i]) <- intercept + coef*X1[i] + eta[i]
Y[i] ~ dpois(mean[i])
}
# Our priors:
intercept ~ dnorm(0, 10^-6)
coef ~ dnorm(0, 10^-6)
#data# N, X1, Y, X
#monitor# intercept, coef, b, rho
## JAGAM
eta <- X %*% b ## linear predictor
## prior for s(X2)...
for (i in 1:8) { b[i] ~ dnorm(0, lambda[1]) }
for (i in 9:9) { b[i] ~ dnorm(0, lambda[2]) }
## smoothing parameter priors CHECK...
for (i in 1:2) {
lambda[i] ~ dgamma(.05,.005)
rho[i] <- log(lambda[i])
}
## END JAGAM
}'
请注意,在GLM行中添加了+ eta [i],以考虑GAM项,并在监视器中添加b和rho。那应该是模型所需要做的全部工作(除了按照建议检查先验参数等是否平滑)。
然后,我们需要提取新的X数据变量以用于JAGS:
X <- jd$jags.data$X
如果需要,您还可以提取b和lambda的初始值。最后,我们可以使用runjags运行模型:
results <- run.jags(model, n.chains=2, data=dataset)
results
当然,通过将jagam代码放入更简单的模型中,这个愚蠢的示例毫无用处-jagam可以为我们创建整个模型(包括截距和线性预测器)。但是,当将一个相对较小的GAM组件添加到一个较大的预先存在的模型中时,这种方法可能有价值,该模型已被编写为使用runjags中的某些功能...
如果我们想使用sim2jam返回并在合适的runjags对象上使用mgcv中的相关诊断/帮助程序功能,当前需要直接调用rjags以获得更多样本:
library('rjags')
sam <- jags.samples(as.jags(results), c('b','rho'), n.iter=10000)
jam <- sim2jam(sam,jd$pregam)
plot(jam)
这里缺少两件事:
1)使用sim2jam的能力,而无需在rjags中进行更多采样。这需要对rjags包中的mcarray类进行一些补充,目前我正在研究。
2)template.jags()可以自动为您完成所有操作的能力-这是我将来要实现的事情。
希望有帮助-我很想听听你的生活。
马特