我从伽马密度模拟了100个观测值:
x <- rgamma(100,shape=5,rate=5)
我尝试用R中的optim
函数得到最大似然估计量的渐近方差。为此,我手动计算了伽马密度的对数似然的表达式,并将其乘以-1因为optim
是最低限度的。这是我的代码:
min <- function(data, par) {
with(data, 1/par[2]*sum(x)-(par[1]-1)*sum(log(x))+n*(log(gamma(par[1]))+par[1]*log(par[2])))
}
mle <- optim(par=c(0,1),min,method='BFGS', hessian=TRUE)
AV <- 1 / mle$hessian
但是,我得到以下错误(因为第二行代码):
Error in eval(substitute(expr), data, enclos = parent.frame()) :
numeric 'envir' arg not of length one
有没有办法解决这个问题?任何提示都会很感激。谢谢。
P.S:我知道我可以找到渐近方差:
library(MASS)
AV <- (fitdistr(x, "gamma", start=list(shape=1, rate=1))$sd)^2
但那不是我想要的方式。
答案 0 :(得分:5)
Ok, let's go by parts.
First of all, your expression for the minus log likelihood is incorrect, as it is actually parameterized as a function of the shape and scale parameters. Since you sampled the data by defining the shape and rate parameters, it is simpler to maintain consistency. See https://en.wikipedia.org/wiki/Gamma_distribution
Second, the specification of the function for optim
is incorrect; the documentation explicitly mentions that in the function "first argument the vector of parameters over which minimization is to take place". In the code below, I left the data as a global variable that is accessed by the function to be minimized.
Third, in such a scenario it is advisable to enforce the constraints on the two parameters being estimated, otherwise the fitting may fail in some cases, depending on the sampled data.
Finally, the calculation of the asymptotic variance is incorrect: you need to invert the Fisher's information matrix; see, e.g., https://stats.stackexchange.com/questions/68080/basic-question-about-fisher-information-matrix-and-relationship-to-hessian-and-s
Here is the code:
# Data
x <- rgamma(100, shape = 5, rate = 5)
# Minus log likelihood function
minus_log_L_fun <- function(params) {
a <- params[1] # shape
b <- params[2] # rate (1 / scale)
n <- length(x) # sample size
log_L <- (a - 1) * sum(log(x)) - b * sum(x) + n * a * log(b) - n * log(gamma(a))
return (-log_L)
}
# Impose constraints on the estimates of the shape and rate parameters: both being strictly positive
# Use algorithm 'L-BFGS-B', since it allows for box constraints
mle <- optim(par = c(1, 1), minus_log_L_fun, method = "L-BFGS-B", lower = c(1e-10, 1e-10), upper = c(100, 100), hessian = TRUE)
# Retrieve the point estimates
shape_fit <- mle$par[1]
rate_fit <- mle$par[2]
# Fisher Information Matrix (equal to the Hessian, since minimizing minus log likelihood)
I <- mle$hessian
# Obtain the asymptotic variances (need to invert the FIM)
var_Theta <- diag(solve(I))
cat(sprintf("Results:\n"))
cat(sprintf("Point estimates: shape = %g, rate = %g\n", shape_fit, rate_fit))
cat(sprintf("Asymptotic ML variances: shape = %g, rate = %g\n", var_Theta[1], var_Theta[2]))
producing, for a particular run:
Results:
Point estimates: shape = 4.25661, rate = 4.08384
Asymptotic ML variances: shape = 0.336318, rate = 0.34875
Using the MASS
package to confirm:
library(MASS)
res <- fitdistr(x, "gamma", start = list(shape = 1, rate = 1))
MASS_PE <- res$estimate
MASS_AV <- (res$sd)^2
cat(sprintf("From the MASS package:\n"))
cat(sprintf("Point estimates:\n"))
print(MASS_PE)
cat(sprintf("Asymptotic variances:\n"))
print(MASS_AV)
leads to:
From the MASS package:
Point estimates:
shape rate
4.256613 4.083836
Asymptotic variances:
> print(MASS_AV)
shape rate
0.3363179 0.3487502
答案 1 :(得分:2)
set.seed(101)
x <- rgamma(100,shape=5,rate=5)
library("bbmle")
m1 <- mle2(x~dgamma(shape,rate=rate),
start=list(shape=2,rate=2), ## anything reasonable
data=data.frame(x) ## data must be specified as a data frame
)
我们收到一条警告信息,在这种情况下无害,但我们可以通过以下方式减轻:
m2 <- update(m1,lower=c(0,0),
method="L-BFGS-B")
现在我们可以轻松得到点估计和渐近方差 - 协方差矩阵:
coef(m2)
vcov(m2)
注意:
bbmle::mle2
是stats4::mle
的扩展,也应该适用于此问题(mle2
有一些额外的花里胡哨,并且更加健壮),尽管你会必须将对数似然函数定义为: nLL <- function(shape,rate) {
-sum(dgamma(x,shape,rate=rate,log=TRUE))
}
dgamma()
适用于您的问题时,使用内置分发功能(例如http://www.example.com/file.xxx
)是一个好主意;它们经过了充分测试,功能强大,并且使代码更易于阅读。