Elastic Net, In Full Depth
Ridge Regression adds an L2 penalty and handles correlated features gracefully, but it never sets a weight to exactly zero. Lasso Regression adds an L1 penalty and selects features automatically, but when features are correlated it picks among them almost at random. This page derives the model that adds both penalties: why lasso's choice is unstable, why a little L2 fixes it (with a short proof), the coordinate-descent update that solves it, how to choose its two hyperparameters, and when it's the wrong tool.
Imagine a manager splitting a bonus between team members, and two of them always work as a pair, doing exactly the same work. A manager following Lasso's rule wants to reward as few people as possible, so they give the whole bonus to one of the pair and nothing to the other, and which one wins depends on trivia like who spoke first in a meeting. Ask again next month and the other one might get it all.
A manager following Ridge's rule never gives anyone zero, even people who did nothing. Elastic net is a manager who still gives nothing to people who did nothing, but who splits the pair's bonus evenly because they did the same work. Everything below is that rule made exact: the penalty that produces it, why it works, and how to compute it.
1. The Objective
Elastic net keeps the hypothesis of Linear Regression, , and adds both penalties to the squared-error cost. Written the way scikit-learn and glmnet write it:
where and . The intercept is left out of the penalty (and out of the formula, by centering and each feature first).
There are two hyperparameters:
- sets the overall strength of regularization, as in ridge and lasso.
- sets the mix. is pure lasso, is pure ridge, and anything in between is a blend.
The in front of the error and the on the L2 term are there to make the derivative clean in Section 4; they don't change which is optimal, only the scale at which is measured. One naming trap: scikit-learn calls the overall strength alpha and the mix l1_ratio, so its alpha is this page's and its l1_ratio is this page's . Zou and Hastie, who introduced the method in 2005, used two separate strengths for L1 and for L2; that's the same model with and .
The objective is easy to write down. Why it's worth having two penalties instead of one takes a closer look at what lasso does wrong.
2. What Lasso Does With Correlated Features
Take the extreme case: two features that are exact copies, . The prediction depends only on the sum , since . Say the data wants that sum to be 4. Look at what each penalty charges for different ways of splitting it:
| Split | L1: | L2: |
|---|---|---|
| 4 | 16 | |
| 4 | 10 | |
| 4 | 8 | |
| 4 | 16 |
The L1 penalty is the same for every split with both weights positive. Lasso is indifferent: there are infinitely many optimal solutions, and which one a solver returns depends on details like the order it visits the features. With features that are highly correlated but not identical, the tie is broken by noise in the data, so a different train/test split or a few extra rows can move all the weight from one feature to the other. The selected set of features, often the reason for using lasso in the first place, isn't stable.
Lasso has a second limitation that matters when there are more features than examples (, common in genomics and text): it selects at most nonzero features before it saturates (Efron et al., 2004; Tibshirani, 2013 makes the condition precise). With 100 patients and 20,000 genes, lasso can never pick more than 100 genes, even if 300 matter.
The L2 column shows the fix. Its unique minimum is the even split, . Adding even a small L2 term breaks lasso's tie in favour of sharing, which the next section proves in general.
3. Why the L2 Term Groups Correlated Features
The duplicate case, proved. Suppose , and suppose some optimal solution had with both weights of the same sign. Replace both weights by their average . Then:
- The fit is unchanged, since predictions depend only on .
- The L1 term is unchanged, since when the signs agree.
- The L2 term strictly decreases. Write and with :
So averaging lowers , which contradicts the assumption that the unequal solution was optimal. With any , the optimum gives exact duplicates exactly equal weights. (If the signs disagreed, averaging would lower the L1 term too, so that case can't be optimal either.)
More generally, the L2 term makes strictly convex: the squared error is convex, the L1 term is convex, and is strictly convex whenever . A strictly convex function has exactly one minimizer. Lasso's ambiguity is gone, so the solution no longer depends on solver details or on tiny perturbations of the data.
Near-duplicates. Zou and Hastie proved a quantitative version, called the grouping effect. With standardized features whose correlation is , and both weights of the same sign, the solution satisfies (in their notation, with unscaled squared error)
As , the right side goes to zero and the two weights are forced together. Lasso is the case , where the bound says nothing.
The L1 term still does the selecting: a feature whose correlation with the residual is too weak to overcome still gets a weight of exactly zero, as Section 4 shows. Elastic net selects groups of correlated features together, in or out, rather than one arbitrary representative. The cost of this, covered in Section 6, is a second hyperparameter and some extra shrinkage.
4. Solving It: Coordinate Descent, Step by Step
Elastic net has no closed-form solution (the L1 term has a corner at zero), but it has a very simple coordinate descent algorithm: optimize one weight at a time while holding all the others fixed, and cycle through the weights until nothing changes. It's the same strategy as lasso's solver, and the derivation is worth doing once by hand.
Fix every weight except . Let be the residual from all the other features (here means the -th feature column). As a function of alone, the objective is
Expand the squared norm, keeping only the terms that involve :
is how strongly feature correlates with what the other features haven't explained. is the feature's mean square (exactly 1 for a standardized feature). Collect the quadratic terms:
This is a one-dimensional parabola plus a V-shape. Away from zero, has derivative , so setting the derivative to zero gives:
- If : , so , which is positive only when .
- If : by symmetry, , negative only when .
- If : neither case is consistent, and the minimum sits at the corner, . (At zero, the subgradient of is any value in , which is exactly enough to absorb .)
All three cases are one formula, using the soft-thresholding operator :
Read each penalty's role straight off it. The L1 part sits in the numerator: it subtracts from the feature's correlation and clips at zero, which is what produces exact zeros. The L2 part sits in the denominator: it divides by something larger than , shrinking every surviving weight proportionally, the way ridge does. Set and the update is lasso's; set and it's coordinate descent for ridge.
One update by hand. Take a standardized feature () with , and . Compare what each method does with it:
| Method | Numerator | Denominator | New |
|---|---|---|---|
| No penalty () | |||
| Ridge () | |||
| Lasso () | |||
| Elastic net () |
Now a weaker feature with : ridge gives it , but lasso and elastic net both have thresholds above 0.08 (0.2 and 0.1), so both set it to exactly zero. That's the whole behaviour in two rows: weak features are removed outright, strong ones are kept and shrunk, and elastic net's shrinkage of the strong ones sits between ridge's and lasso's.
Each update can only lower , and since is convex, cycling through the coordinates converges to the global minimum (Tseng, 2001, proved this for objectives of the form "smooth convex function plus a separable non-smooth one"). Friedman, Hastie and Tibshirani's glmnet (2010) made this fast with two tricks: updating the residual incrementally rather than recomputing it, and computing a whole regularization path from large to small, starting each solve from the previous solution (warm starts). The largest useful is the one where every weight is zero: , directly from the threshold condition above.
Drag between the two extremes on the same correlated dataset the ridge and lasso studios use, and watch the regularization path change shape:
5. Choosing λ and α
Both are hyperparameters, so both are chosen by cross-validation on the training data (see ML Workflow Fundamentals). The usual procedure is a small grid over and a full path over for each:
- Standardize the features (inside a pipeline, so validation folds don't leak into the scaling). Both penalties treat all weights alike, so unscaled features are penalized according to their units rather than their importance.
- Pick a handful of mixes, for example . The scikit-learn documentation suggests this kind of grid, weighted towards lasso, because the path changes most as approaches 1.
- For each , compute the path over about 100 values of on a log scale from down to , with warm starts. This costs little more than a single fit.
- Pick the with the best cross-validated error, or use the one-standard-error rule: the largest whose error is within one standard error of the best, which gives a sparser model that is statistically indistinguishable.
ElasticNetCV(l1_ratio=[...], cv=5) does steps 2 to 4 in one call (without the one-standard-error option; glmnet's cv.glmnet reports both lambda.min and lambda.1se).
A rough guide to what the chosen tells you: close to 1 means the data looks like lasso's ideal, a few independent relevant features. A moderate value means relevant features come in correlated groups. Close to 0 means most features carry some signal and sparsity isn't helping, in which case plain ridge is simpler.
6. Ridge vs. Lasso vs. Elastic Net
| Ridge (L2) | Lasso (L1) | Elastic Net (L1 + L2) | |
|---|---|---|---|
| Sets weights to exactly 0? | No | Yes | Yes |
| Correlated features | Shares weight among them | Picks one, unstably | Shares weight, and selects or drops the group together |
| Unique solution? | Yes | Not always | Yes (for ) |
| Max features selected when | All (no selection) | At most | Up to |
| Hyperparameters | , | ||
| Solver | Closed form or iterative | Coordinate descent, LARS | Coordinate descent |
Elastic net is the safest default of the three when you want a sparse model and don't know how correlated the features are, because it degrades gracefully into either neighbour: if the data wants lasso, cross-validation picks near 1. The price is one more hyperparameter to search and, for the same sparsity, slightly more shrinkage of the surviving weights.
7. Minimal Implementation
The coordinate-descent update from Section 4, in NumPy. The residual is updated incrementally, the way glmnet does it, so each update costs instead of :
Output (scikit-learn 1.7):
The twenty-line implementation matches scikit-learn to three decimals. The two near-duplicate features share the weight (1.35 and 1.47, summing to about the true 3 minus shrinkage), two of the four noise features are set to exactly zero, and the other two get small weights of about 0.1, which a larger would remove.
The bootstrap experiment is the point of the page in numbers. Across 200 resamples of the same data, lasso put on average only 17% of the pair's weight on , with a standard deviation of 0.19, and in 32% of resamples dropped one of the two features entirely. Elastic net split the weight almost exactly in half every time (0.48, standard deviation 0.01) and never dropped either. If you were reading the coefficients to decide which measurement matters, lasso's answer would change from one resample to the next; elastic net's wouldn't.
8. When Not to Use Elastic Net
| Situation | Better choice |
|---|---|
| You don't need a sparse model, just stable predictions with correlated features | Ridge: one hyperparameter, closed-form solution |
| Few features, mostly uncorrelated, and you want the simplest sparse model | Lasso; elastic net would choose anyway |
| You need valid p-values or confidence intervals for the selected coefficients | Penalized estimates are biased and post-selection inference is hard; use a pre-registered model, or selective-inference methods |
| You know the group structure in advance (e.g. dummy columns for one categorical variable) | Group lasso, which selects predefined groups explicitly |
| The relationship is nonlinear or has interactions | Tree ensembles (Random Forest, boosting) |
| Millions of rows that don't fit in memory | SGDRegressor(penalty="elasticnet"); see SGD Classifier & Regressor |
Remember
| Idea | In one line |
|---|---|
| Objective | Squared error |
| Two knobs | = how much regularization, = how much of it is L1 |
| Naming | scikit-learn's alpha is ; its l1_ratio is |
| Lasso's flaw | Indifferent between splits of correlated features, so it picks one unstably |
| The fix | L2 makes the objective strictly convex: one solution, equal weights for duplicates |
| Grouping | Correlated features enter or leave the model together |
| Update | : L1 thresholds, L2 shrinks |
| Lasso selects at most features; elastic net has no such ceiling | |
| Tuning | Grid over , path over , standardized features, cross-validation |
Next: Logistic Regression, the same linear machinery and the same penalties adapted for classification. The linear regression family is now complete: Linear Regression, Ridge, Lasso, and Elastic Net.
Sources
- H. Zou and T. Hastie, Regularization and Variable Selection via the Elastic Net, Journal of the Royal Statistical Society B, 2005
- J. Friedman, T. Hastie and R. Tibshirani, Regularization Paths for Generalized Linear Models via Coordinate Descent, Journal of Statistical Software, 2010
- P. Tseng, Convergence of a Block Coordinate Descent Method for Nondifferentiable Minimization, Journal of Optimization Theory and Applications, 2001
- B. Efron, T. Hastie, I. Johnstone and R. Tibshirani, Least Angle Regression, Annals of Statistics, 2004
- R. J. Tibshirani, The Lasso Problem and Uniqueness, Electronic Journal of Statistics, 2013
- T. Hastie, R. Tibshirani and M. Wainwright, Statistical Learning with Sparsity, 2015, Chapters 2 and 4
- scikit-learn, Elastic-Net user guide