I have a question that I've been struggling with. My students are asking me, but I can't figure it out myself.
When I train LASSO regression in R caret, I use the method "glmnet" and a grid with a fixed value of $\alpha=1$ and a range of values for $\lambda$. Here is a minimal example (it seems to be to work the same way in all versions of R that I tried and on different operating systems):
lambda <- 10^seq(-1, 0.6, length = 5)
lambda
lasso <- train(
mpg ~., data = mtcars, method = "glmnet",
trControl = trainControl("cv", number = 10),
tuneGrid = expand.grid(alpha = 1, lambda = lambda),
preProcess = c("scale")
)
lasso
The output looks as follows:
[1] 0.1000000 0.2511886 0.6309573 1.5848932 3.9810717
glmnet
32 samples
10 predictors
Pre-processing: scaled (10)
Resampling: Cross-Validated (10 fold)
Summary of sample sizes: 29, 29, 28, 30, 28, 29, ...
Resampling results across tuning parameters:
lambda RMSE Rsquared MAE
0.1000000 2.623500 0.8248033 2.330232
0.2511886 2.593066 0.8343992 2.285429
0.6309573 2.425283 0.8775376 2.126263
1.5848932 2.637736 0.8920448 2.320468
3.9810717 4.123196 0.8613370 3.685106
Tuning parameter 'alpha' was held constant at a value of 1
RMSE was used to select the optimal model using the smallest value.
The final values used for the model were alpha = 1 and lambda = 0.6309573.
I understand that in order to extract coefficients of the model for different values of $\lambda$, I need to use the function "coef". I do it like this:
coef(lasso$finalModel, lambda)
and I get the intended output:
11 x 5 sparse Matrix of class "dgCMatrix"
1 2 3 4 5
(Intercept) 20.12070307 29.64873768 36.40838250 33.3021609 24.3644781
cyl -0.39267064 -1.09019265 -1.57746798 -1.4822386 -0.4249298
disp . . . . .
hp -0.89172557 -0.94001668 -0.91663301 -0.3768918 .
drat 0.41257152 0.26861963 . . .
wt -2.58105019 -2.54389779 -2.70993457 -2.2109627 -0.8520593
qsec 0.82333186 0.30725294 . . .
vs 0.05920734 0.02024462 . . .
am 1.05461719 0.70458954 0.05087579 . .
gear 0.22456562 . . . .
carb -0.75029547 -0.50103229 -0.01280360 . .
However, here comes something that puzzles me. Suppose that I do not specify the values of $\lambda$ for which I want the coefficients of my model, i.e., run the following command:
coef(lasso$finalModel)
Then R prints a matrix of dimensions $11\times 79$. Here is what it looks like (just first 6 columns):
11 x 79 sparse Matrix of class "dgCMatrix"
[[ suppressing 79 column names ‘s0’, ‘s1’, ‘s2’ ... ]]
(Intercept) 20.09062 21.63712187 23.2405070 24.7015023 26.0327070 27.2462419
cyl . -0.02129088 -0.2585639 -0.4748148 -0.6718548 -0.8520529
disp . . . . . .
hp . . . . . .
drat . . . . . .
wt . -0.44789995 -0.6855245 -0.9019950 -1.0992346 -1.2784335
qsec . . . . . .
vs . . . . . .
am . . . . . .
gear . . . . . .
carb . . . . . .
It looks like there exist some $79$ values of $\lambda$ for which the LASSO model has been trained. And it's true! These values of $\lambda$ can be extracted from the model:
lasso$finalModel$lambda
outputs
[1] 5.146981063 4.689737451 4.273114102 3.893502423 3.547614399 3.232454113
[7] 2.945291799 2.683640194 2.445232995 2.228005236 2.030075391 1.849729089
[13] 1.685404255 1.535677586 1.399252222 1.274946511 1.161683777 1.058482992
[19] 0.964450281 0.878771176 0.800703567 0.729571269 0.664758168 0.605702885
[25] 0.551893910 0.502865176 0.458192020 0.417487504 0.380399064 0.346605460
[31] 0.315813986 0.287757942 0.262194320 0.238901699 0.217678330 0.198340388
[37] 0.180720374 0.164665674 0.150037230 0.136708336 0.124563544 0.113497662
[43] 0.103414843 0.094227753 0.085856819 0.078229536 0.071279840 0.064947535
[49] 0.059177775 0.053920585 0.049130429 0.044765817 0.040788945 0.037165367
[55] 0.033863699 0.030855341 0.028114238 0.025616646 0.023340934 0.021267390
[61] 0.019378053 0.017656561 0.016088000 0.014658787 0.013356541 0.012169982
[67] 0.011088835 0.010103733 0.009206145 0.008388297 0.007643104 0.006964111
[73] 0.006345439 0.005781728 0.005268095 0.004800092 0.004373665 0.003985121
[79] 0.003631093
Here come my two questions:
1)How does my lasso model choose these values of $\lambda$? For instance, why did it decide to vary $\lambda$ but not $\alpha$? And why does it seem to have ignored the values of $\lambda$ but not $\alpha$ that I specified in the "train" function call?
2)How can it compute the coefficients for values of $\lambda$ that are not in this list, e.g, values of $\lambda$ that I specified in the "train" function call?