Regularized linear regression — Ridge (L2) and Lasso (L1). Drag one slider and watch a wiggly, over-fitted curve relax into a clean, general model. The maths runs live in your browser.
Find weights w that make predictions close to reality — minimise the squared error:
With enough flexibility, this chases every wiggle in the training data — including the noise.
Add a "keep the weights small" term. λ (alpha) sets how strict you are:
λ = 0 → ordinary regression. λ → ∞ → weights crushed to ~0 (a flat line).
A degree-9 polynomial is fit to noisy points with a real Ridge solver running live. Slide λ from left (no penalty) to right (strong penalty) and watch the purple curve go from over-fitted & wiggly → smooth & general → too flat. Green dots are training data, red rings are unseen test points.
Both shrink coefficients as λ grows — but Lasso can hit exactly zero, dropping a feature entirely (automatic feature selection). Ridge only gets close to zero. Slide λ and watch the bars. (Shown for the clean orthonormal case, where the formulas are exact.)
Three short, beginner-friendly explainers from StatQuest with Josh Starmer — widely used in classrooms. Watch in order for a complete picture.
Videos are embedded from YouTube and belong to their creators. If a frame is blank, your network may block YouTube — open the titles on youtube.com directly.
Implemented with scikit-learn. Swap in any dataset CSV (here a built-in one is used so it runs anywhere).
import numpy as np
import pandas as pd
from sklearn.datasets import load_diabetes
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
X, y = load_diabetes(return_X_y=True) # or pd.read_csv("data.csv")
X_tr, X_te, y_tr, y_te = train_test_split(X, y, test_size=0.2, random_state=1)
# Always scale features before regularizing!
sc = StandardScaler().fit(X_tr)
X_tr, X_te = sc.transform(X_tr), sc.transform(X_te)
from sklearn.linear_model import LinearRegression, Ridge, Lasso
from sklearn.metrics import mean_squared_error, r2_score
models = {
"OLS": LinearRegression(),
"Ridge": Ridge(alpha=1.0), # L2 penalty
"Lasso": Lasso(alpha=0.1), # L1 penalty
}
for name, m in models.items():
m.fit(X_tr, y_tr)
pred = m.predict(X_te)
print(name, "MSE:", round(mean_squared_error(y_te, pred),1),
"R2:", round(r2_score(y_te, pred),3))
print(" non-zero coefs:", np.sum(m.coef_ != 0))
# Pick the best alpha automatically with cross-validation
from sklearn.linear_model import RidgeCV, LassoCV
ridge_cv = RidgeCV(alphas=np.logspace(-3, 3, 50)).fit(X_tr, y_tr)
lasso_cv = LassoCV(cv=5).fit(X_tr, y_tr)
print("best Ridge alpha:", ridge_cv.alpha_)
print("best Lasso alpha:", lasso_cv.alpha_)
import matplotlib.pyplot as plt
# See how coefficients shrink as alpha grows
alphas = np.logspace(-2, 3, 30)
coefs = [Ridge(alpha=a).fit(X_tr, y_tr).coef_ for a in alphas]
plt.plot(alphas, coefs)
plt.xscale("log"); plt.xlabel("alpha (λ)"); plt.ylabel("coefficient")
plt.title("Ridge coefficient shrinkage"); plt.show()
Regularized linear regression was implemented using scikit-learn. Ridge and Lasso reduced overfitting compared with plain OLS, giving lower test error at a suitable α. Lasso additionally set several coefficients to exactly zero, performing automatic feature selection. This demonstrates CO3.
RidgeCV / LassoCV try a range of α values and select the one with the lowest validation error.