ML Study Hub

Home / MLP / Week 4

Week 4 · Polynomial regression and regularisation

Official syllabus line: Polynomial regression, Regularized models
About 90 minQuiz 1 material (see exam radar)BSCS2008 · Ashish Tendulkar
Before you start: MLP week 3 (LinearRegression, SGDRegressor). MLT week 5 and week 6 for the ideas behind overfitting and ridge/LASSO.
Watch first: the animated story of this weekAbout 1-2 minutes of real 3D animation with a friendly voice. Pause any time.
Read the words of the video
  1. Imagine a car. The faster it goes, the much longer it takes to stop. A simple straight line might not perfectly show this "curvy" relationship. Our goal is to build models that can bend and capture these real-world patterns, making them smarter than just a simple straight line.
  2. To bend our simple lines, we add "curvy" features like x squared. This helps models fit complex data. But too many curves make the line wiggle wildly, fitting noise too closely. We use a 'leash' called regularisation, like Ridge or Lasso, to tame these wiggles and keep our models simpler.
  3. For example, trying to fit a simple straight line to curvy car data will underfit, performing poorly. A perfectly bent line, like a parabola, works well. But a super wiggly line tries to hit every single noisy dot, leading to huge errors on new, unseen data, which is extreme overfitting.
  4. Remember this key tip for your exams: in models like Ridge, a larger alpha means stronger regularisation. But for Logistic Regression, a smaller C means stronger regularisation! Don't mix them up. So, we learned to bend lines and tame wiggles for better predictions!

The one-minute story

Think of it like this

A straight line is the simplest model. But data is often curvy: the faster a car goes, the much longer it takes to stop. To bend a straight-line model we feed it extra columns like x2x^2 and x3x^3. That is polynomial regression: still the same linear-regression machine, just with more (curved) features.

More curviness is a double-edged sword. With a too-curvy model, the line wiggles through every noisy dot and goes crazy between them. So the second half of the week is the leash: Ridge, Lasso and Elastic Net add a penalty for big weights and tame the wiggles. You will learn which knob makes the leash tighter in each scikit-learn model (and one nasty knob, C, that works backwards).

By the end of this week you can:

  • create polynomial features with PolynomialFeatures and count them;
  • diagnose underfitting and overfitting from train and test error;
  • fit Ridge, Lasso, ElasticNet and say how coefficients behave as alpha grows;
  • pick the regularisation strength with RidgeCV or GridSearchCV;
  • say, for each model, which direction of its knob means more regularisation.

Words you need

Words you need
  • Polynomial features - extra columns made from powers and products of the originals.
  • Interaction term - a product of two different features (x1x2x_1x_2).
  • Underfitting - the model is too simple: poor on both train and test.
  • Overfitting - the model is too flexible: great on train, poor on test.
  • Regularisation - discouraging large weights so the model stays simple.
  • alpha - penalty strength in Ridge, Lasso, ElasticNet, SGD*.
  • Learning curve - error as a function of the amount of training data.

Idea 1: PolynomialFeatures

from sklearn.preprocessing import PolynomialFeatures
PolynomialFeatures(degree=2).fit_transform([[2, 3]])

For the single row (x1,x2)=(2,3)(x_1,x_2)=(2,3) the output is

degree 2 : [1, 2, 3, 4, 6, 9]          -> 1, x1, x2, x1^2, x1*x2, x2^2   (6 columns)
degree 3 : [1, 2, 3, 4, 6, 9, 8, 12, 18, 27]   (10 columns)
degree 2, include_bias=False   : [2, 3, 4, 6, 9]     (drops the column of 1s)
degree 2, interaction_only=True, include_bias=False : [2, 3, 6]   (no pure powers)

How many output columns for nn input features and degree dd (with the bias column)? (n+dd)\binom{n+d}{d}. For n=2,d=2n=2,d=2: (42)=6\binom42=6 ✓. For n=3,d=2n=3,d=2: (52)=10\binom52=\mathbf{10} ✓. The count explodes quickly as nn and dd grow, which is why high degrees overfit and cost a lot.

Rules of thumb:

  • The default is include_bias=True: it adds a column of 1s. LinearRegression already has its own intercept, so use include_bias=False there to avoid redundancy.
  • Scale after expanding: x10x^{10} can be astronomically bigger than xx.
  • Use it inside a pipeline: make_pipeline(PolynomialFeatures(2, include_bias=False), StandardScaler(), LinearRegression()).

Idea 2: Underfitting and overfitting, with numbers

We made 30 noisy points around the curve y=0.5x2+x+2y=0.5x^2+x+2 (the true shape is a parabola), split 70/30, and fitted polynomials of degree 1, 2 and 12:

rng = np.random.RandomState(1)
xs = np.sort(6 * rng.rand(30, 1) - 3, axis=0)
ys = 0.5 * xs[:, 0] ** 2 + xs[:, 0] + 2 + rng.randn(30)
x_tr, x_te, y_tr, y_te = train_test_split(xs, ys, test_size=0.3, random_state=0)

for d in (1, 2, 12):
    m = make_pipeline(PolynomialFeatures(d, include_bias=False),
                      StandardScaler(), LinearRegression()).fit(x_tr, y_tr)
    print(d, mean_squared_error(y_tr, m.predict(x_tr)),
             mean_squared_error(y_te, m.predict(x_te)))
DegreeTrain MSETest MSEDiagnosis
1 (a line)2.143.76underfit: poor on both (high bias)
2 (a parabola)0.620.70just right: low, and train ≈\approx test
120.25240.40overfit: tiny train error, huge test error (high variance)
Think of it like this

Degree 12 has so much freedom it threads through every training dot, noise and all, and then swings wildly between dots. Its test error is more than 300 times the sensible model's.

Reading learning curves. Plot train and validation error against the number of training examples:

  • High bias (underfit): both curves are high and close together; more data will not help, you need a richer model.
  • High variance (overfit): a large gap: train low, validation high; more data, or a simpler/regularised model, helps.
from sklearn.model_selection import learning_curve
sizes, train_scores, val_scores = learning_curve(model, X, y, cv=5,
        scoring="neg_mean_squared_error", train_sizes=np.linspace(0.1, 1, 5))

Idea 3: Ridge, Lasso and Elastic Net

from sklearn.linear_model import Ridge, Lasso, ElasticNet
Ridge(alpha=1.0)                       # default alpha = 1.0
Lasso(alpha=1.0)
ElasticNet(alpha=1.0, l1_ratio=0.5)    # l1_ratio=1 is pure Lasso, 0 is pure Ridge
  • Ridge (ℓ2\ell_2): minimises ∥y−Xw∥2+α∥w∥22\|\mathbf y-X\mathbf w\|^2+\alpha\|\mathbf w\|_2^2. It shrinks all weights smoothly and keeps them non-zero. It has a closed-form solution (XTX+αI)−1XTy(X^TX+\alpha I)^{-1}X^T\mathbf y (we checked: Ridge(alpha=1, fit_intercept=False) matches the formula).
  • Lasso (ℓ1\ell_1): minimises 12n∥y−Xw∥2+α∥w∥1\frac1{2n}\|\mathbf y-X\mathbf w\|^2+\alpha\|\mathbf w\|_1 (note scikit-learn's 12n\frac1{2n} scaling). It can set weights exactly to zero: automatic feature selection.
  • Elastic Net: a mix controlled by l1_ratio.
  • Scale your features first: the penalty treats all weights alike.
  • The intercept is not penalised.

A real run on a synthetic data set (60 samples, 8 features, only 3 informative, standardised):

LinearRegression  [ 65.6  -1.2  92.1  -1.4   1.0  91.6   0.6   2.6]
Ridge alpha=1     [ 64.8  -1.0  90.5  -1.8   0.9  89.9   0.8   2.9]
Ridge alpha=100   [ 27.1   0.8  34.3  -5.9   0.5  33.8   2.3   4.7]
Lasso alpha=1     [ 64.6  -0.6  91.4  -0.4   0.2  90.8   0.0   1.6]    (1 weight is exactly 0)
Lasso alpha=10    [ 56.3  -0.0  82.7  -0.0   0.0  82.3   0.0   0.0]    (5 weights are exactly 0)

The three big weights are the informative features. As alpha rises, ridge shrinks every weight, including the big ones (27 vs 65 at alpha 100), but none hits zero; Lasso keeps the big ones and zeroes the junk (five zeros at alpha 10).

Which knob tightens the leash? (the exam asks: "which model has the lowest overfitting, i.e. the largest regularisation?")

ModelKnobMore regularisation means
Ridge, Lasso, ElasticNetalphalarger alpha
SGDRegressor / SGDClassifieralphalarger alpha
LogisticRegressionC (inverse strength)smaller C
SVC, LinearSVC, SVRCsmaller C
DecisionTree*max_depth, min_samples_leafsmaller depth, larger leaf size
KNeighbors*n_neighborslarger kk
MLP*alpha (L2)larger alpha
Watch out - real exam trap

C works backwards. In LogisticRegression and the SVM classes, C is the inverse of the regularisation strength: small C == strong regularisation, large C == weak. In Ridge/Lasso/SGD*, large alpha == strong regularisation. Do not mix them up.

Idea 4: Choosing alpha

from sklearn.linear_model import RidgeCV
RidgeCV(alphas=[0.01, 0.1, 1, 10, 100], cv=5).fit(X, y)       # picks the best alpha by CV
from sklearn.model_selection import GridSearchCV
GridSearchCV(Ridge(), {"alpha": [0.01, 0.1, 1, 10]}, cv=5).fit(X, y)
GridSearchCV(pipe, {"model__alpha": [0.01, 0.1, 1, 10]}, cv=5)       # inside a pipeline

All three are correct methods to search for the best regularisation parameter; the grid key inside a pipeline needs the step name with a double underscore. There are also LassoCV and ElasticNetCV. Regularisation can also come from early stopping: SGDRegressor(early_stopping=True) holds out validation_fraction=0.1 of the data and stops when the validation score stops improving.

Solved examples

Solved example: 1. How many polynomial features?

Question. Three features, degree 3, with the bias column. How many output columns? And without bias?

Solution. (3+33)=(63)=20\binom{3+3}{3}=\binom63=\mathbf{20} with the bias, so 19\mathbf{19} without (include_bias=False).

Solved example: 2. Which has the least overfitting?

Question. Which model is the most regularised? (a) Ridge(alpha=0.01) (b) Ridge(alpha=100) (c) LogisticRegression(C=100) (d) LogisticRegression(C=0.01).

Solution. Compare within each family. For Ridge, bigger alpha is stronger, so (b) beats (a). For logistic regression, C is inverse, so C=0.01C=0.01 (d) is stronger than C=100C=100 (c). The two strongly regularised settings are (b) and (d); (a) and (c) are the weak ones. (You cannot rank a Ridge alpha against a logistic C by the numbers alone, so an exam option list normally keeps one family at a time.)

Solved example: 3. Reading the coefficients

Question. A Lasso fit gives coef_ = [3.2, 0.0, -1.5, 0.0]. What does it say?

Solution. Features 2 and 4 have been eliminated (their weights are exactly zero), so Lasso judged them unhelpful. Features 1 and 3 matter: feature 1 raises the prediction (+3.2 per unit), feature 3 lowers it (-1.5 per unit). Ridge would never give an exact zero.

Your turn

Your turn: 1. Counting

Two input features, degree 3, include_bias=False. How many columns, and what are they for the row (a,b)(a,b)?

Need a hint?

(2+33)−1\binom{2+3}{3}-1.

Show the full solution

With the bias column there would be (53)=10\binom53=10 columns, so without it there are 9\mathbf9: a,  b,  a2,  ab,  b2,  a3,  a2b,  ab2,  b3a,\;b,\;a^2,\;ab,\;b^2,\;a^3,\;a^2b,\;ab^2,\;b^3.

Your turn: 2. Diagnose

A model has train MSE 1.2 and test MSE 1.4, and a linear model on the same data has train 5.0 and test 5.2. What do you conclude about the linear model, and about the first?

Need a hint?

Compare each model's two errors and the other model's.

Show the full solution

The linear model has high error on both train and test: underfitting (high bias). The first model has low error on both, with a small gap: a good fit.

Your turn: 3. Direction of the knob

For each, say whether to increase or decrease the parameter to reduce overfitting: (a) Ridge(alpha=…) (b) SVC(C=…) (c) LogisticRegression(C=…) (d) DecisionTreeRegressor(max_depth=…) (e) KNeighborsClassifier(n_neighbors=…).

Need a hint?

Use the table.

Show the full solution

(a) increase, (b) decrease, (c) decrease, (d) decrease, (e) increase.

Your turn: 4. Pick the method

Which of these correctly searches for the best alpha of a Ridge model inside pipe = Pipeline([("sc", StandardScaler()), ("model", Ridge())])? (a) GridSearchCV(pipe, {"alpha": [0.1, 1, 10]}, cv=5) (b) GridSearchCV(pipe, {"model__alpha": [0.1, 1, 10]}, cv=5).

Need a hint?

Nested parameter names.

Show the full solution

(b). The step is called model, so the key is model__alpha. (a) would raise an error: the pipeline itself has no parameter named alpha.

Your turn: 5. Lasso or Ridge?

You have 500 features, believe only about 10 matter, and want a model that tells you which. Which regulariser and why?

Need a hint?

Which one zeroes weights?

Show the full solution

Lasso (or Elastic Net): its ℓ1\ell_1 penalty sets many weights exactly to zero, giving a sparse model that highlights the useful features. Ridge keeps all 500 weights non-zero.

Exam radar

Exam radar

In MLP Quiz 1, summaries mention Polynomial Features in 8 papers, Polynomial Transformation in 7, Ridge Regression in 8, Lasso Regression in 8, Regression Algorithms in 5. In Quiz 2, "what is the effect of increasing the regularisation parameter alpha in Ridge Regression?" appears. The End Term includes: "Which of these models has the lowest overfitting (largest regularisation)?" (mixing alpha and C), "which options correctly search for the best regularisation parameter for ridge?", and "which statements about Ridge in scikit-learn are correct?". Also "l1 penalty in LinearSVC leads to coef_ vectors that are sparse."

Watch out - real exam trap
  • C is inverse regularisation (logistic, SVM); alpha is direct (ridge, lasso, SGD).
  • PolynomialFeatures adds a bias column by default; use include_bias=False with LinearRegression.
  • Lasso can zero weights; Ridge cannot.
  • Scale features before regularising.
  • Increasing the polynomial degree always lowers training error, never promising lower test error.

Quick quiz

Quick quiz

For three input features and degree 2 (with the bias column), PolynomialFeatures produces how many columns?

  • 6
  • 9
  • 10
  • 12
C(3+2, 2) = 10.

Which has the strongest regularisation?

  • Ridge(alpha=0.1)
  • LogisticRegression(C=10)
  • Ridge(alpha=50)
  • SVC(C=100)
A large alpha is strong regularisation for Ridge; large C is weak for logistic regression and SVMs.

Increasing alpha in a Ridge model...

  • increases the size of the coefficients
  • shrinks the coefficients and raises bias
  • makes the model more complex
  • has no effect
A larger alpha penalises large weights more, so the coefficients shrink and the model becomes simpler.

Select all TRUE statements. (select all that apply)

  • Lasso can set some coefficients exactly to zero.
  • A degree-12 polynomial on 30 points can overfit badly.
  • Ridge produces sparse coefficient vectors.
  • A smaller C in LogisticRegression means weaker regularisation.
Ridge shrinks but does not zero, and a smaller C means stronger regularisation.

Recap

Remember this
  • PolynomialFeatures(degree): (n+dd)\binom{n+d}{d} columns (with bias); include_bias=False, interaction_only=True. Scale afterwards.
  • Underfit: high error on both; overfit: low train, high test. Learning curves show the gap.
  • Ridge shrinks, Lasso zeroes (and uses 12n\frac1{2n}), ElasticNet mixes (l1_ratio). alpha ↑\uparrow = more regularisation, but C ↓\downarrow = more regularisation.
  • Tune with RidgeCV, GridSearchCV (step__alpha in a pipeline).
Formulas to keep
  • Polynomial feature count: (n+dd)\binom{n+d}{d} (with bias), minus 1 without
  • Ridge: ∥y−Xw∥2+α∥w∥2\|\mathbf y-X\mathbf w\|^2+\alpha\|\mathbf w\|^2; w=(XTX+αI)−1XTy\mathbf w=(X^TX+\alpha I)^{-1}X^T\mathbf y
  • Lasso (sklearn): 12n∥y−Xw∥2+α∥w∥1\frac1{2n}\|\mathbf y-X\mathbf w\|^2+\alpha\|\mathbf w\|_1
  • Defaults: alpha=1.0 (Ridge, Lasso, ElasticNet), l1_ratio=0.5 (ElasticNet)
  • More regularisation: alpha ↑\uparrow; C ↓\downarrow
Connected weeks (learn them together)

Practise with real exam questions

These come straight from past papers (with the real figures and the official answer key). Open 60 real questions on this week   All Quiz 1 papers