Concepts / Cross-Validation Fundamentals

Cross-Validation Fundamentals

GridSearchCV uses stratified k-fold cross-validation by default for classification and k-fold cross-validation for regression.

  • 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…

Why Tuning Multiplies the Work

When you tune a model with GridSearchCV, every candidate combination of parameters has to be evaluated on several different train-and-validate partitions of the data. That repeated evaluation is what makes the search trustworthy, but it also multiplies the amount of work. A grid with many candidates, run on a large dataset or with a model that takes a long time to train, can become expensive quickly.

This article looks at the cv parameter, which controls how those partitions are created, and at the option of replacing many partitions with one carefully chosen split. Before reading on, try to answer the question below from memory.

What do you think happens?

If you call GridSearchCV on a classification problem without setting cv, which partitioning strategy do you think it uses?

  • Plain k-fold

  • Stratified k-fold

  • A single random split

  • Leave-one-out

Reveal answer
Answer:

Stratified k-fold

GridSearchCV uses stratified k-fold by default for classification, which divides the data into k parts while keeping the class proportions roughly the same in each part. For regression it uses plain k-fold instead.

Tracing the Rotation of Folds

With k-fold cross-validation, the data is divided into k parts, usually called folds. In each iteration one fold is held out as the validation set and the remaining folds are used for training. Each candidate parameter set is therefore trained and checked several times, once for every fold taking its turn as the validation set.

Iteration 1Fold 1 validates, Folds 2-4trainIteration 2Fold 2 validates, Folds 1,3, 4 trainIteration 3Fold 3 validates, Folds 1,2, 4 trainIteration 4Fold 4 validates, Folds 1-3trainnext foldnext foldnext fold
In each iteration, which fold is held out for validation and which folds are used for training, and how does this change across iterations?

Notice that the number of trainings grows with k. A candidate evaluated with 4-fold cross-validation is trained four times, and a grid of 12 candidates therefore requires 48 training runs. This is the cost that a single split later tries to reduce.

Defaults by Estimator Type

You do not have to specify anything to get cross-validation inside GridSearchCV. The defaults follow the same logic as the cross_val_score function. The choice depends on the kind of problem the estimator solves. A classifier predicts categories, so GridSearchCV uses stratified k-fold, which keeps the class proportions roughly the same in each part. A regressor predicts continuous values, so GridSearchCV uses plain k-fold instead. Stratification is a classification concern because class labels are what needs to be balanced across the parts.

ClassifierPredicts categoriesStratified k-foldKeeps class proportions perfoldRegressorPredicts continuous valuesk-foldPlain partitioning into kpartsdefaultdefault
Which default splitter does GridSearchCV apply when the estimator is a classifier versus a regressor?

Passing a Splitter Through cv

The cv argument accepts more than a number of folds. You can pass any cross-validation splitter object, which is a tool that knows how to generate train and validation index sets from the data. Once you hand a splitter to GridSearchCV through cv, the search uses that splitter's logic in place of the default. An integer asks for that many folds using the default strategy for the estimator type, while a splitter object supplies the exact partitioning logic you want.

python
Notes on the code
  • cv=5 requests five folds using the default strategy for the estimator type
  • cv=one_split passes a splitter object whose logic replaces the default
  • n_splits=1 is the single-split setting; older releases call this n_iter=1

One Split Instead of Many

Ordinary cross-validation gives you several partitions, so each candidate parameter set is trained and checked several times. A different option is to ask for only a single split into one training set and one validation set. You get this by using ShuffleSplit or StratifiedShuffleSplit with n_iter=1. In recent releases the same setting is named n_splits. ShuffleSplit produces random train and validation partitions.

Split 1Random train and validationrowsSingle splitOne train and onevalidation setTraining portionEach candidate is fit hereSplit 2Different random rowsValidation portionEach candidate is scoredhereSplit 3Different random rows againtraining rowsvalidation rows
What does the data look like after a single ShuffleSplit with n_iter=1 compared with repeated random splits, and which rows end up in training versus validation?

Before working through the numbers, consider the flow of data. The full dataset is divided once. Each candidate parameter set is then trained on the training portion and scored on the validation portion. Because there is only one partition, no candidate is judged on a second or third validation set.

When One Split Is a Sensible Trade-off

The source gives a specific motivation for the single-split option: it might be helpful for very large datasets, or for very slow models. In both cases the cost of repeating training across many folds can dominate the total time. A single split keeps the search affordable while still giving each candidate a fair held-out evaluation.

Consider a grid of 12 candidates with a model that takes hours to train on the full dataset. With 5-fold cross-validation, the search would require 60 training runs. A single split reduces that to 12 training runs. The saving is real, but the score for each candidate now rests on one validation portion, so it is less stable than an average over several folds.

Mistakes With the cv Parameter

  • Common mistake

    Assuming cv always changes the strategy

    What it looks like

    Writing cv=5 and expecting a plain 5-fold split for a classifier.

    Why it fails

    An integer requests that many folds using the default strategy for the estimator type. For a classifier that default is stratified k-fold.

    Do this instead

    Use an integer when the default is what you want, and pass a splitter object when you need a different partitioning logic.

  • Common mistake

    Using n_iter with a release that expects n_splits

    What it looks like
    Writing ShuffleSplit(n_iter=1) in a recent release.
    Why it fails

    Recent releases name this setting n_splits, so the older name may not be recognized.

    Do this instead

    Use n_splits=1 in recent releases, and check the documentation of your installed version if older code fails.

  • Common mistake

    Choosing a plain random split for imbalanced classes

    What it looks like

    Using ShuffleSplit on a dataset where one class is rare.

    Why it fails

    Plain shuffling does not keep class proportions consistent, so the validation portion may not resemble the full dataset.

    Do this instead

    Use StratifiedShuffleSplit when classes are imbalanced and the validation portion should match the class makeup.

  • Common mistake

    Treating one split as equally reliable as k folds

Practice Choosing a Splitter

MEDIUM

A team is tuning a classifier on a dataset with several million rows, and each training run takes most of an afternoon. They want to keep the search affordable. Which splitter would you pass through cv, what setting produces a single split, and what risk should they note in their report?

Hints
  • Think about which option produces exactly one train and validation pair.
  • The class makeup matters for a classifier, so consider the stratified variant.
  • A single split gives one validation estimate per candidate.

Key Takeaways

  • GridSearchCV uses stratified k-fold cross-validation by default for classification and plain k-fold cross-validation for regression.
  • The cv parameter accepts an integer or a splitter object, and a splitter object replaces the default partitioning strategy.
  • ShuffleSplit or StratifiedShuffleSplit with n_splits=1 (n_iter=1 in older releases) produces one training and validation split, with StratifiedShuffleSplit preserving class proportions.
  • A single split reduces the training cost of tuning on very large datasets or with very slow models, at the cost of relying on one validation estimate.

Related concepts

More concepts starting with C