我编写了自己的Poisson似然函数,但对于具有特定数据交互的模型,它返回的值与glm明显不同。请注意,该函数与我尝试过的所有其他数据以及没有此数据交互的模型的glm结果完全相同。
fun mixAnimalsA(a1: Animal, a2: Animal) =
when (setOf(a1, a2)) {
setOf(Animal.OWL, Animal.Leopard) -> Beast.OWLPARD
setOf(Animal.ELEPHANT, Animal.BUTTERFLY) -> Beast.BUTTERPHANT
else -> throw Exception("Not possible combination")
}
这是特定于数据的吗?它是固有的吗? 优化过程,最终会与glm发生更大的分歧,我对这些数据感到不幸?它是使用method =“BFGS”进行优化的函数吗?
答案 0 :(得分:1)
通过重新调整右侧变量,结果会有很大改善。
> library(data.table)
> setDT(tmp)
> tmp[, x1 := scale(x1)][, x2 := scale(x2)]
>
>
> withmyfun = with(tmp, llpoi(cbind(x1, x2, x1 * x2), y))
> withmyfun
[,1] [,2]
[1,] 0.57076392 0.1124637
[2,] -0.19620040 0.1278070
[3,] -0.01509032 0.1169019
[4,] 0.05636459 0.1380611
>
> withglm = glm(y ~ x1 + x2 + x1 * x2, family = "poisson", data = tmp)
> summary(withglm)$coef[, 1:2]
Estimate Std. Error
(Intercept) 0.57075132 0.1124641
x1 -0.19618199 0.1278061
x2 -0.01507467 0.1169034
x1:x2 0.05636934 0.1380621
>
所以,我的建议是,在llpoi
内,有一个过程来规范化变量,然后再将optim
用于数据,并在函数返回值之前重新调整估计值。您的示例数据范围太大,导致系数估计非常小。由于相对平坦的可能性表面,由于无关紧要的变量,这个问题变得更糟。
注意:强>
除了拦截之外,您可以获得非常接近的输出。标准化的意思是这样的。
llpoi = function(X, y){
# Ensures X is a matrix
if(class(X) != "matrix") X = as.matrix(X)
# Ensures there's a constant
if(sum(X[, 1]) != nrow(X)) X = cbind(1, X)
# A useful scalar that I'll need below
avgs <- c(0, apply(X[, 2:ncol(X)], 2, mean))
sds <- c(1, apply(X[, 2:ncol(X)], 2, sd))
X<- t((t(X) - avgs)/sds)
k = ncol(X)
## Function to be maximized
FUN = function(par, X, y){
# beta hat -- the parameter we're trying to estimate
betahat = par[1:k]
# mu hat -- the systematic component
muhat = X %*% betahat
# Log likelihood function
sum(muhat * y - exp(muhat))
}
# Optimizing
opt = optim(rep(0, k), fn = FUN, y = y, X = X, control = list(fnscale = -1), method = "BFGS", hessian = T)
# Results, including getting the SEs from the hessian
cbind(opt$par, sqrt(diag(solve(-1 * opt$hessian))))/sds
}
答案 1 :(得分:-1)
经过大量研究,我了解到两个结果不同,因为glm.fit,glm背后的主力通过Newton-Raphson方法优化了函数,而我在llpoi函数中使用了BFGS。 BFGS更快,但不太精确。在大多数情况下,这两个结果非常相似,但是当表面积过大或者有太多的最大值时可能会有更大的差异,正如amatsuo_net正确指出的那样,因为BFGS使用的攀爬算法会卡住。