Title: | Inference for Linear Models with Nuisance Parameters |
---|---|
Description: | Efficient Frequentist profiling and Bayesian marginalization of parameters for which the conditional likelihood is that of a multivariate linear regression model. Arbitrary inter-observation error correlations are supported, with optimized calculations provided for independent-heteroskedastic and stationary dependence structures. |
Authors: | Martin Lysy [aut, cre], Bryan Yates [aut] |
Maintainer: | Martin Lysy <[email protected]> |
License: | GPL-3 |
Version: | 1.1.2 |
Built: | 2024-11-20 04:20:38 UTC |
Source: | https://github.com/mlysy/lmn |
Efficient profile likelihood and marginal posteriors when nuisance parameters are those of linear regression models.
Consider a model of the form
where is the response matrix,
is a covariate matrix which depends on
,
is the coefficient matrix,
and
are the between-row and between-column variance matrices, and (suppressing the dependence on
) the Matrix-Normal distribution is defined by the multivariate normal distribution
where
is a vector of length
stacking the columns of of
, and
is the Kronecker product.
The model above is referred to as a Linear Model with Nuisance parameters (LMN) , with parameters of interest
. That is, the LMN package provides tools to efficiently conduct inference on
first, and subsequently on
, by Frequentist profile likelihood or Bayesian marginal inference with a Matrix-Normal Inverse-Wishart (MNIW) conjugate prior on
.
Maintainer: Martin Lysy [email protected]
Authors:
Bryan Yates
Useful links:
Report bugs at https://github.com/mlysy/LMN/issues
Converts a list of return values of multiple calls to lmn_prior()
or lmn_post()
to a single list of MNIW parameters, which can then serve as vectorized arguments to the functions in mniw.
list2mniw(x)
list2mniw(x)
x |
List of |
A list with the following elements:
Lambda
The mean matrices as an array of size p x p x n
.
Omega
The between-row precision matrices, as an array of size p x p x
.
Psi
The between-column scale matrices, as an array of size q x q x n
.
nu
The degrees-of-freedom parameters, as a vector of length n
.
Loglikelihood function for LMN models.
lmn_loglik(Beta, Sigma, suff)
lmn_loglik(Beta, Sigma, suff)
Beta |
A |
Sigma |
A |
suff |
An object of class |
Scalar; the value of the loglikelihood.
# generate data n <- 50 q <- 3 Y <- matrix(rnorm(n*q),n,q) # response matrix X <- 1 # intercept covariate V <- 0.5 # scalar variance specification suff <- lmn_suff(Y, X = X, V = V) # sufficient statistics # calculate loglikelihood Beta <- matrix(rnorm(q),1,q) Sigma <- diag(rexp(q)) lmn_loglik(Beta = Beta, Sigma = Sigma, suff = suff)
# generate data n <- 50 q <- 3 Y <- matrix(rnorm(n*q),n,q) # response matrix X <- 1 # intercept covariate V <- 0.5 # scalar variance specification suff <- lmn_suff(Y, X = X, V = V) # sufficient statistics # calculate loglikelihood Beta <- matrix(rnorm(q),1,q) Sigma <- diag(rexp(q)) lmn_loglik(Beta = Beta, Sigma = Sigma, suff = suff)
Marginal log-posterior for the LMN model.
lmn_marg(suff, prior, post)
lmn_marg(suff, prior, post)
suff |
An object of class |
prior |
A list with elements |
post |
A list with elements |
The scalar value of the marginal log-posterior.
# generate data n <- 50 q <- 2 p <- 3 Y <- matrix(rnorm(n*q),n,q) # response matrix X <- matrix(rnorm(n*p),n,p) # covariate matrix V <- .5 * exp(-(1:n)/n) # Toeplitz variance specification suff <- lmn_suff(Y = Y, X = X, V = V, Vtype = "acf") # sufficient statistics # default noninformative prior pi(Beta, Sigma) ~ |Sigma|^(-(q+1)/2) prior <- lmn_prior(p = suff$p, q = suff$q) post <- lmn_post(suff, prior = prior) # posterior MNIW parameters lmn_marg(suff, prior = prior, post = post)
# generate data n <- 50 q <- 2 p <- 3 Y <- matrix(rnorm(n*q),n,q) # response matrix X <- matrix(rnorm(n*p),n,p) # covariate matrix V <- .5 * exp(-(1:n)/n) # Toeplitz variance specification suff <- lmn_suff(Y = Y, X = X, V = V, Vtype = "acf") # sufficient statistics # default noninformative prior pi(Beta, Sigma) ~ |Sigma|^(-(q+1)/2) prior <- lmn_prior(p = suff$p, q = suff$q) post <- lmn_post(suff, prior = prior) # posterior MNIW parameters lmn_marg(suff, prior = prior, post = post)
Calculates the parameters of the LMN model's Matrix-Normal Inverse-Wishart (MNIW) conjugate posterior distribution (see Details).
lmn_post(suff, prior)
lmn_post(suff, prior)
suff |
An object of class |
prior |
A list with elements |
The Matrix-Normal Inverse-Wishart (MNIW) distribution on random matrices
and symmetric positive-definite
is defined as
where the Matrix-Normal distribution is defined in lmn_suff()
.
The posterior MNIW distribution is required to be a proper distribution, but the prior is not. For example, prior = NULL
corresponds to the noninformative prior
A list with elements named as in prior
specifying the parameters of the posterior MNIW distribution. Elements Omega = NA
and nu = NA
specify that parameters Beta = 0
and Sigma = diag(q)
, respectively, are known and not to be estimated.
# generate data n <- 50 q <- 2 p <- 3 Y <- matrix(rnorm(n*q),n,q) # response matrix X <- matrix(rnorm(n*p),n,p) # covariate matrix V <- .5 * exp(-(1:n)/n) # Toeplitz variance specification suff <- lmn_suff(Y = Y, X = X, V = V, Vtype = "acf") # sufficient statistics
# generate data n <- 50 q <- 2 p <- 3 Y <- matrix(rnorm(n*q),n,q) # response matrix X <- matrix(rnorm(n*p),n,p) # covariate matrix V <- .5 * exp(-(1:n)/n) # Toeplitz variance specification suff <- lmn_suff(Y = Y, X = X, V = V, Vtype = "acf") # sufficient statistics
The conjugate prior for LMN models is the Matrix-Normal Inverse-Wishart (MNIW) distribution. This convenience function converts a partial MNIW prior specification into a full one.
lmn_prior(p, q, Lambda, Omega, Psi, nu)
lmn_prior(p, q, Lambda, Omega, Psi, nu)
p |
Integer specifying row dimension of |
q |
Integer specifying the dimension of |
Lambda |
Mean parameter for
|
Omega |
Row-wise precision parameter for
|
Psi |
Scale parameter for
|
nu |
Degrees-of-freedom parameter for |
The Matrix-Normal Inverse-Wishart (MNIW) distribution on random matrices
and symmetric positive-definite
is defined as
where the Matrix-Normal distribution is defined in lmn_suff()
.
A list with elements Lambda
, Omega
, Psi
, nu
with the proper dimensions specified above, except possibly Omega = NA
or nu = NA
(see Details).
# problem dimensions p <- 2 q <- 4 # default noninformative prior pi(Beta, Sigma) ~ |Sigma|^(-(q+1)/2) lmn_prior(p, q) # pi(Sigma) ~ |Sigma|^(-(q+1)/2) # Beta | Sigma ~ Matrix-Normal(0, I, Sigma) lmn_prior(p, q, Lambda = 0, Omega = 1) # Sigma = diag(q) # Beta ~ Matrix-Normal(0, I, Sigma = diag(q)) lmn_prior(p, q, Lambda = 0, Omega = 1, nu = NA)
# problem dimensions p <- 2 q <- 4 # default noninformative prior pi(Beta, Sigma) ~ |Sigma|^(-(q+1)/2) lmn_prior(p, q) # pi(Sigma) ~ |Sigma|^(-(q+1)/2) # Beta | Sigma ~ Matrix-Normal(0, I, Sigma) lmn_prior(p, q, Lambda = 0, Omega = 1) # Sigma = diag(q) # Beta ~ Matrix-Normal(0, I, Sigma = diag(q)) lmn_prior(p, q, Lambda = 0, Omega = 1, nu = NA)
Calculate the loglikelihood of the LMN model defined in lmn_suff()
at the MLE Beta = Bhat
and Sigma = Sigma.hat
.
lmn_prof(suff, noSigma = FALSE)
lmn_prof(suff, noSigma = FALSE)
suff |
An object of class |
noSigma |
Logical. If |
Scalar; the calculated value of the profile loglikelihood.
# generate data n <- 50 q <- 2 Y <- matrix(rnorm(n*q),n,q) # response matrix X <- matrix(1,n,1) # covariate matrix V <- exp(-(1:n)/n) # diagonal variance specification suff <- lmn_suff(Y, X = X, V = V, Vtype = "diag") # sufficient statistics # profile loglikelihood lmn_prof(suff) # check that it's the same as loglikelihood at MLE lmn_loglik(Beta = suff$Bhat, Sigma = suff$S/suff$n, suff = suff)
# generate data n <- 50 q <- 2 Y <- matrix(rnorm(n*q),n,q) # response matrix X <- matrix(1,n,1) # covariate matrix V <- exp(-(1:n)/n) # diagonal variance specification suff <- lmn_suff(Y, X = X, V = V, Vtype = "diag") # sufficient statistics # profile loglikelihood lmn_prof(suff) # check that it's the same as loglikelihood at MLE lmn_loglik(Beta = suff$Bhat, Sigma = suff$S/suff$n, suff = suff)
Calculate the sufficient statistics of an LMN model.
lmn_suff(Y, X, V, Vtype, npred = 0)
lmn_suff(Y, X, V, Vtype, npred = 0)
Y |
An |
X |
An
|
V , Vtype
|
The between-observation variance specification. Currently the following options are supported:
For |
npred |
A nonnegative integer. If positive, calculates sufficient statistics to make predictions for new responses. See Details. |
The multi-response normal linear regression model is defined as
where is the response matrix,
is the covariate matrix,
is the coefficient matrix,
and
are the between-row and between-column variance matrices, and the Matrix-Normal distribution is defined by the multivariate normal distribution
where
is a vector of length
stacking the columns of of
, and
is the Kronecker product.
The function lmn_suff()
returns everything needed to efficiently calculate the likelihood function
When npred > 0
, define the variables Y_star = rbind(Y, y)
, X_star = rbind(X, x)
, and V_star = rbind(cbind(V, w), cbind(t(w), v))
. Then lmn_suff()
calculates summary statistics required to estimate the conditional distribution
The inputs to lmn_suff()
in this case are Y = Y
, X = X_star
, and V = V_star
.
An S3 object of type lmn_suff
, consisting of a list with elements:
Bhat
The matrix
.
T
The matrix
.
S
The matrix
.
ldV
The scalar log-determinant of V
.
n
, p
, q
The problem dimensions, namely n = nrow(Y)
, p = nrow(Beta)
(or p = 0
if X = 0
), and q = ncol(Y)
.
In addition, when npred > 0
and with ,
, and
defined in Details:
Ap
The npred x q
matrix .
Xp
The npred x p
matrix .
Vp
The scalar .
# Data n <- 50 q <- 3 Y <- matrix(rnorm(n*q),n,q) # No intercept, diagonal V input X <- 0 V <- exp(-(1:n)/n) lmn_suff(Y, X = X, V = V, Vtype = "diag") # X = (scaled) Intercept, scalar V input (no need to specify Vtype) X <- 2 V <- .5 lmn_suff(Y, X = X, V = V) # X = dense matrix, Toeplitz variance matrix p <- 2 X <- matrix(rnorm(n*p), n, p) Tz <- SuperGauss::Toeplitz$new(acf = 0.5*exp(-seq(1:n)/n)) lmn_suff(Y, X = X, V = Tz, Vtype = "acf")
# Data n <- 50 q <- 3 Y <- matrix(rnorm(n*q),n,q) # No intercept, diagonal V input X <- 0 V <- exp(-(1:n)/n) lmn_suff(Y, X = X, V = V, Vtype = "diag") # X = (scaled) Intercept, scalar V input (no need to specify Vtype) X <- 2 V <- .5 lmn_suff(Y, X = X, V = V) # X = dense matrix, Toeplitz variance matrix p <- 2 X <- matrix(rnorm(n*p), n, p) Tz <- SuperGauss::Toeplitz$new(acf = 0.5*exp(-seq(1:n)/n)) lmn_suff(Y, X = X, V = Tz, Vtype = "acf")