如何在glmnet中指定日志链接?

时间:2014-08-08 15:21:23

标签: r glmnet

我使用R中的glmnet和插入符号包在广义线性模型上运行弹性网。

我的响应变量是成本(其中费用> 0美元),因此我想为我的GLM指定一个带有日志链接的高斯族。但是,glmnet似乎不允许我指定(link="log")如下:

> lasso_fit <- glmnet(x, y, alpha=1, family="gaussian"(link="log"), lambda.min.ratio=.001)

我尝试过不同的变体,有没有引用,但没有运气。 glmnet文档没有讨论如何包含日志链接。

我错过了什么吗? family="gaussian"是否已隐式假设日志链接?

2 个答案:

答案 0 :(得分:5)

这有点令人困惑,但familyglmnet中的glm参数完全不同。在glm中,您可以指定character "gaussian",或者您可以使用某些参数指定一个函数,例如gaussian(link="log")。在glmnet中,您只能使用character指定系列,例如"gaussian",并且无法通过该参数自动设置链接。

gaussian的默认链接是identity函数,即根本没有转换。但是,请记住链接函数只是对y变量的转换;你可以自己指定一下:

glmnet(x, log(y), family="gaussian")

另请注意,poisson系列的默认链接为log,但目标函数将更改。请参阅前几段中?glmnet下的详细信息。


你的评论让我重新回答了我的回答;我有证据表明不正确

正如您所指出的,E [log(Y)]和log(E [Y])之间存在差异。我认为上面的代码所做的是适合E [log(Y)],这不是你想要的。以下是一些代码,用于生成数据并确认您在评论中注明的内容:

# Generate data
set.seed(1)
x <- replicate(3,runif(1000))
y <- exp(2*x[,1] + 3*x[,2] + x[,3] + runif(1000))
df <- data.frame(y,x)

# Run the model you *want*
glm(y~., family=gaussian(link="log"), data=df)$coef
# (Intercept)          X1          X2          X3 
#   0.4977746   2.0449443   3.0812333   0.9451073 

# Run the model you *don't want* (in two ways)    
glm(log(y)~., family=gaussian(link='identity'), data=df)$coef
# (Intercept)          X1          X2          X3 
#   0.4726745   2.0395798   3.0167274   0.9957110 
lm(log(y)~.,data=df)$coef
# (Intercept)          X1          X2          X3 
#   0.4726745   2.0395798   3.0167274   0.9957110 

# Run the glmnet code that I suggested - getting what you *don't want*.
library(glmnet)
glmnet.model <- glmnet(x,log(y),family="gaussian", thresh=1e-8, lambda=0)
c(glmnet.model$a0, glmnet.model$beta[,1])
#        s0        V1        V2        V3 
# 0.4726745 2.0395798 3.0167274 0.9957110 

答案 1 :(得分:0)

我知道这是一个古老的问题,但是在当前版本的(4.0-2)中,可以 使用glm族函数作为“族”的参数字符串,因此您可以使用:

glmnet(x, y, family=gaussian(link="log"))

请注意,使用字符串参数时,程序包会更快。

参考: https://glmnet.stanford.edu/articles/glmnetFamily.html