我在R中优化多元正态对数似然时遇到了麻烦,如果有人有好的解决方案,请告诉我。具体来说,我似乎无法保持协方差矩阵正定并使参数处于合理范围内。
让我更全面地介绍一下这个问题。我基本上正在尝试使用MLE同时解决这两个回归方程:
$$ y_1 = \beta_1 + \beta_2 x_1 + \beta_3 x_2 \\ y_2 = \beta_4 + \beta_3 x_1 + \beta_5 x_2 $$
事实上,$\beta_3$同时出现在两个方程式中并不是一个错误。我通过最大化多元正态分布的似然性来解决这个问题,其中$Y = (y_1, y_2)^\top$的均值像上述回归方程那样进行参数化。
我已经附上了对数似然函数,因为我认为它应该是这样的。我通过重新创建必须为正的特征值和Cholesky分解来将方差协方差矩阵限制为正定。
mvrestricted_ll <- function(par, Y, X) {
# Indices
n <- nrow(X)
nbetas <- (2 + 3 * (ncol(Y) - 1))
# Extract parameters
beta <- par[1:nbetas]
eigvals <- exp(par[(nbetas + 1):(nbetas + ncol(Y))]) # constrain to be positive
chole <- par[(nbetas + ncol(Y) + 1):(nbetas + ncol(Y) + ncol(Y)*(ncol(Y)+1)/2)]
# Build Sigma from positive eigenvalues and cholesky (should be pos def)
L <- diag(ncol(Y))
L[lower.tri(L, diag=T)] <- chole
Sigma <- diag(eigvals) + tcrossprod(L)
# Linear predictor
# Hard coded for 2x2 example for now
mu <- cbind(beta[1] + beta[2]*X[,1] + beta[3]*X[,2],
beta[4] + beta[3]*X[,1] + beta[5]*X[,2])
yminmu <- Y - mu
nlogs <- n * log(det(Sigma))
invSigma <- solve(Sigma)
meat <- yminmu %*% tcrossprod(invSigma, yminmu)
return(- nlogs - sum(diag(meat)))
}
# Create fake data
n <- 1000
p <- 2
set.seed(20160201)
X <- matrix(rnorm(n*p), nrow = n)
set.seed(20160201)
Y <- matrix(rnorm(n*p), nrow = n)
# Initialize parameters
initpars <- c(rep(0, (2 + 3 * (ncol(Y) - 1)) + ncol(Y) + ncol(Y)*(ncol(Y)+1)/2))
# Optimize fails with BFGS
optim(par = initpars, fn = mvrestricted_ll, X=X, Y=Y, method = "BFGS")
# Optim does not converge with Nelder-mead, if you up the maxits it also fails
optim(par = initpars, fn = mvrestricted_ll, X=X, Y=Y)
非常感谢您的帮助。
编辑:需要注意的是,仅在参数中让Sigma成为向量,然后在它不是正定时返回一个非常大的值也不起作用。