[英]Custom Link function works for GLM but not mgcv GAM
抱歉,如果答案很明显,但我花了很多时间尝试在mgcv.gam中使用自定义链接功能
简而言之,
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.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
我将使用你想要使用的函数probit.2asym
g = 0.1
和lam = 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.