Implementing Lasso Regression in Numpy

I'm doing a little self study project, and am trying to implement OLS, Ridge, and Lasso regression from scratch using just Numpy, and am having problems getting this to work with Lasso regression.

To check my results I'm comparing my results with those returned by Scikit-Learn.

The coefficients for OLS can be derived from the following expression: In numpy, this can be implemented in the following way:

np.linalg.inv(X.T @ X) @ (X.T @ y)

If I use the boston housing dataset from scikit learn with this equation my coefficients match what's returned from scikit learn exactly.

The coefficients from Ridge Regression can be represented with the following expression: In numpy this can be represented in the following way:

np.linalg.inv(X.T @ X + alpha * np.identity(X.shape) @ (X.T @ y)

Again, if I plug in the appropriate variables for X, y and alpha, my coefficients match what's output by Scikit Learn's Ridge class.

However, I run into large discrepancies when I try to match the results from its Lasso.

I believe the coefficients for Lasso Regression can be derived in the following way: I haven't seen this coded anywhere on the web, but I assume its implementation would look like this:

np.linalg.inv(X.T @ X) @ (X.T @ y - alpha*np.ones(X.shape))

This returns results, but they do not match what's in scikit learn, and it's not particularly close. If I run a Lasso regression with alpha set to 10 in scikit learn on the boston dataset half of the coefficients are shrunk to zero. Whereas with my implementation they are shrunk only slightly.

What mistake am I making in getting Lasso to work?

Thank you.

• – Demetri Pananos Mar 24 at 3:18
• @DemetriPananos - ie, I'm not getting the same results because Lasso itself requires a level of independence between my variables that I don't have, so the two methods are returning different values? – Jonathan Bechtel Mar 24 at 3:20
• Though I am not confident in the implementation of Lasso in sklearn, it could be the case that sklearn's optimizer is converging to a different a different, yet equivalent optima. I'm about to go grab Hastie's book and see if he writes anything about this. – Demetri Pananos Mar 24 at 3:24
• If you look through the documentation, the class for Lasso regression is inherited from the Elastic Net, so I believe they are implementing it as a special case of that, so maybe if I tried to do it that way I'd get better results. – Jonathan Bechtel Mar 24 at 3:26
• Ahhh. That makes sense now. Unfortunately, the formulas in that answer do not generalize to the multi feature case. I'll write up an answer this evening that explains in more detail. – Matthew Drury Mar 24 at 22:29