簡體   English   中英

自定義鏈接功能適用於GLM,但不適用於mgcv GAM

[英]Custom Link function works for GLM but not mgcv GAM

抱歉,如果答案很明顯,但我花了很多時間嘗試在mgcv.gam中使用自定義鏈接功能

簡而言之,

  • 我想使用包psyphy中的修改后的probit鏈接(我想使用psyphy.probit_2asym ,我稱之為custom_link
  • 我可以使用此鏈接創建一個{stats}系列對象,並在glm的“family”參數中使用它。

    m <- glm(y~x, family=binomial(link=custom_link), ... )

  • 當用作{mgcv} gam的參數時,它不起作用

    m <- gam(y~s(x), family=binomial(link=custom_link), ... )

    Error in fix.family.link.family(family) : link not recognised收到錯誤Error in fix.family.link.family(family) : link not recognised

我沒有得到這個錯誤的原因,如果我指定標准link=probit ,glm和gam都會工作。

所以我的問題可歸納為:

這個自定義鏈接中缺少哪些適用於glm但不適用於gam?

如果你能給我一些關於我該做什么的提示,請提前致謝。


鏈接功能

probit.2asym <- function(g, lam) {
    if ((g < 0 ) || (g > 1))
        stop("g must in (0, 1)")
    if ((lam < 0) || (lam > 1))
        stop("lam outside (0, 1)")
    linkfun <- function(mu) {
        mu <- pmin(mu, 1 - (lam + .Machine$double.eps))
        mu <- pmax(mu, g + .Machine$double.eps)
        qnorm((mu - g)/(1 - g - lam))
        }
    linkinv <- function(eta) {
        g + (1 - g - lam) * 
         pnorm(eta)
        }
    mu.eta <- function(eta) {
        (1 - g - lam) * dnorm(eta)      }
    valideta <- function(eta) TRUE
    link <- paste("probit.2asym(", g, ", ", lam, ")", sep = "")
    structure(list(linkfun = linkfun, linkinv = linkinv, 
    mu.eta = mu.eta, valideta = valideta, name = link), 
    class = "link-glm")
}

如您所知, glm采用迭代重加權最小二乘擬合迭代。 早期版本的gam通過擬合迭代懲罰的重加權最小二乘來擴展這一點,這是由gam.fit函數完成的。 這在某些上下文中稱為性能迭代

自2008年以來(或者略微甚至更早), gam.fit3基於所謂外迭代已經取代gam.fitgam默認。 這種變化確實需要一些關於家庭的額外信息,您可以閱讀這些信息?fix.family.link

兩次迭代之間的主要差異是系數beta迭代和平滑參數lambda迭代是否嵌套。

  • 性能迭代采用嵌套方式,每次更新beta ,執行單次lambda迭代;
  • 外部迭代完全分離了這兩個迭代,其中對於beta每次更新, lambda迭代被帶到最后直到收斂。

顯然,外迭代更穩定,並且不太可能遭受收斂失敗。

gam有一個參數optimizer 默認情況下,它需要optimizer = c("outer", "newton") ,這是外部迭代的牛頓方法; 但如果你設置optimizer = "perf" ,它將需要性能迭代。


因此,在上述概述之后,我們有兩個選擇:

  • 仍然使用外部迭代,但擴展您的自定義鏈接功能;
  • 使用性能迭代來保持與glm

我很懶,所以會展示第二個(實際上我對第一種方法感覺不太自信)


可重復的例子

您沒有提供可重復的示例,因此我准備如下。

set.seed(0)
x <- sort(runif(500, 0, 1))    ## covariates (sorted to make plotting easier)
eta <- -4 + 3 * x * exp(x) - 2 * log(x) * sqrt(x)   ## true linear predictor
p <- binomial(link = "logit")$linkinv(eta)    ## true probability (response)
y <- rbinom(500, 1, p)    ## binary observations

table(y)    ## a quick check that data are not skewed
#  0   1 
#271 229 

我將使用你想要使用的函數probit.2asym g = 0.1lam = 0.1

probit2 <- probit.2asym(0.1, 0.1)

par(mfrow = c(1,3))

## fit a glm with logit link
glm_logit <- glm(y ~ x, family = binomial(link = "logit"))
plot(x, eta, type = "l", main = "glm with logit link")
lines(x, glm_logit$linear.predictors, col = 2)

## glm with probit.2asym
glm_probit2 <- glm(y ~ x, family = binomial(link = probit2))
plot(x, eta, type = "l", main = "glm with probit2")
lines(x, glm_probit2$linear.predictors, col = 2)

## gam with probit.2aysm
library(mgcv)
gam_probit2 <- gam(y ~ s(x, bs = 'cr', k = 3), family = binomial(link = probit2),
                   optimizer = "perf")
plot(x, eta, type = "l", main = "gam with probit2")
lines(x, gam_probit2$linear.predictors, col = 2)

在此輸入圖像描述

我使用s(x)自然三次樣條基礎cr ,對於單變量平滑,不需要使用薄板樣條的默認設置。 我還設置了一個小的基礎維度k = 3 (對於三次樣條曲線不能更小),因為我的玩具數據接近線性並且不需要大的基礎尺寸。 更重要的是,這似乎可以防止我的玩具數據集的性能迭代收斂失敗。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM