我试图从我自己的数据中获取Hessian矩阵,我有两个结果 -
相对于numericHessian的结果,Hessian的结果非常小。
在这种情况下,我应该信任哪些结果?
具体来说,我使用的数据范围从350000到1100000,它们是9X2矩阵,总共有18个数据值。
我使用了一种标准偏差公式,“numericHessian”的结果从2到2矩阵的230到466不等,而“Hessian”的结果从-3.42e-18到1.34e-17不等。比前一个少得多。
您认为哪一种标准差的正确计算?
代码如下:
data=read.table("C:/file.txt", header=T);
data <- as.matrix(data);
library(plyr)
library(MASS)
w1 = tail(data/(rowSums(data)),1)
w2 = t(w1)
f <- function(x){
w1 = tail(x/(rowSums(x)),1)
w2 = t(w1)
r = ((w1%*%cov(cbind(x))%*%w2)^(1/2))
return(r)
}
library(maxLik);
numericHessian(f, t0=rbind(data[1,1], data[1,2]))
library(numDeriv);
hessian(f, rbind(data[1,1], data[1,2]), method="Richardson")
file.txt如下:
1 2
137 201
122 342
142 111
171 126
134 123
823 876
634 135
541 214
423 142
“numericHessian”的结果是:
[,1] [,2]
[1,] 0.007105427 0.007105427
[2,] 0.007105427 0.000000000
然后,“Hessian”的结果是:
[,1] [,2]
[1,] -3.217880e-15 -1.957243e-16
[2,] -1.957243e-16 1.334057e-16
非常感谢你。
答案 0 :(得分:4)
你没有给reproducible example,但我还是会尝试。
library(bbmle)
x <- 0:10
y <- c(26, 17, 13, 12, 20, 5, 9, 8, 5, 4, 8)
d <- data.frame(x,y)
LL <- function(ymax=15, xhalf=6)
-sum(stats::dpois(y, lambda=ymax/(1+x/xhalf), log=TRUE))
fit <- mle2(LL)
cc <- coef(fit)
以下是MLE中负对数似然函数的Hessian(二阶导数矩阵)的有限差分估计:反演这些矩阵给出了参数的方差 - 协方差矩阵的估计。
library(numDeriv)
hessian(LL,cc)
## [,1] [,2]
## [1,] 1.296717e-01 -1.185789e-15
## [2,] -1.185789e-15 4.922087e+00
library(maxLik)
numericHessian(LL, t0=cc)
## [,1] [,2]
## [1,] 0.1278977 0.000000
## [2,] 0.0000000 4.916956
因此,对于这个相对简单的示例,numDeriv::hessian
和maxLik::numericHessian
给出了非常相似的结果。因此,必须有一些你没有向我们展示过的东西,或者关于你问题的数字的特别之处。为了进一步发展,我们需要一个可重现的例子,请...
dat <- matrix(c(137,201,122,342,142,111,
171,126,134,123,823,876,
634,135,541,214,423,142),
byrow=TRUE,ncol=2)
f <- function(x){
w1 <- tail(x/(rowSums(x)),1)
sqrt(w1%*%cov(cbind(x))%*%t(w1))
}
p <- t(dat[1,1:2,drop=FALSE])
f(p) ## 45.25483
numDeriv::hessian(f,p)
## [,1] [,2]
## [1,] -3.217880e-15 -1.957243e-16
## [2,] -1.957243e-16 1.334057e-16
maxLik::numericHessian(f,t0=p)
## [,1] [,2]
## [1,] 0.007105427 0.007105427
## [2,] 0.007105427 0.000000000
好的,这些明显不同意。我不确定原因,但在这种特殊情况下,我们可以分析您正在做的事情,看看哪一个是正确的:
x/rowSums(x)
是1的向量,因此最后一个元素(w1 <- tail(...,1)
)只有1。sqrt(cov(cbind(x)))
。同样,由于x
是一列矩阵,cov()
只是方差,sqrt(cov(.))
只是标准偏差,或矢量的范数。numDeriv::hessian
正在给出正确答案我们还可以通过提高eps
的{{1}}来确认这一点:
numericHessian
底线是maxLik::numericHessian(f,t0=p,eps=1e-3)
## [,1] [,2]
## [1,] 0 0.000000e+00
## [2,] 0 -7.105427e-09
使用更准确(但更慢)的方法,但如果您小心,可以从numDeriv
获得合理的答案。