自定义链接功能适用于GLM,但不适用于mgcv GAM

时间:2016-09-30 13:48:07

标签: r regression glm gam mgcv

道歉,如果答案很明显,但我花了很长时间尝试在mgcv.gam中使用自定义链接功能

简而言之,

  • 我想使用包psyphy中的修改过的probit链接(我想使用psyphy.probit_2asym,我称之为custom_link
  • 我可以使用此链接创建一个{stats}系列对象,并将其用于'系列' glm的论点。

    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

我不明白这个错误的原因,如果我指定标准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")
}

1 个答案:

答案 0 :(得分:4)

如您所知,RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget); ... try { InputStream is = context.getAssets().open("image.jpg"); Bitmap bmp = BitmapFactory.decodeStream(is); remoteViews.setImageViewBitmap(R.id.widget_image, bmp); } catch (IOException e) { e.printStackTrace(); } 采用迭代重加权最小二乘法拟合迭代。 glm的早期版本通过拟合迭代惩罚重新加权最小二乘来扩展这一点,这由gam函数完成。在某些情况下,这称为性能迭代

自2008年(或稍早一点)以来,gam.fit基于所谓的外部迭代已将gam.fit3替换为gam.fit默认值。此类更改确实需要一些家庭的额外信息,您可以阅读gam

两次迭代之间的主要区别在于系数?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 的{​​{1}}和g = 0.1

lam = 0.1

enter image description here

我使用probit.2asym的自然三次样条基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) ,因为单变量平滑,不需要使用薄板样条的默认设置。我还设置了一个小的基础维cr(对于三次样条曲线来说可以小一些),因为我的玩具数据接近线性并且不需要大的基础尺寸。更重要的是,这似乎可以防止我的玩具数据集的性能迭代收敛失败。