GLM начальные значения не принимаются лог-ссылка - PullRequest
5 голосов
/ 21 ноября 2011

Я хочу запустить Gaussian GLM со ссылкой на журнал и смещением. Возникают следующие проблемы:

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)))

Ошибка в eval (expr, envir, enclos): не удается найти действительные начальные значения: укажите несколько "

Кто-нибудь видит, что не так (надеюсь, просто в моем кодировании)?

Ответы [ 2 ]

10 голосов
/ 21 ноября 2011

Похоже, start не распознается, когда присутствует offset. Вы пытаетесь взять лог 0 в значениях y, что составляет -Inf. glm, очевидно, не может справиться с этим при поиске решения без помощи start. Небольшое возмущение в ваших y значениях позволит решить проблему.

exp(coef(glm(I(y+.Machine$double.eps)~1 + offset(log(t)), family=gaussian(link=log))))
(Intercept) 
  0.1481481
9 голосов
/ 22 ноября 2011

Вот результаты некоторой археологии, которая объясняет, что происходит, глубоко внутри функции 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.fit (значение по умолчанию method), но без начальных значений, поскольку они обычно не нужны для модели только для перехвата.

Теперь отладка внутри glm.fit, чтобы увидеть, что происходит: мы попадаем на

  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, не стесняйтесь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...