GLM起始值不被接受的问题(对数链接)

11

我想使用对数链接和偏移量运行高斯广义线性模型。

以下问题可能会出现:

y <- c(1,1,0,0)
t <- c(5,3,2,4)

没问题:

exp(coef(glm(y~1 +  offset(log(t)), family=poisson)))

使用 family=gaussian 时,需要指定起始值,在这里有效:

exp(coef(glm(y~1, family=gaussian(link=log), start=0)))

但这里不起作用:

exp(coef(glm(y~1 +  offset(log(t)), family=gaussian(link=log), start=0)))

在评估(expr, envir, enclos)时出错:找不到有效的起始值:请指定一些

有人看到问题出在哪里了吗(希望只是我的编码问题)?


1
“不起作用”比实际的错误信息“在eval(expr,envir,enclos)中出错:无法找到有效的起始值:请指定一些”要少有用。我尝试了一些简单的glm(y〜1 + offset(junk)),一切正常。我认为您的数据集非常小,并且具有一些不太可能的偏移量,因此glm无法找到适合的拟合。” - Carl Witthoft
我的“非常小的数据集”是人们所称的最小示例,让您... - Andi
你是不是试图取0的对数? - James
不,起始值应该在线性预测器比例上,这意味着它从beta_zero=0开始。其他起始值相同的错误。不知道为什么R要求指定起始值时实际上已经指定了... - Andi
1
@Andi 我的意思是在y值中取对数0。尝试使用非零正数的y,它将起作用,并且不需要start - James
2个回答

15

以下是一些考古工作的结果,它解释了在glm函数深处发生了什么:

通过调试(使用debug("glm"))并逐步执行函数,可以发现它在以下调用处失败:

if (length(offset) && attr(mt, "intercept") > 0L) {
  fit$null.deviance <- eval(call(if (is.function(method)) "method" else method, 
    x = X[, "(Intercept)", drop = FALSE], y = Y, weights = weights, 
    offset = offset, family = family, control = control, 
    intercept = TRUE))$deviance
}

这是计算模型的零偏差的尝试。仅在存在截距项和偏移项时进行评估(我不确定为什么;可能是由于上一次调用 glm 计算的默认零偏差在这种情况下是错误的,必须重新计算?)。它调用 glm.fitmethod 的默认值),但是没有启动值,因为对于仅有截距的模型来说,通常不需要启动值。

现在正在 glm.fit 内部进行调试以查看发生了什么:我们(在调用 family 函数 gaussian() 时)得到:

  if (is.null(etastart) && is.null(start) && is.null(mustart) && 
    ((family$link == "inverse" && any(y == 0)) || (family$link == 
        "log" && any(y <= 0))))
    stop("cannot find valid starting values: please specify some")

我们可以看到,由于起始值未经过传递,使用了对数链接,并且有一些y值等于零,拟合失败了。因此,仅当同时指定偏移量和截距、使用对数链接并且响应值为零时,才会发生这种情况。

如果您运行dump("glm",file="glmtemp.R"),请添加以下行。

    start = start[1], etastart = etastart[1], mustart = mustart[1],

对于适合零偏差(即上面显示的那个)的调用,以及source("glmtemp.R"),它似乎可以正常工作...我认为这应该是一个合理的通用解决方案。如果有人想在R开发列表中提出这个问题,请随意。


通过您的参与,技术问题已得到解决。谢谢!您能否给我一个提示,为什么估计参数与泊松GLM不同?(相同的偏移量,相同的对数链接)没有偏移项,两个估计是相同的。 - Andi
我没有时间深入研究这个问题,但你为什么会期望它们是相同的呢?我认为非偏移模型相同是一个特殊情况...我建议逐步分析模型定义(即,在链接比例上找到最小的预期方差加权平方和,有或没有偏移)。 - Ben Bolker
2
不错的发现! :) 我认为有一个更好的修复方法:只需添加 mustart = fit$fitted.values。我已经在 https://bugs.r-project.org/bugzilla/show_bug.cgi?id=16877 提交了一个补丁。 - bastistician

10

看起来当存在offset时无法识别start。您试图对y值中的0取对数,这是-Infglm在不得到start的帮助下寻找解决方案时无法处理此问题。微调y值中的一个小量将允许解决方案。

exp(coef(glm(I(y+.Machine$double.eps)~1 + offset(log(t)), family=gaussian(link=log))))
(Intercept) 
  0.1481481

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接