我应该首先说明我要做的事情:我想使用mle函数,而不必在每次我想尝试不同的模型规范时重新编写我的对数似然函数。因为mle期望一个命名的起始值列表,所以你显然不能将对数似然函数写成带参数的向量。一个简单的例子:
假设我想通过最大可能性拟合线性回归模型,首先,我忽略了我的一个预测因素:
n <- 100
df <- data.frame(x1 = runif(n), x2 = runif(n), y = runif(n))
Y <- df$y
X <- model.matrix(lm(y ~ x1, data = df))
# define log-likelihood function
ll <- function(beta0, beta1, sigma){
beta = matrix(NA, nrow=2, ncol=1)
beta[,1] = c(beta0, beta1)
-sum(log(dnorm(Y - X %*% beta, 0, sigma)))
}
library(stats4)
mle(ll, start = list(beta0=.1, beta1=.2, sigma=1)
现在,如果我想要适合不同的模型,请说:
m <- lm(y ~ x1 + x2, data = df)
我无法重新使用我的对数似然函数 - 我必须重新编写它以获得beta3参数。我想做的是:
ll.flex <- function(theta){
# theta is a vector that I can use directly
...
}
if 然后我可以以某种方式调整mle中的start参数来解释我现在的向量输入对数似然函数,或者除此之外,有一个在运行时构造对数似然函数的函数-time,比如通过构造命名的参数列表然后用它来定义函数,例如:
X <- model.matrix(lm(y ~ x1 + x2, data = df))
arguments <- rep(NA, dim(X)[2])
names(arguments) <- colnames(X)
ll.magic <- function(bring.this.to.life.as.function.arguments(arguments)){...}
更新:
我最终编写了一个辅助函数,可以向传递的函数f添加任意数量的命名参数x1,x2,x3 ....
add.arguments <- function(f,n){
# adds n arguments to a function f; returns that new function
t = paste("arg <- alist(",
paste(sapply(1:n, function(i) paste("x",i, "=",sep="")), collapse=","),
")", sep="")
formals(f) <- eval(parse(text=t))
f
}
这很丑陋,但它完成了工作,让我在运行中重新考虑我的对数似然函数。
答案 0 :(得分:5)
您可以使用包mle2
中的bbmle
函数,该函数允许您将向量作为参数传递。这是一些示例代码。
# REDEFINE LOG LIKELIHOOD
ll2 = function(params){
beta = matrix(NA, nrow = length(params) - 1, ncol = 1)
beta[,1] = params[-length(params)]
sigma = params[[length(params)]]
minusll = -sum(log(dnorm(Y - X %*% beta, 0, sigma)))
return(minusll)
}
# REGRESS Y ON X1
X <- model.matrix(lm(y ~ x1, data = df))
mle2(ll2, start = c(beta0 = 0.1, beta1 = 0.2, sigma = 1),
vecpar = TRUE, parnames = c('beta0', 'beta1', 'sigma'))
# REGRESS Y ON X1 + X2
X <- model.matrix(lm(y ~ x1 + x2, data = df))
mle2(ll2, start = c(beta0 = 0.1, beta1 = 0.2, beta2 = 0.1, sigma = 1),
vecpar = TRUE, parnames = c('beta0', 'beta1', 'beta2', 'sigma'))
这会给你
Call:
mle2(minuslogl = ll2, start = c(beta0 = 0.1, beta1 = 0.2, beta2 = 0.1,
sigma = 1), vecpar = TRUE, parnames = c("beta0", "beta1",
"beta2", "sigma"))
Coefficients:
beta0 beta1 beta2 sigma
0.5526946 -0.2374106 0.1277266 0.2861055
答案 1 :(得分:4)
直接使用optim
可能更容易;这就是mle
正在使用的东西。
ll2 <- function(par, X, Y){
beta <- matrix(c(par[-1]), ncol=1)
-sum(log(dnorm(Y - X %*% beta, 0, par[1])))
}
getp <- function(X, sigma=1, beta=0.1) {
p <- c(sigma, rep(beta, ncol(X)))
names(p) <- c("sigma", paste("beta", 0:(ncol(X)-1), sep=""))
p
}
set.seed(5)
n <- 100
df <- data.frame(x1 = runif(n), x2 = runif(n), y = runif(n))
Y <- df$y
X1 <- model.matrix(y ~ x1, data = df)
X2 <- model.matrix(y ~ x1 + x2, data = df)
optim(getp(X1), ll2, X=X1, Y=Y)$par
optim(getp(X2), ll2, X=X2, Y=Y)$par
输出
> optim(getp(X1), ll2, X=X1, Y=Y)$par
sigma beta0 beta1
0.30506139 0.47607747 -0.04478441
> optim(getp(X2), ll2, X=X2, Y=Y)$par
sigma beta0 beta1 beta2
0.30114079 0.39452726 -0.06418481 0.17950760
答案 2 :(得分:3)
它可能不是你想要的,但我会这样做:
mle2(y ~ dnorm(mu, sigma),parameters=list(mu~x1 + x2), data = df,
start = list(mu = 1,sigma = 1))
mle2(y ~ dnorm(mu,sigma), parameters = list(mu ~ x1), data = df,
start = list(mu=1,sigma=1))
您可能可以针对多项式调整此公式,但dmultinom
可能不起作用 - 您可能需要编写一个Dmultinom()
,其中包含多项式样本矩阵并返回(日志)概率。
答案 3 :(得分:0)
Ramnath提供的R代码也可以应用于optim函数,因为 它也将矢量作为参数。