R: Configure Reversible Jump for Variable Selection

configureRJ {nimble} | R Documentation

## Configure Reversible Jump for Variable Selection

### Description

Modifies an MCMC configuration object to perform a reversible jump MCMC sampling for variable selection, using a univariate normal proposal distribution. Users can control the mean and scale of the proposal. This function supports two different types of model specification: with and without indicator variables.

### Usage

    configureRJ(conf, targetNodes, indicatorNodes = NULL, priorProb = NULL,
      control = list(mean = NULL, scale = NULL, fixedValue = NULL))

### Arguments

`conf` | An `MCMCconf` object.
`targetNodes` | A character vector, specifying the nodes and/or variables for which variable selection is to be performed. Nodes may be specified in their indexed form, `'y[1, 3]'`. Alternatively, nodes specified without indexing will be expanded, e.g., `'x'` will be expanded to `'x[1]'`, `'x[2]'`, etc.
`indicatorNodes` | An optional character vector, specifying the indicator nodes and/or variables paired with `targetNodes`. Nodes may be specified in their indexed form, `'y[1, 3]'`. Alternatively, nodes specified without indexing will be expanded, e.g., `'x'` will be expanded to `'x[1]'`, `'x[2]'`, etc. Nodes must be provided consistently with `targetNodes`. See details.
`priorProb` | An optional value or vector of prior probabilities for each node to be in the model. See details.
`control` | An optional list of control arguments: mean. The mean of the normal proposal distribution (default = 0). scale. The standard deviation of the normal proposal distribution (default = 1). fixedValue. Value for the variable when it is out of the model, which can be used only when `priorProb` is provided (default = 0). If specified when `indicatorNodes` is passed, a warning is given and `fixedValue` is ignored.

### Details

This function modifies the samplers in MCMC configuration object for each of the nodes provided in the `targetNodes` argument. To these elements two samplers are assigned: a reversible jump sampler to transition the variable in/out of the model, and a modified version of the original sampler, which performs updates only when the target node is already in the model.

`configureRJ` can handle two different ways of writing a NIMBLE model, either with or without indicator variables. When using indicator variables, the `indicatorNodes` argument must be provided. Without indicator variables, the `priorProb` argument must be provided. In the latter case, the user can provide a non-zero value for `fixedValue` if desired.

Note that this functionality is intended for variable selection in regression-style models but may be useful for other situations as well. At the moment, setting a variance component to zero and thereby removing a set of random effects that are explicitly part of a model will not work because MCMC sampling in that case would need to propose values for multiple parameters (the random effects), whereas the current functionality only proposes adding/removing a single model node.

### Value

`NULL` `configureRJ` modifies the input MCMC configuration object in place.

### Author(s)

Sally Paganin, Perry de Valpine, Daniel Turek

### References

Peter J. Green. (1995). Reversible jump Markov chain Monte Carlo computation and Bayesian model determination. Biometrika, 82(4), 711-732.

### See Also

`samplers` `configureMCMC`

### Examples

    ## Not run:

    ## Linear regression with intercept and two covariates, using indicator variables

    code <- nimbleCode({
      beta0 ~ dnorm(0, sd = 100)
      beta1 ~ dnorm(0, sd = 100)
      beta2 ~ dnorm(0, sd = 100)
      sigma ~ dunif(0, 100)
      z1 ~ dbern(psi)   ## indicator variable associated with beta1
      z2 ~ dbern(psi)   ## indicator variable associated with beta2
      psi ~ dunif(0, 1) ## hyperprior on inclusion probability
      for(i in 1:N) {
        Ypred[i] <- beta0 + beta1 * z1 * x1[i] + beta2 * z2 * x2[i]
        Y[i] ~ dnorm(Ypred[i], sd = sigma)
      }
    })

    ## simulate some data
    set.seed(1)
    N <- 100
    x1 <- runif(N, -1, 1)
    x2 <- runif(N, -1, 1) ## this covariate is not included
    Y <- rnorm(N, 1 + 2.5 * x1, sd = 1)

    ## build the model
    rIndicatorModel <- nimbleModel(code, constants = list(N = N),
                                   data = list(Y = Y, x1 = x1, x2 = x2),
                                   inits = list(beta0 = 0, beta1 = 0, beta2 = 0, sigma = sd(Y),
                                   z1 = 1, z2 = 1, psi = 0.5))

    indicatorModelConf <- configureMCMC(rIndicatorModel)

    ## Add reversible jump
    configureRJ(conf = indicatorModelConf,        ## model configuration
                targetNodes = c("beta1", "beta2"), ## coefficients for selection
                indicatorNodes = c("z1", "z2"),    ## indicators paired with coefficients
                control = list(mean = 0, scale = 2))

    indicatorModelConf$addMonitors("beta1", "beta2", "z1", "z2")

    rIndicatorMCMC <- buildMCMC(indicatorModelConf)
    cIndicatorModel <- compileNimble(rIndicatorModel)
    cIndicatorMCMC <- compileNimble(rIndicatorMCMC, project = rIndicatorModel)

    set.seed(1)
    samples <- runMCMC(cIndicatorMCMC, 10000, nburnin = 6000)

    ## posterior probability to be included in the mode
    mean(samples[ , "z1"])
    mean(samples[ , "z2"])

    ## posterior means when in the model
    mean(samples[ , "beta1"][samples[ , "z1"] != 0])
    mean(samples[ , "beta2"][samples[ , "z2"] != 0])

    ## Linear regression with intercept and two covariates, without indicator variables

    code <- nimbleCode({
      beta0 ~ dnorm(0, sd = 100)
      beta1 ~ dnorm(0, sd = 100)
      beta2 ~ dnorm(0, sd = 100)
      sigma ~ dunif(0, 100)
      for(i in 1:N) {
        Ypred[i] <- beta0 + beta1 * x1[i] + beta2 * x2[i]
        Y[i] ~ dnorm(Ypred[i], sd = sigma)
      }
    })

    rNoIndicatorModel <- nimbleModel(code, constants = list(N = N),
                                     data = list(Y = Y, x1 = x1, x2 = x2),
                                     inits=  list(beta0 = 0, beta1 = 0, beta2 = 0, sigma = sd(Y)))

    noIndicatorModelConf <- configureMCMC(rNoIndicatorModel)

    ## Add reversible jump
    configureRJ(conf = noIndicatorModelConf,      ## model configuration
                targetNodes = c("beta1", "beta2"), ## coefficients for selection
                priorProb = 0.5,                   ## prior probability of inclusion
                control = list(mean = 0, scale = 2))

    ## add monitors
    noIndicatorModelConf$addMonitors("beta1", "beta2")
    rNoIndicatorMCMC <- buildMCMC(noIndicatorModelConf)

    cNoIndicatorModel <- compileNimble(rNoIndicatorModel)
    cNoIndicatorMCMC <- compileNimble(rNoIndicatorMCMC, project = rNoIndicatorModel)

    set.seed(1)
    samples <- runMCMC(cNoIndicatorMCMC, 10000, nburnin = 6000)

    ## posterior probability to be included in the mode
    mean(samples[ , "beta1"] != 0)
    mean(samples[ , "beta2"] != 0)

    ## posterior means when in the model
    mean(samples[ , "beta1"][samples[ , "beta1"] != 0])
    mean(samples[ , "beta2"][samples[ , "beta2"] != 0])

    ## End(Not run)

[Package nimble version 0.9.1 Index]