The original elastic net paper Zou & Hastie (2005) Regularization and variable selection via the elastic net introduced elastic net loss function for linear regression (here I assume all variables are centered and scaled to unit variance): $$\mathcal L = \frac{1}{n}\big\lVert y - X\beta\big\rVert^2 + \lambda_1\lVert \beta\rVert_1 + \lambda_2 \lVert \beta\rVert^2_2,$$ but called it "naive elastic net". They argued that it performs double shrinkage (lasso and ridge), tends to over-shrink, and can be improved by rescaling the resulting solution as follows: $$\hat\beta^* = (1+\lambda_2)\hat\beta.$$ They gave some theoretical arguments and experimental evidence that this leads to better performance.
However, the subsequent glmnet
paper Friedman, Hastie, & Tibshirani (2010) Regularization paths for generalized linear models via coordinate descent did not use this rescaling and only had a brief footnote saying
Zou and Hastie (2005) called this penalty the naive elastic net, and preferred a rescaled version which they called elastic net. We drop this distinction here.
No further explanation is given there (or in any of the Hastie et al. textbooks). I find it somewhat puzzling. Did the authors leave the rescaling out because they considered it too ad hoc? because it performed worse in some further experiments? because it was not clear how to generalize it to the GLM case? I have no idea. But in any case the glmnet
package became very popular since then and so my impression is that nowadays nobody is using the rescaling from Zou & Hastie, and most people are probably not even aware about this possibility.
Question: after all, was this rescaling a good idea or a bad idea?
With glmnet
parametrization, Zou & Hastie rescaling should be $$\hat\beta^* = \big(1+\lambda(1-\alpha)\big)\hat\beta.$$
glmnet
code. It's not available there even as an optional feature (their earlier code that accompanied the 2005 paper does of course support rescaling). $\endgroup$inst/mortran/glmnet5dpclean.m
), which is translated by the mortran processor to fortran 77 (src/glmnet5dpclean.f
), which is indeed unreadable. However, if you want to do some debugging and don't have a working mortran preprocessor, you can read the mortran code, identify the corresponding part in the f77 code, and place your debug output there. It's a bit painful, but it's doable... $\endgroup$