Как указать лог ссылку в glmnet?

Я использую эластичную сеть на обобщенной линейной модели с пакетами glmnet и caret в R.

Моя переменная ответа - это стоимость (где стоимость> $0), и поэтому я бы хотел указать семейство Гауссов со ссылкой на журнал для моего GLM. Однако glmnet не позволяет мне указывать (link="log") следующее:

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

Я пробовал разные варианты, с цитатами и без, но не повезло. В документации glmnet не обсуждается, как включить ссылку на журнал.

Я что-то пропустил? Есть ли family="gaussian" уже неявно предполагаем ссылку на логи?

1 ответ

Это немного сбивает с толку, но family аргумент в glmnet а также 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 

Я знаю, что это старый вопрос, но в текущей версии glmnet (4.0-2), что это можно использовать GLM семейных функций в качестве аргументов для "семьи" вместо строки символов, так что вы можете использовать:

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

Обратите внимание, что при использовании строковых аргументов пакет работает быстрее.

Ссылка: https://glmnet.stanford.edu/articles/glmnetFamily.html

Другие вопросы по тегам