Hello! In our last lesson, we established a toolkit of metrics like MAE, RMSE, and R-squared to measure a regression model's performance. However, all our evaluations were based on a single train_test_split. This introduces a subtle but significant problem: our model's score can be a matter of luck. Depending on which data points happen to land in the test set, the score can vary wildly. A "lucky" split might give us an overly optimistic score, while an "unlucky" one might make a good model look poor.
This lesson tackles that problem head-on. We'll explore cross-validation, a powerful and fundamental technique for getting a much more reliable and robust estimate of your model's true performance. You will learn the mechanics of k-fold cross-validation and its crucial variant, stratified k-fold cross-validation, which is essential when dealing with imbalanced datasets. This will solidify your understanding of how to properly evaluate a model, a non-negotiable skill in machine learning.
The Problem with a Single Split
Imagine you train a model and get an accuracy of 92% on your test set. That sounds great, but how confident are you in that single number? What if you had just used a different random_state in your train_test_split function and the accuracy dropped to 85%? Which score is "correct"? The answer is that neither is the full story. Both are just single data points reflecting a particular random split of your data.
To truly understand this variability, let's watch a practical demonstration.
A Comprehensive Guide to Cross-Validation with Scikit-Learn and Python
The video "A Comprehensive Guide to Cross-Validation" starts by perfectly illustrating the problem we're discussing.
Watch the first part of the video from the beginning until the end of the second test. The presenter trains the exact same model but gets two different scores (0.71 and 0.80) just by changing the random_state of the train-test split. This highlights why relying on a single score is risky.
This demonstration shows that to get a trustworthy assessment of a model's ability to generalize to new, unseen data, we need a more systematic approach than a one-off split.
K-Fold Cross-Validation: The Solution
K-fold cross-validation solves this problem by performing multiple train-test splits and averaging the results. The process is straightforward:
- Split: The entire dataset is partitioned into k equally sized segments, or "folds". A common choice for k is 5 or 10.
- Iterate: The process then iterates k times. In each iteration:
- One different fold is held out as the test set.
- The remaining k-1 folds are combined and used as the training set.
- The model is trained on the training set and evaluated on the test set, and the performance score is recorded.
- Aggregate: After k iterations, you will have k performance scores. The final cross-validation score is the average of these k scores. This average provides a much more stable and reliable estimate of the model's performance.
The image below illustrates this process for k=5. In each iteration, a different fold (in yellow) serves as the test set.

For a clear written explanation of this process and its benefits, the following article is excellent.
Understand K-Fold Cross-Validation:A Step-by-Step Guide | DigitalOcean
This guide from DigitalOcean provides a concise overview of K-Fold cross-validation.
First, read the section What is K-Fold Cross-Validation? for a clear definition. Then, review the table in the section K-Fold vs. Train-Test Split. This table is a great summary of why cross-validation is superior to a single split, touching on data utilization, the bias-variance tradeoff, and overfitting risk.
Implementing K-Fold with Scikit-Learn
Your proficiency with Python and scikit-learn allows us to look under the hood before using the convenient high-level functions. The codebasics channel provides an excellent walkthrough.
Machine Learning Tutorial Python 12 - K Fold Cross Validation
This video, "Machine Learning Tutorial Python 12 - K Fold Cross Validation," demonstrates the concept and its implementation from the ground up.
First, watch the conceptual explanation from this segment, which visually walks through the iterative process. Next, see how this is implemented in Python by creating a manual loop with StratifiedKFold. Watch from this section. Understanding this manual loop is great for building intuition about what happens internally. (We will discuss StratifiedKFold next, but the looping logic is the same for KFold). Finally, watch the part on cross_val_score from this segment. This function is the simple, practical way you'll perform cross-validation in most of your work.
As the video shows, while you can write a loop yourself using an iterator object like KFold, scikit-learn provides the cross_val_score function to do all the work in one line. It handles the splitting, looping, training, and scoring for you.
You provide the model, the full dataset (X and y), and the number of folds (cv), and it returns an array of scores, one for each fold.
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LinearRegression
# Assuming X and y are your features and target
model = LinearRegression()
# Perform 5-fold cross-validation
# For regression, you can specify a scoring metric like 'neg_mean_squared_error'
scores = cross_val_score(model, X, y, cv=5, scoring='neg_mean_squared_error')
# The scores are negative because scikit-learn's convention is to maximize scores.
# So we take the absolute value and often the mean.
import numpy as np
rmse_scores = np.sqrt(-scores)
print(f"Scores for each fold: {rmse_scores}")
print(f"Average RMSE: {rmse_scores.mean():.4f}")
print(f"Standard Deviation of RMSE: {rmse_scores.std():.4f}")
Reporting both the mean and the standard deviation of the scores gives a complete picture: the mean tells you the expected performance, and the standard deviation tells you how much that performance varies between different training sets.
Stratified K-Fold Cross-Validation
Standard K-Fold randomly splits the data. This works well for regression or balanced classification problems. However, for imbalanced classification problems (e.g., 95% non-fraud vs. 5% fraud), a random split could lead to a test fold containing very few, or even zero, instances of the minority class. Training or evaluating on such a fold would be uninformative or even cause errors.
Stratified K-Fold is the solution. It's a variation of k-fold that ensures the proportion of each class is the same in every fold as it is in the original dataset.

Let's turn to the scikit-learn documentation to see the technical difference.
3.1. Cross-validation: evaluating estimator performance
The official scikit-learn documentation provides a precise explanation and a powerful code example.
First, read the section on stratification to understand why it's needed for certain classification tasks. Next, read the section on Stratified K-fold. Pay close attention to the code example that follows. It generates a highly imbalanced dataset and compares the class counts in the folds created by StratifiedKFold versus KFold. You'll see that KFold creates folds with no minority class samples, while StratifiedKFold preserves the ratio perfectly.
The good news is that scikit-learn often makes the smart choice for you. When you pass an integer for the cv parameter in cross_val_score for a classification model, it automatically uses StratifiedKFold by default. For regression models, it uses KFold. This is a design choice that reflects best practices.
Conclusion
You now have a robust method for evaluating machine learning models that goes far beyond a simple train-test split. This is a cornerstone of reliable model development and selection.
Key Takeaways:
- A single
train_test_splityields an unstable performance score that depends on the randomness of the split. - K-Fold Cross-Validation provides a more reliable performance estimate by training and testing a model on multiple (
k) different subsets of the data and averaging the results. - Stratified K-Fold is a crucial variant for classification tasks. It ensures that the class proportions in each fold mirror the proportions in the overall dataset, which is vital for imbalanced data.
- In
scikit-learn, thecross_val_scorefunction is the primary tool for efficiently performing cross-validation.
In our upcoming lessons, we will delve into one of the most important theoretical concepts in machine learning: the bias-variance tradeoff. Cross-validation is not just an evaluation tool; it is also our primary diagnostic tool for understanding whether a model is too simple (high bias) or too complex (high variance). Your understanding of CV will be essential as we learn to diagnose and correct these common modeling issues.