Concepts / Visualizing Cross-Validation Results with Heat Maps

Visualizing Cross-Validation Results with Heat Maps

The mean cross-validation score for each candidate is taken from the search results and reshaped into a table with three rows and as many columns as needed.

  • Programming
Interactive lab

Try it: K-Fold Cross-Validation and Model Selection

How hold-out and k-fold cross-validation choose among candidate models: each fold takes a turn as the validation set, the fold errors are averaged, the lowest average picks the model, and only then is the untouched test set used once — while tuning on the test set would report an optimistic number.

How it works

  1. Set 10 test points aside; they take no part in any choice.
  2. Optionally shuffle the 20 development points (seeded), then cut them into k folds (hold-out: one chunk validates, the rest trains).
  3. For every round, train each candidate polynomial on the other folds and measure its validation MSE on the held-out fold.
  4. Average each candidate's fold errors (with repeated shuffling: average the p run scores; p × k fits per candidate).
  5. Select the candidate with the lowest average, retrain it on all development points, and evaluate it once on the test set.
  6. For contrast, show which candidate the test set itself would have picked — that figure is leaked and optimistic.

Default run (12 steps): 20 development points (sorted by x as they arrived) and 10 test points set aside. Candidates: polynomial degree 0, 1, 2, 3, 4, 5, 6. Plan: 5-fold cross-validation, shuffled with seed 1 → 5 fits per candidate (p × k = 1 × 5), 35 in total. … 5-fold cross-validation picks degree 3 (score 0.0768); its honest test MSE is 0.0889. Picking by test error would report degree 4 at 0.0868 — a leaked, optimistic figure.

Simplified: One fixed toy dataset (20 development + 10 test points from sin(2πx) with noise) and polynomial least squares of degree 0–6 as the candidate models. Shuffling uses a seeded mulberry32 Fisher–Yates; folds are contiguous chunks like scikit-learn's KFold. Hold-out uses the first of k chunks as the validation set.

Educational simulation

Loading the simulation…

Deciding How Much Feature Engineering to Apply

A recurring question in model building is how much feature engineering to apply. If you add polynomial features, which degree should you choose? Should you add polynomial features at all? The most reliable answer is to let the outcome decide. Try several candidate settings, measure each one with cross-validation, and keep the setting that scores best. This article shows how a single grid search can make that comparison for two settings at once, one from the preprocessing stage and one from the model.

The code that drives this comparison assumes a pipeline called pipe, built earlier, and a training split made of X_train and y_train. Keep two things in view as you read: the keys in param_grid, and what the fit call receives. Each of them is explained in the sections that follow.

Reading the Prefixed Keys in param_grid

A pipeline contains several named steps, and each step may have parameters of its own. A grid search needs an unambiguous way to say which step a parameter belongs to. The convention used here is to write the lowercase step name, then two underscore characters, then the parameter name. The key polynomialfeatures__degree therefore means the degree parameter of the step named polynomialfeatures, and ridge__alpha means the alpha parameter of the step named ridge. The prefix is what routes each candidate value to the correct step.

polynomialfeaturespipeline step name__two underscores separatestep from parameterdegreeparameter name
In the key polynomialfeatures__degree, which part names the pipeline step, which part names the parameter, and which object receives the value?

Read the key from left to right. The part before the double underscore identifies the step. The part after it identifies the parameter inside that step. The value in the list is then given to that parameter. The same rule gives ridge__alpha: the step named ridge receives the candidate alpha values.

python
Notes on the code
  • The key polynomialfeatures__degree routes its values to the degree parameter of the polynomialfeatures step.
  • The key ridge__alpha routes its values to the alpha parameter of the ridge step.
  • The alpha values shown here are illustrative; the source does not list the specific values it used.

Counting Candidates and Model Fits

Each candidate in the grid is a full combination of values, one value for each key. The number of candidates is therefore the product of the number of values for each key. This is the rule that tells you how large a search will be before you run it.

Worked example

Counting candidates in a two-key grid

A grid has 4 degree values and 5 alpha values, and the search uses 5-fold cross-validation. How many candidates are evaluated, and how many model fits does that imply?

  1. 1
    Count the candidates

    Each candidate pairs one degree with one alpha, so the number of candidates is $4 \times 5 = 20$.

  2. 2
    Count the fits per candidate

    Cross-validation with 5 folds fits the model once per fold, so each candidate is fitted 5 times.

  3. 3
    Count the total fits

    Multiply the candidates by the folds: $20 \times 5 = 100$ model fits.

Result

The grid evaluates 20 candidates, which implies 100 model fits.

The same arithmetic applies to the grid in this chapter. Three degrees and six alpha values give $3 \times 6 = 18$ candidates, which matches the eighteen candidate scores the visualization reads.

What do you think happens?

If the degree list has 4 values and the alpha list has 5 values, and cross-validation uses 5 folds, how many model fits does the grid search perform?

Reveal answer
Answer:

100 model fits: 4 times 5 gives 20 candidates, and 20 candidates times 5 folds gives 100 fits.

Multiplying the number of values for each key gives the candidates, and each candidate is fitted once per fold.

Why One Grid Covers Both Stages

The search does not tune the model in isolation. Because the polynomial degree and the Ridge alpha both appear in one param_grid, each candidate is a complete choice: a degree paired with an alpha. For every pair, the pipeline builds polynomial features at that degree, fits Ridge at that alpha, and scores the result by cross-validation.

X_traintraining featuresPolynomialFeaturesdegree from the gridRidgealpha from the gridCross-validated scoreone candidate's resulttransformtransformed datascore
When the grid changes polynomial degree, which steps re-run on each fold, and how does the transformed data reach the Ridge model?

The best pair is therefore chosen with both stages taken into account at once. The preprocessing choice of degree is judged by how well the Ridge model performs on the features it produces, and the alpha is judged on the same transformed features. This is why the source treats preprocessing and model parameters as tunable together. Neither value is picked in advance; both are compared on the measured outcome.

Reshaping Scores into a Heat Map

Eighteen candidate scores are too many to read as a list, so the results are arranged as a grid. The mean cross-validation score for each candidate is taken from the search results and reshaped into a table with three rows and as many columns as needed. Since there are three degrees, the three rows correspond to degrees 1, 2, and 3. The six alpha values then form the columns. Each cell is colored by its score, which makes it possible to see at a glance where the good settings cluster.

The mean for each candidate is the average of that candidate's cross-validation scores. Cross-validation scores the model on several held-out portions of the training data, and the mean summarizes those scores as one number per candidate. The heat map therefore shows one value per degree-alpha pair, not one value per fold.

The axis labels in the plotting code name the two parameters, so the reader does not have to guess which dimension is which. Without labels, a heat map with three rows and six columns looks the same whether it is read by degree or by alpha.

Reading the Degree-by-Alpha Pattern

Once the heat map is drawn, the cross-validation results can be read directly. Using polynomials of degree two improves the score compared with the alternatives. Degree-three polynomials perform much worse than either degree one or degree two. The best parameters found by the search are reported from the same results, and they reflect this pattern.

To read a heat map, start by locating the best cell, which is the one with the most favorable score. Its row tells you the degree and its column tells you the alpha. Then move along each axis: across a row, you see how alpha changes the score at a fixed degree; down a column, you see how degree changes the score at a fixed alpha.

The decision about the degree therefore comes from the measured outcome rather than from a guess made before the search. The heat map is the evidence for that decision, and it applies only to the values that were included in the grid.

Degree 1better than degree 3Degree 2improves the scoreDegree 3much worse than 1 or 2
Which degree row holds the best mean score, and how does performance change across the three degree rows?

Mistakes Readers Make with the Heat Map

  • Common mistake

    Treating the heat map's best cell as the best model in general

    Why it fails

    The conclusions apply only to the values included in the grid. A degree that was never tested cannot be ranked by this search.

    Do this instead

    Describe the result as the best of the tested candidates, and widen the grid if the best value sits at an edge.

  • Common mistake

    Assuming the number of candidates equals the number of keys

    Why it fails

    Each candidate is a full combination, so the count is the product of the number of values for each key, not their sum.

    Do this instead

    Multiply the value counts: 3 degrees and 6 alphas give 18 candidates, not 9.

  • Common mistake

    Reading a key without its prefix as a step-specific setting

    Why it fails

    A bare name such as degree does not say which step it belongs to. The prefix is what routes the value to the correct step.

    Do this instead

    Read polynomialfeatures__degree as the degree of the polynomialfeatures step, and ridge__alpha as the alpha of the ridge step.

  • Common mistake

    Reading the heat map with rows and columns swapped

    Why it fails

    The reshape follows the order of the candidates, and the labels must match that order.

    Do this instead

    Check that each block of six consecutive scores becomes one row, and that the axis labels name degree for rows and alpha for columns.

Practice: Predict Before You Read the Grid

MEDIUM

A param_grid has the key polynomialfeatures__degree with the values 1, 2, 3, 4 and the key ridge__alpha with five values. Before running anything, state how many candidates the grid evaluates and how many model fits 5-fold cross-validation implies. Then explain which step receives each value.

Hints
  • Multiply the number of values for each key to get the candidates.
  • Each candidate is fitted once per cross-validation fold.
  • The prefix before the double underscore names the step that receives the value.

Key Takeaways

  • A param_grid key uses the step name, two underscores, and the parameter name, so each candidate value reaches the intended step.
  • Each candidate is a full combination of values, so the number of candidates is the product of the number of values for each key, and each candidate is fitted once per cross-validation fold.
  • Because preprocessing and model parameters share one pipeline and one param_grid, a single grid search chooses a degree and an alpha together using measured cross-validation scores.
  • A heat map of mean scores laid out by degree and alpha shows where good settings cluster, but its conclusions apply only to the values included in the grid.

Related concepts

More concepts starting with V