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

R 如何在glmnet中指定日志链接?,r,glmnet,R,Glmnet,我在广义线性模型上运行一个弹性网络,在R中使用glmnet和caret包 我的响应变量是cost(其中cost>0美元),因此我想为我的GLM指定一个带有日志链接的Gaussian族。但是,glmnet似乎不允许我指定(link=“log”),如下所示: > lasso_fit <- glmnet(x, y, alpha=1, family="gaussian"(link="log"), lambda.min.ratio=.001) >lasso_-fit这有点令人困惑,但是glm

我在广义线性模型上运行一个弹性网络,在R中使用glmnet和caret包

我的响应变量是cost(其中cost>0美元),因此我想为我的GLM指定一个带有日志链接的Gaussian族。但是,glmnet似乎不允许我指定
(link=“log”)
,如下所示:

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

>lasso_-fit这有点令人困惑,但是
glmnet
glm
中的
family
参数有很大不同。在
glm
中,您可以指定一个
字符,如
“gaussian”
,也可以指定一个带有一些参数的函数,如
gaussian(link=“log”)
。在
glmnet
中,只能指定带有
字符的族,如
“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)

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

glmnet(x, y, family=gaussian(link="log"))
请注意,使用字符串参数时,程序包速度更快

参考:

太好了,谢谢。如果我像你建议的那样指定glmnet(x,log(y),family=“gaussian”),那么glmnet实际上是在估计log[E(y)](我想要的)而不是E[log(y)](对数线性OLS,我不想要的),对吗?老实说,直到五分钟前我才发现log[E(y)]并不完全等同于E[log(y)]。我运行了一些代码来测试
glm(y~x,family=gaussian(link=“log”))
相当于
glm(log(y)~x,family=gaussian)
,确实如此,所以我可能遗漏了一些基本的东西。嗯,我仔细检查了自己的数据,发现glm(log(y)~x,family=gaussian)与glm的回归系数不同(y~x,family=gaussian(link=“log”)),而lm(log(y)~x)和glm(log(y)~x,family=gaussian)生成相同的系数。不用担心-我会与glmnet的作者核实。我不敢相信他们会忽略这一点,因为带有对数链接的高斯族上的GLMs在医疗成本数据中相当常见。@RNs_Ghost No-再次阅读NOGRAPS的回复,唯一的另一种可能性是经常使用glmnet中的泊松链接作为具有日志链接的Gaussian族的“等价物”。但是,如果在Nograps toy数据集上运行以下代码:
glmnet.model,我认为这可能很困难。如果深入研究
glmnet
代码,您将看到
glmnet(…,family=“Gaussian”)
调用
elnet
,调用Fortran
spelnet
函数。(泊松回归调用
fishnet
,调用
fishnet
spfishnet
(用于密集与稀疏模型矩阵。)所以我怀疑有人必须从头开始写一个弹性网络的变体来处理日志链接。。。