Как я могу предоставить соответствующие начальные значения для многослойной модели повторного захвата с использованием JAGS через R? - PullRequest
0 голосов
/ 07 апреля 2020

Я пытался запустить многоуровневую модель метки-повторного захвата, модифицированную из примеров в Bayesian Population Analysis, используя WinBUGS от Kery and Schaub (2012). Тем не менее, я застрял на некоторое время, поэтому я надеюсь, что кто-то может иметь некоторое понимание. Я продолжаю получать следующую ошибку:

Error in jags.model(file = model.file, data = data, inits = inits, n.chains = n.chains,  : 
  Error in node y[1,7]
Node inconsistent with parents

Я довольно новичок в JAGS (и в байесовском анализе в целом), но из того, что я прочитал, я понимаю, что это не редкая ошибка и проблема скорее всего лежит с начальными значениями, которые я предоставил. Я пробовал различные начальные значения, но продолжаю получать ту же ошибку. Я также пробовал гамма-априоры для вероятностей перехода состояний (psi), но получаю ту же ошибку. Моя переменная ответа (y) представляет собой матрицу 392 x 99, что означает 99 случаев выборки, что довольно мало - интересно, связана ли проблема с количеством случаев выборки? (Когда я запускаю пример точно так же, как в Kery and Schaub (2012) с 6 случаями выборки, он работает.) Это симулированные данные, но я получаю то же сообщение об ошибке с моими реальными данными, которые расположены в матрице аналогичного размера. Я предоставил код для имитации данных и код моей модели ниже. Обратите внимание, что вероятность перехода из состояний BF в NB установлена ​​равной нулю - индивидуумы не переходят в этом направлении. Если у кого-то есть идеи относительно более подходящих начальных значений или другого источника проблемы, я был бы очень признателен.

################################################################################
# MULTISTATE MARK-RECAPTURE MODEL
# adapted from Kery and Schaub (2012)
################################################################################

#### SIMULATE DATA ####

library(rjags)
library(jagsUI)

set.seed(42)

# Define mean survival, transitions, recapture, as well as number of occasions, states, observations and released individuals
phiNB <- 0.85
phiNST <- 0.75
phiBF <- 0.65
psiNB.NST <- 0.3
psiNB.BF <- 0.2
psiNST.NB <- 0.5
psiNST.BF <- 0.1
psiBF.NB <- 0
psiBF.NST <- 0.3
psiNB <- 0.7
psiNST <- 0.4
psiBF <- 0.5
n.occasions <- 99
n.states <- 4
n.obs <- 4
marked <- matrix(NA, ncol = n.states, nrow = n.occasions)
marked[,1] <- rep(1, n.occasions)  
marked[,2] <- rep(2, n.occasions)
marked[,3] <- rep(1, n.occasions)
marked[,4] <- rep(0, n.occasions)

# Define matrices with survival, transition and recapture probabilities
# These are 4-dimensional matrices, with 
# Dimension 1: state of departure
# Dimension 2: state of arrival
# Dimension 3: individual
# Dimension 4: time
# 1. State process matrix
totrel <- sum(marked)*(n.occasions-1)
PSI.STATE <- array(NA, dim=c(n.states, n.states, totrel, n.occasions-1))
for (i in 1:totrel){
  for (t in 1:(n.occasions-1)){
    PSI.STATE[,,i,t] <- matrix(c(
      phiNB*(1-psiNB.NST-psiNB.BF), phiNB*psiNB.NST,           phiNB*psiNB.BF,           1-phiNB,
      phiNST*psiNST.NB,           phiNST*(1-psiNST.NB-psiNST.BF), phiNST*psiNST.BF,           1-phiNST,
      phiBF*psiBF.NB,           phiBF*psiBF.NST,           phiBF*(1-psiBF.NB-psiBF.NST), 1-phiBF,
      0,                    0,                    0,                    1), nrow = n.states, byrow = TRUE)
  } #t
} #i

# 2.Observation process matrix
PSI.OBS <- array(NA, dim=c(n.states, n.obs, totrel, n.occasions-1))
for (i in 1:totrel){
  for (t in 1:(n.occasions-1)){
    PSI.OBS[,,i,t] <- matrix(c(
      psiNB, 0,  0,  1-psiNB,
      0,  psiNST, 0,  1-psiNST,
      0,  0,  psiBF, 1-psiBF,
      0,  0,  0,  1), nrow = n.states, byrow = TRUE)
  } #t
} #i

# Define function to simulate multistate capture-recapture data
simul.ms <- function(PSI.STATE, PSI.OBS, marked, unobservable = NA){
  # Unobservable: number of state that is unobservable
  n.occasions <- dim(PSI.STATE)[4] + 1
  CH <- CH.TRUE <- matrix(NA, ncol = n.occasions, nrow = sum(marked))
  # Define a vector with the occasion of marking
  mark.occ <- matrix(0, ncol = dim(PSI.STATE)[1], nrow = sum(marked))
  g <- colSums(marked)
  for (s in 1:dim(PSI.STATE)[1]){
    if (g[s]==0) next  # To avoid error message if nothing to replace
    mark.occ[(cumsum(g[1:s])-g[s]+1)[s]:cumsum(g[1:s])[s],s] <-
      rep(1:n.occasions, marked[1:n.occasions,s])
  } #s
  for (i in 1:sum(marked)){
    for (s in 1:dim(PSI.STATE)[1]){
      if (mark.occ[i,s]==0) next
      first <- mark.occ[i,s]
      CH[i,first] <- s
      CH.TRUE[i,first] <- s
    } #s
    for (t in (first+1):n.occasions){
      # Multinomial trials for state transitions
      if (first==n.occasions) next
      state <- which(rmultinom(1, 1, PSI.STATE[CH.TRUE[i,t-1],,i,t-1])==1)
      CH.TRUE[i,t] <- state
      # Multinomial trials for observation process
      event <- which(rmultinom(1, 1, PSI.OBS[CH.TRUE[i,t],,i,t-1])==1)
      CH[i,t] <- event
    } #t
  } #i
  # Replace the NA and the highest state number (dead) in the file by 0
  CH[is.na(CH)] <- 0
  CH[CH==dim(PSI.STATE)[1]] <- 0
  CH[CH==unobservable] <- 0
  id <- numeric(0)
  for (i in 1:dim(CH)[1]){
    z <- min(which(CH[i,]!=0))
    ifelse(z==dim(CH)[2], id <- c(id,i), id <- c(id))
  }
  return(list(CH=CH[-id,], CH.TRUE=CH.TRUE[-id,]))
  # CH: capture histories to be used
  # CH.TRUE: capture histories with perfect observation
}

# Execute simulation function
sim <- simul.ms(PSI.STATE, PSI.OBS, marked)
CH <- sim$CH

# Compute vector with occasions of first capture
get.first <- function(x) min(which(x!=0))
f <- apply(CH, 1, get.first)

# Recode CH matrix: note, a 0 is not allowed in WinBUGS! (is it in JAGS?)
# 1 = seen alive in NB, 2 = seen alive in NST, 3, seen alive in BF, 4 = not seen
rCH <- CH  # Recoded CH
rCH[rCH==0] <- 4

#### FUNCTIONS FOR INITS ####

# Function to create known latent states z
known.state.ms <- function(ms, notseen){
  # notseen: label for ‘not seen’
  state <- ms
  state[state==notseen] <- NA
  for (i in 1:dim(ms)[1]){
    m <- min(which(!is.na(state[i,])))
    state[i,m] <- NA
  }
  return(state)
}

# Function to create initial values for unknown z
ms.init.z <- function(ch, f){
  for (i in 1:dim(ch)[1]){ch[i,1:f[i]] <- NA}
  states <- max(ch, na.rm = TRUE)
  known.states <- 1:(states-1)
  v <- which(ch==states)
  ch[-v] <- NA
  ch[v] <- sample(known.states, length(v), replace = TRUE)
  return(ch)
}

#### JAGS MODEL CODE ####

sink("SESA-multistate.jags")
cat("
    model {

    # -------------------------------------------------
    # Parameters:
    # phiNB: persistence (survival) probability at site NB
    # phiNST: persistence (survival) probability at site NST
    # phiBF: persistence (survival) probability at site BF

    # psiNB.NST: movement (transition) probability from NB to NST
    # psiNB.BF: movement (transition) probability from NB to BF
    # psiNST.NB: movement (transition) probability from NST to NB
    # psiNST.BF: movement (transition) probability from NST to BF
    # psiBF.NB: movement (transition) probability from BF to NB
    # psiBF.NST: movement (transition) probability from BF to NST

    # pNB: detection probability at site NB
    # pNST: detection probability at site NST
    # pBF: detection probability at site BF
    # -------------------------------------------------

    # States (S):
    # 1 alive at site NB
    # 2 alive at site NST
    # 3 alive at site BF
    # 0 gone

    # Observations (O):
    # 1 detected at site NB
    # 2 detected at site NST
    # 3 detected at site BF
    # 0 not detected
    # -------------------------------------------------

    # Priors and constraints
    # Survival and recapture: uniform
    phiNB ~ dunif(0, 1)
    phiNST ~ dunif(0, 1)
    phiBF ~ dunif(0, 1)

    pNB ~ dunif(0, 1)
    pNST ~ dunif(0, 1)
    pBF ~ dunif(0, 1)

    # Transitions: multinomial logit
    # Normal priors on logit of all but one transition probas
    for (i in 1:2){
    lpsiNB[i] ~ dnorm(0, 0.001)
    lpsiNST[i] ~ dnorm(0, 0.001)
    lpsiBF[i] ~ dnorm(0, 0.001)
    }

    # Constrain the transitions such that their sum is < 1
    for (i in 1:2){
    psiNB[i] <- exp(lpsiNB[i]) / (1 + exp(lpsiNB[1]) + exp(lpsiNB[2]))
    psiNST[i] <- exp(lpsiNST[i]) / (1 + exp(lpsiNST[1]) + exp(lpsiNST[2]))
    psiBF[i] <- exp(lpsiBF[i]) / (1 + exp(lpsiBF[1]) + exp(lpsiBF[2]))
    }

    # Calculate the last transition probability
    psiNB[3] <- 1-psiNB[1]-psiNB[2]
    psiNST[3] <- 1-psiNST[1]-psiNST[2]
    psiBF[3] <- 1-psiBF[1]-psiBF[2]

    # Define state-transition and observation matrices  
    for (i in 1:nind){
    # Define probabilities of state S(t+1) given S(t)
    for (t in f[i]:(n.occasions-1)){

    ps[1,i,t,1] <- phiNB * psiNB[1]
    ps[1,i,t,2] <- phiNB * psiNB[2]
    ps[1,i,t,3] <- phiNB * psiNB[3]
    ps[1,i,t,4] <- 1-phiNB

    ps[2,i,t,1] <- phiNST * psiNST[1]
    ps[2,i,t,2] <- phiNST * psiNST[2]
    ps[2,i,t,3] <- phiNST * psiNST[3]
    ps[2,i,t,4] <- 1-phiNST

    ps[3,i,t,1] <- 0
    ps[3,i,t,2] <- phiBF * psiBF[2]
    ps[3,i,t,3] <- phiBF * psiBF[3]
    ps[3,i,t,4] <- 1-phiBF

    ps[4,i,t,1] <- 0
    ps[4,i,t,2] <- 0
    ps[4,i,t,3] <- 0
    ps[4,i,t,4] <- 1

    # Define probabilities of O(t) given S(t)

    po[1,i,t,1] <- pNB
    po[1,i,t,2] <- 0
    po[1,i,t,3] <- 0
    po[1,i,t,4] <- 1-pNB

    po[2,i,t,1] <- pNST
    po[2,i,t,2] <- 0
    po[2,i,t,3] <- 0
    po[2,i,t,4] <- 1-pNST

    po[3,i,t,1] <- pBF
    po[3,i,t,2] <- 0
    po[3,i,t,3] <- 0
    po[3,i,t,4] <- 1-pBF

    po[4,i,t,1] <- 0
    po[4,i,t,2] <- 0
    po[4,i,t,3] <- 0
    po[4,i,t,4] <- 1
    } #t
  } #i

    # Likelihood 
    for (i in 1:nind){
    # Define latent state at first capture   
    z[i,f[i]] <- y[i,f[i]]
    for (t in (f[i]+1):n.occasions){
    # State process: draw S(t) given S(t-1)
    z[i,t] ~ dcat(ps[z[i,t-1], i, t-1,])
    # Observation process: draw O(t) given S(t)
    y[i,t] ~ dcat(po[z[i,t], i, t-1,])
    } #t
  } #i
}
    ",fill = TRUE)
sink()

#### R CODE TO RUN MODEL ####

# Bundle data
jags.data <- list(y = rCH, f = f, n.occasions = dim(rCH)[2], nind = dim(rCH)[1],
                  z = known.state.ms(rCH, 4))

# Initial values 
inits <- function(){list(phiNB = runif(1, 0, 1), phiNST = runif(1, 0, 1), phiBF = runif(1, 0, 1),
                         lpsiNB = rnorm(2), lpsiNST = rnorm(2), lpsiBF = rnorm(2),
                         pNB = runif(1, 0, 1) , pNST = runif(1, 0, 1) , pBF = runif(1, 0, 1),
                         z = ms.init.z(rCH, f))}  


# Parameters monitored
parameters <- c("phiNB", "phiNST", "phiBF",
                "psiNB", "psiNST", "psiBF",
                "pNB", "pNST", "pBF")

# MCMC settings
ni <- 100 # very few just to see if model will initialize
nt <- 1
nb <- 20
nc <- 3

# Call JAGS from R (BRT 56 min)
ms.test <- jags(jags.data, inits, parameters, "SESA-multistate.jags",
          n.chains = nc, n.thin = nt, n.iter = ni, n.burnin = nb)

print(ms.test, digits = 3)

Заранее большое спасибо!

(Примечание: я я публикую это на справочном форуме JAGS )

...