Quiz 2

Regularization & Overfitting

1854 words
9 min read
Python Week 1: the first filter for runtime behavior
Visual companion
Python
Type and operator map

Python Week 1: the first filter for runtime behavior

View
Revision summary

What this note is really saying

Short form

# Regularization & Overfitting ## 🎯 Learning Objectives - Explain how regularization prevents overfitting and when to use each type - Implement Ridge (L2), Lasso (L1), and Elastic Net regression - Use cross-validation to find optimal regularization strength - Build a complete ML pipeline in sklearn including prepro...

Regularization & Overfitting

🎯 Learning Objectives

  • Explain how regularization prevents overfitting and when to use each type
  • Implement Ridge (L2), Lasso (L1), and Elastic Net regression
  • Use cross-validation to find optimal regularization strength
  • Build a complete ML pipeline in sklearn including preprocessing and modeling
  • Diagnose and fix overfitting systematically

📋 Prerequisites

  • Linear & Logistic Regression — the models we regularize
  • Model Evaluation — cross-validation, bias-variance tradeoff
  • Feature Scaling — critical for regularized models

📖 Core Content

12.1 Intuition: Keeping the Model Humble

Imagine a student who memorizes every answer in the textbook versus one who learns the underlying principles. The memorizer gets perfect scores on homework (just like the textbook) but fails the final exam (unseen problems). The principles-learner gets good, not perfect, on homework but passes the final exam. Regularization is the technique that prevents memorization. It adds a penalty for complexity — large coefficients are made smaller, forcing the model to rely on all features modestly rather than a few features strongly. (Diagram)

12.2 Ridge Regression (L2 Regularization)

Adds the sum of squared coefficients as a penalty:
J(θ)=MSE(θ)+αj=1nθj2J(\theta) = MSE(\theta) + \alpha \sum_{j=1}^{n} \theta_j^2
Where α\alpha controls the regularization strength:
  • α=0\alpha = 0: Standard linear regression (no regularization)
  • α\alpha \to \infty: All coefficients approach 0 (underfitting) Properties:
  • Shrinks coefficients toward 0 (but never exactly 0)
  • Handles multicollinearity well (distributes importance among correlated features)
  • Has a closed-form solution: θ=(XTX+αI)1XTy\theta = (X^T X + \alpha I)^{-1} X^T y
python
# runnable
from sklearn.linear_model import Ridge
from sklearn.datasets import load_diabetes
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
import numpy as np
diabetes = load_diabetes()
X, y = diabetes.data, diabetes.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# Ridge with different alphas
for alpha in [0, 0.1, 1, 10, 100]:
    ridge = Ridge(alpha=alpha)
    ridge.fit(X_train, y_train)
    train_score = ridge.score(X_train, y_train)
    test_score = ridge.score(X_test, y_test)
    print(f"α={alpha:5.1f}: Train R²={train_score:.3f}, Test R²={test_score:.3f}")

12.3 Lasso Regression (L1 Regularization)

Adds the sum of absolute coefficients as a penalty:
J(θ)=MSE(θ)+αj=1nθjJ(\theta) = MSE(\theta) + \alpha \sum_{j=1}^{n} |\theta_j|
Properties:
  • Forces some coefficients to exactly 0 (feature selection!)
  • Produces sparse models (fewer features used)
  • Good when you believe only a few features matter
python
# runnable
from sklearn.linear_model import Lasso
from sklearn.datasets import load_diabetes
lasso = Lasso(alpha=0.1)
lasso.fit(X_train, y_train)
print(f"Features used: {np.sum(lasso.coef_ != 0)} / {len(lasso.coef_)}")
print(f"Coefficients: {lasso.coef_}")
print(f"Test R²: {lasso.score(X_test, y_test):.3f}")

12.4 Worked Example 1: Ridge vs Lasso by Hand

Simple dataset: y = 2 + 3x₁ + 0.5x₂ + noise, but x₁ and x₂ are correlated. Without regularization (α=0): θ=[2.0,3.2,0.3]\theta = [2.0, 3.2, 0.3] — similar to true coefficients. Ridge (α=1): θ=[1.9,2.8,0.4]\theta = [1.9, 2.8, 0.4] — both coefficients shrunk toward 0 but neither reaches 0. Lasso (α=0.5): θ=[1.8,3.0,0.0]\theta = [1.8, 3.0, 0.0] — x₂'s coefficient is exactly 0! Lasso selected only x₁. This illustrates Lasso's feature selection property.

12.5 Elastic Net: Best of Both Worlds

Combines L1 and L2 penalties:
J(θ)=MSE(θ)+rαθj+1r2αθj2J(\theta) = MSE(\theta) + r\alpha \sum |\theta_j| + \frac{1-r}{2}\alpha \sum \theta_j^2
Where rr (l1_ratio) controls the mix:
  • r=1r = 1: Pure Lasso
  • r=0r = 0: Pure Ridge
  • r=0.5r = 0.5: Equal mixture Elastic Net is preferred when:
  • You have more features than samples (p > n)
  • Features are grouped (Lasso picks one, Ridge picks all, Elastic Net picks groups)
  • You want Ridge's stability + Lasso's sparsity
python
# runnable
from sklearn.linear_model import ElasticNet
from sklearn.model_selection import GridSearchCV
elastic = ElasticNet()
param_grid = {
    'alpha': [0.001, 0.01, 0.1, 1, 10],
    'l1_ratio': [0.1, 0.3, 0.5, 0.7, 0.9]
}
grid = GridSearchCV(elastic, param_grid, cv=5, scoring='r2')
grid.fit(X_train, y_train)
print(f"Best params: {grid.best_params_}")
print(f"Best CV R²: {grid.best_score_:.3f}")

12.6 Comparing Regularization Methods

AspectRidge (L2)Lasso (L1)Elastic Net
Penaltyθj2\sum \theta_j^2$\sum\theta_j
Coefficient behaviorShrinks toward 0Shrinks to exactly 0Mix
Feature selectionNoYesYes (grouped)
MulticollinearityHandles wellUnstable (chooses arbitrarily)Groups correlated features
Closed-form solutionYesNo (iterative)No
Best forMany equally important featuresSparse featuresGrouped correlated features

12.7 Early Stopping (Gradient Descent Regularization)

For iterative algorithms (gradient descent, neural networks), stopping before convergence acts as regularization:
python
# runnable
from sklearn.linear_model import SGDRegressor
from sklearn.datasets import load_diabetes
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import make_pipeline
X, y = load_diabetes(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# Without early stopping
sgd = SGDRegressor(max_iter=1000, tol=1e-3, random_state=42, penalty=None)
sgd.fit(X_train, y_train)
print(f"No regularization: Test R² = {sgd.score(X_test, y_test):.3f}")
# With early stopping (fewer iterations = simpler model)
sgd_early = SGDRegressor(max_iter=10, tol=None, random_state=42, penalty=None)
sgd_early.fit(X_train, y_train)
print(f"Early stopping (iter=10): Test R² = {sgd_early.score(X_test, y_test):.3f}")

12.8 The ML Pipeline

A pipeline chains preprocessing steps with a final estimator:
python
# runnable
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler, PolynomialFeatures
from sklearn.linear_model import Ridge
from sklearn.model_selection import cross_val_score
import numpy as np
# Build pipeline
pipeline = Pipeline([
    ('scaler', StandardScaler()),
    ('poly', PolynomialFeatures(degree=2, include_bias=False)),
    ('ridge', Ridge(alpha=1.0))
])
# Use as a single estimator
scores = cross_val_score(pipeline, X_train, y_train, cv=5, scoring='r2')
print(f"Pipeline CV R²: {scores.mean():.3f} ± {scores.std():.3f}")
# Grid search over pipeline params
from sklearn.model_selection import GridSearchCV
param_grid = {
    'poly__degree': [1, 2, 3],
    'ridge__alpha': [0.01, 0.1, 1, 10]
}
grid = GridSearchCV(pipeline, param_grid, cv=5)
grid.fit(X_train, y_train)
print(f"Best pipeline: {grid.best_params_}")
print(f"Test R²: {grid.score(X_test, y_test):.3f}")

12.9 When to Use / Not Use

When to UseWhen NOT to Use
Many features (n > samples)Already have a simple model that generalizes
Multicollinearity presentNeed all features in model (use Ridge)
Feature selection needed (Lasso)Features are equally important (use Ridge)
Overfitting observedModel is already underfitting
Need sparse model for productionExtreme large scale (use SGD-based)

📐 Key Formulas / Concepts

ConceptFormulaNotes
Ridge costMSE+αθj2MSE + \alpha \sum \theta_j^2Shrinks all coefficients
Ridge solutionθ=(XTX+αI)1XTy\theta = (X^T X + \alpha I)^{-1} X^T yClosed form
Lasso cost$MSE + \alpha \sum\theta_j
Elastic NetMSE+rαL1+(1r)αL2MSE + r\alpha L_1 + (1-r)\alpha L_2Mix of both
PipelineSequential transform + estimatorsklearn Pipeline class

⚠️ Common Pitfalls

Pitfall 1: Not Scaling Before Regularization

The mistake: Applying Ridge/Lasso without standardizing features. Why: The penalty term sums coefficients. If a feature has a large range, its coefficient is naturally smaller — it gets penalized less unfairly. Fix: Always standardize features (mean=0, std=1) before regularization.

Pitfall 2: Choosing α Too Large

The mistake: Setting α=100 "to be safe" from overfitting. Why: The model shrinks all coefficients too much, causing underfitting. Fix: Search α across a logarithmic scale [0.001, 0.01, 0.1, 1, 10, 100] using cross-validation.

Pitfall 3: Lasso with Highly Correlated Features

The mistake: Using Lasso when features are grouped (e.g., one-hot encoded categories). Why: Lasso arbitrarily picks one feature from a correlated group, ignoring the others. This loses information. Fix: Use Elastic Net (l1_ratio around 0.5) which groups correlated features together.

📝 Practice Questions

Q1: Ridge shrinks coefficients toward 0. Why would we want to do this?
Large coefficients mean the model relies heavily on individual features. If those features change slightly (noise), predictions change dramatically. Shrinking coefficients makes the model more robust — each feature contributes modestly, reducing variance. This is the classic bias-variance tradeoff: we accept a small bias increase for a large variance decrease. Q2: With α=0, Ridge is equivalent to what?
Standard Linear Regression (OLS). No regularization is applied. The coefficients minimize only the MSE. Q3: Lasso gives coefficients [0, 2.5, 0, 0.3, 0, 0]. What does this tell you?
Only 2 features out of 6 are used (features 1 and 3 with values 2.5 and 0.3). Lasso performed feature selection — the other 4 features had coefficients shrunk to exactly 0. This model is sparse and likely simpler to deploy. Q4: Why does Lasso produce zero coefficients but Ridge doesn't?
The L1 penalty's derivative is constant (±α), so the optimization pushes coefficients all the way to 0 when they're small. The L2 penalty's derivative is 2αθ, which approaches 0 as θ approaches 0 — so Ridge keeps shrinking but never fully zeros out.
Geometrically: Lasso's constraint region is a diamond (with corners at axis intersections), Ridge's is a circle (no corners). Q5: You have 10 features, 50 samples, and high multicollinearity. Which regularization?
Ridge — it handles multicollinearity well (distributes coefficients among correlated features) and works with p < n (10 < 50). Elastic Net would also work. Lasso would be unstable with correlated features. Q6: Implement a pipeline with StandardScaler, PolynomialFeatures, and Ridge.
python
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler, PolynomialFeatures
from sklearn.linear_model import Ridge

pipeline = Pipeline([
    ('scaler', StandardScaler()),
    ('poly', PolynomialFeatures(degree=2)),
    ('model', Ridge(alpha=1.0))
])
pipeline.fit(X_train, y_train)
The pipeline ensures that:
  1. Scaling is fit on training data and applied consistently
  2. Polynomial features are created after scaling
  3. Ridge regression is the final estimator Q7: What is the information-theoretic justification for regularization?
Occam's razor: simpler models are preferred. Regularization penalizes model complexity (large coefficients = complex model). This connects to:
  • VC-dimension: Regularized models have lower effective VC-dimension
  • Bayesian prior: L2 regularization = Gaussian prior on weights, L1 = Laplace prior
  • Minimum Description Length: Regularization prefers models that compress the data better Q8: With 100 features but only 2 are truly relevant, which regularizer?
Lasso (L1) — it will drive the 98 irrelevant feature coefficients to 0. Ridge would keep them small but non-zero, making the model harder to interpret. Lasso naturally performs feature selection for sparse solutions. Q9: In Elastic Net, what does l1_ratio=0.3 mean?
30% L1 penalty + 70% L2 penalty. The model is closer to Ridge than Lasso. It will shrink coefficients (L2) but also push some to zero (L1), handling correlated features better than pure Lasso. Q10: How do you choose α in Ridge regression?
Use cross-validation with RidgeCV or GridSearchCV:
python
from sklearn.linear_model import RidgeCV
ridge_cv = RidgeCV(alphas=[0.001, 0.01, 0.1, 1, 10, 100], cv=5)
ridge_cv.fit(X_train, y_train)
print(f"Best α: {ridge_cv.alpha_}")
The optimal α balances bias and variance for your specific dataset. Q11: Why is scaling important for L1 regularization?
The L1 penalty sums |θⱼ|. If feature A has values [0.1, 0.2] and feature B has [100, 200], feature B's coefficient will be ~1000× smaller to have the same effect. With L1, a small coefficient for B gets zeroed out easily, while A's larger coefficient survives. This biases the model against features with small scales. Q12: What happens if you apply Lasso to one-hot encoded categorical features?
One-hot encoding creates perfectly correlated dummy variables (sum to 1). Lasso will arbitrarily pick one category and zero out the rest, losing information. Solution: use Elastic Net (which groups correlated features) or drop one category before Lasso.

🔗 Cross-References

Document outline

Keep your place and jump directly to a heading.

Table of Contents
System Normal // Awaiting Context

Intelligence Hub

Navigate the knowledge graph to generate context. The Hub adapts dynamically to surface backlinks, related notes, and metadata insights.