Dav*_*son 12 statistics r
glm.nb在某些输入上抛出异常错误.虽然有多种值导致此错误,但即使非常轻微地更改输入也可以防止错误.
一个可重复的例子:
set.seed(11)
pop <- rnbinom(n=1000,size=1,mu=0.05)
glm.nb(pop~1,maxit=1000)
Run Code Online (Sandbox Code Playgroud)
运行此代码会引发错误:
Error in while ((it <- it + 1) < limit && abs(del) > eps) { :
missing value where TRUE/FALSE needed
Run Code Online (Sandbox Code Playgroud)
起初我认为这与算法没有收敛有关.但是,我很惊讶地发现即使非常轻微地改变输入也可以防止错误.例如:
pop[1000] <- pop[1000] + 1
glm.nb(pop~1,maxit=1000)
Run Code Online (Sandbox Code Playgroud)
我发现它在1到500之间的19.4%的种子上引发了这个错误:
fit.with.seed = function(s) {
set.seed(s)
pop <- rnbinom(n=1000, size=1, mu=0.05)
m = glm.nb(pop~1, maxit=1000)
}
errors = sapply(1:500, function(s) {
is.null(tryCatch(fit.with.seed(s), error=function(e) NULL))
})
mean(errors)
Run Code Online (Sandbox Code Playgroud)
我发现在任何地方只有一个提到这个错误,在一个没有响应的线程上.
可能导致此错误的原因是什么,以及如何修复(除了每次glm.nb抛出错误时随机置换输入?)
ETA:设置control=glm.control(maxit=200,trace = 3)发现theta.ml算法因非常大而破坏,然后成为-Inf,然后成为NaN:
theta.ml: iter67 theta =5.77203e+15
theta.ml: iter68 theta =5.28327e+15
theta.ml: iter69 theta =1.41103e+16
theta.ml: iter70 theta =-Inf
theta.ml: iter71 theta =NaN
Run Code Online (Sandbox Code Playgroud)
这有点粗糙,但在过去,我已经能够glm.nb通过求助于直接最大似然估计来解决问题(即没有使用巧妙的迭代估计算法glm.nb)
一些poking/profiling表明theta参数的MLE实际上是无限的.我决定将它放在反比例尺上,这样我就可以将边界设置为0(一个更高级的版本会设置一个对数似然函数,它会在theta = 0处恢复为Poisson,但这会取消尝试的点.想出一个快速的罐装解决方案).
有了上面给出的两个不好的例子,这个工作得相当好,虽然它确实警告参数拟合在边界上......
library(bbmle)
m1 <- mle2(Y~dnbinom(mu=exp(logmu),size=1/invk),
data=d1,
parameters=list(logmu~X1+X2+offset(X3)),
start=list(logmu=0,invk=1),
method="L-BFGS-B",
lower=c(rep(-Inf,12),1e-8))
Run Code Online (Sandbox Code Playgroud)
第二个例子实际上更有趣,因为它在数字上证明了θ的MLE基本上是无限的,即使我们有一个大小合适的数据集,它是从负二项式偏差产生的(或者我对某些东西感到困惑......)
set.seed(11);pop <- rnbinom(n=1000,size=1,mu=0.05);glm.nb(pop~1,maxit=1000)
m2 <- mle2(pop~dnbinom(mu=exp(logmu),size=1/invk),
data=data.frame(pop),
start=list(logmu=0,invk=1),
method="L-BFGS-B",
lower=c(-Inf,1e-8))
Run Code Online (Sandbox Code Playgroud)