El LASSO adaptativo se utiliza para una selección de variables consistente. Los problemas que encontramos al usar el LASSO para la selección de variables son:
- El parámetro de contracción debe ser mayor para la selección que para la predicción
- Los parámetros grandes no nulos serán demasiado pequeños para que el sesgo sea demasiado grande
- Los parámetros pequeños no nulos no se pueden detectar de manera consistente
- Las altas correlaciones entre predictores conducen a un rendimiento deficiente en la selección
Por lo tanto, el LASSO es consistente solo para la selección de variables bajo algunas condiciones en el parámetro de contracción, los parámetros (condición beta-min) y las correlaciones (condición irrepresentable). Consulta las páginas 101-106 de mi tesis de máster para una explicación detallada.
Frecuentemente, el LASSO incluye demasiadas variables al seleccionar el parámetro de ajuste para la predicción, pero el modelo real es muy probable que sea un subconjunto de estas variables. Esto sugiere usar una etapa secundaria de estimación como el LASSO adaptativo que controla el sesgo de la estimación de LASSO utilizando el parámetro de ajuste óptimo para la predicción. Esto lleva a una selección consistente (o propiedad de oráculo) sin las condiciones mencionadas anteriormente.
Puedes usar glmnet para el LASSO adaptativo. Primero necesitas una estimación inicial, ya sea mínimos cuadrados, ridge o incluso las estimaciones de LASSO, para calcular los pesos. Luego puedes implementar el LASSO adaptativo escalando la matriz X. Aquí tienes un ejemplo utilizando estimaciones iniciales de mínimos cuadrados en los datos de entrenamiento:
# obtener datos
y <- train[, 11]
x <- train[, -11]
x <- as.matrix(x)
n <- nrow(x)
# estandarizar datos
ymean <- mean(y)
y <- y-mean(y)
xmean <- colMeans(x)
xnorm <- sqrt(n-1)*apply(x,2,sd)
x <- scale(x, center = xmean, scale = xnorm)
# ajustar ols
lm.fit <- lm(y ~ x)
beta.init <- coef(lm.fit)[-1] # excluir el intercepto 0
# calcular pesos
w <- abs(beta.init)
x2 <- scale(x, center=FALSE, scale=1/w)
# ajustar lasso adaptativo
require(glmnet)
lasso.fit <- cv.glmnet(x2, y, family = "gaussian", alpha = 1, standardize = FALSE, nfolds = 10)
beta <- predict(lasso.fit, x2, type="coefficients", s="lambda.min")[-1]
# calcular estimaciones
beta <- beta * w / xnorm # volver a la escala original
beta <- matrix(beta, nrow=1)
xmean <- matrix(xmean, nrow=10)
b0 <- apply(beta, 1, function(a) ymean - a %*% xmean) # intercepto
coef <- cbind(b0, beta)