Как glmnet вычисляет максимальное значение лямбда?

на glmnet пакет использует ряд LASSO настройка параметров lambda масштабируется от максимальной lambda_max под которым никакие предикторы не выбраны. Я хочу узнать, как glmnet вычисляет этот lambda_max значение. Например, в тривиальном наборе:

set.seed(1)
library("glmnet")
x <- matrix(rnorm(100*20),100,20)
y <- rnorm(100)
fitGLM <- glmnet(x,y)
max(fitGLM$lambda)
# 0.1975946

виньетка пакета (http://www.jstatsoft.org/v33/i01/paper) описывает в разделе 2.5, что он вычисляет это значение следующим образом:

sx <- as.matrix(scale(x))
sy <- as.vector(scale(y))
max(abs(colSums(sx*sy)))/100
# 0.1865232

что явно близко, но не то же самое значение. Так в чем же причина этой разницы? И в связанном вопросе, как я мог вычислить lambda_max для логистической регрессии?

4 ответов


чтобы получить тот же результат, вам нужно стандартизировать переменные, используя стандартное отклонение с n вместо n-1 знаменатель.

mysd <- function(y) sqrt(sum((y-mean(y))^2)/length(y))
sx <- scale(x,scale=apply(x, 2, mysd))
sx <- as.matrix(sx, ncol=20, nrow=100)
sy <- as.vector(scale(y, scale=mysd(y)))
max(abs(colSums(sx*sy)))/100
## [1] 0.1758808
fitGLM <- glmnet(sx,sy)
max(fitGLM$lambda)
## [1] 0.1758808

Кажется lambda_max для логистической регрессии вычисляется аналогично, с весами, основанными на пропорциях классов:

set.seed(1)
library("glmnet")
x <- matrix(rnorm(100*20),100,20)
y <- rnorm(100)

mysd <- function(y) sqrt(sum((y-mean(y))^2)/length(y))
sx <- scale(x, scale=apply(x, 2, mysd))
sx <- as.matrix(sx, ncol=20, nrow=100)

y_bin <- factor(ifelse(y<0, -1, 1))
prop.table(table(y_bin)) 
# y_bin
#   -1    1 
# 0.62 0.38 
fitGLM_log <- glmnet(sx, y_bin, family = "binomial")
max(fitGLM_log$lambda)
# [1] 0.1214006
max(abs(colSums(sx*ifelse(y<0, -.38, .62))))/100
# [1] 0.1214006

для вашего второго вопроса, посмотрите на статью Фридмана и др., "пути регуляризации для обобщенных линейных моделей через координатный спуск". В частности, см. уравнение (10), которое является равенством при равновесии. Просто проверьте, при каких условиях числитель $S (\cdot,\cdot)$ равен нулю для всех параметров.


По данным help("glmnet") максимальное значение лямбда-это "наименьшее значение, для которого все коэффициенты равны нулю":

sum(fitGLM$beta[, which.max(fitGLM$lambda)])
#[1] 0
sum(glmnet(x,y, lambda=max(fitGLM$lambda)*0.999)$beta)
#[1] -0.0001809804

на быстрый взгляд значение, кажется, вычисляется с помощью кода Fortran, называемого elnet.