Hello! Let's dive into your next lesson in the "Model Evaluation and Improvement" module.
In our last lesson, we explored L1 and L2 regularization as powerful techniques to combat overfitting. A key part of using regularization is choosing the right value for the hyperparameter, . A simple train/test split might give you a misleading idea of which is best, because the result could depend heavily on the random chance of how the data was split.
Today, we'll learn the standard and much more robust solution to this problem. This lesson addresses the learning outcome: Assess model generalization performance using k-fold cross-validation. You will learn a technique that is fundamental to reliable model evaluation, model selection, and hyperparameter tuning in virtually all machine learning projects.
By the end of this lesson, you'll understand why a single data split is risky and how k-fold cross-validation provides a more trustworthy estimate of your model's performance on unseen data.
1. The Limits of a Single Train-Test Split
So far, our primary method for evaluating a model has been to:
- Split our data into a training set and a testing set.
- Train the model on the training set.
- Measure its performance on the test set.
While simple, this approach has a significant weakness: the performance score you get can be a matter of luck. If, by chance, the test set contains "easy" examples, your model might look better than it really is. If it contains particularly "hard" or unusual examples, your model might look worse. This makes it difficult to confidently compare different models or different hyperparameter settings.
To get a better feel for this problem, let's watch the beginning of this tutorial.
Machine Learning Tutorial Python 12 - K Fold Cross Validation
The 'codebasics' channel provides a great analogy to explain why a single train-test split can be unreliable. It sets the stage perfectly for why we need a more robust method.
Watch from the beginning until 03:31. Pay close attention to the analogy of the student preparing for a math test. Notice the two problems discussed: Training and testing on the exact same data. Using a single train-test split, where the split itself might introduce bias (e.g., all algebra for training, all calculus for testing).
This variability means a single score from one test set is not a reliable estimate of the model's true generalization performance. We need a way to get a more stable and accurate assessment.
2. The K-Fold Cross-Validation Process
K-fold cross-validation solves this problem by using the data more efficiently. Instead of a single split, it performs k splits and averages the results. This gives a more reliable estimate of how the model is likely to perform on data it has never seen before.
Here's the process, step-by-step:
- Split: The dataset is partitioned into k equal-sized, non-overlapping subsets, called "folds". A common choice for k is 5 or 10.
- Iterate: The process runs for k iterations. In each iteration:
- A different fold is chosen as the validation set.
- The remaining k-1 folds are combined to form the training set.
- Train & Evaluate: The model is trained on the training set and evaluated on the validation set. The evaluation score (e.g., accuracy, MSE) is recorded.
- Average: After k iterations, you will have k different scores. The final performance metric is the average of these k scores.
This animation from StatQuest provides a fantastic visual explanation of the process.
Machine Learning Fundamentals: Cross Validation
This StatQuest video, "Machine Learning Fundamentals: Cross Validation", masterfully illustrates the core concept of k-fold cross-validation.
Watch from 03:26 to 05:20. This segment clearly shows how the data is divided into blocks (folds) and how each block gets a turn to be the test set. This visual will help solidify your understanding of the core mechanism.
The image below shows a 5-fold cross-validation scheme. Notice how the yellow "Test" block moves through the data in each iteration.

A crucial point is that cross-validation is typically performed after an initial train-test split. You hold out a final test set, perform cross-validation on the training set to select your best model and tune its hyperparameters, and only then, at the very end, do you evaluate your final chosen model on the held-out test set. This prevents any information from the final test set from "leaking" into your model selection process.

3. Implementing K-Fold with Scikit-Learn
As with most common ML tasks, scikit-learn makes implementing cross-validation straightforward. You have two main options: a lower-level approach for more control and a high-level function for convenience.
The cross_val_score Function (The Easy Way)
For most use cases, the cross_val_score function is all you need. It handles the entire k-fold iteration loop for you in a single line of code.
Let's see how it works in practice with a full code example.
A Comprehensive Guide to K-Fold Cross Validation
This article, 'A Comprehensive Guide to K-Fold Cross Validation' from DataCamp, provides a clear, step-by-step coding example. It will show you how to apply cross-validation to a regression problem.
Read the section titled 'Implementing K-Fold Cross-Validation in Python Using scikit-learn'. Follow the code from 'Loading the dataset' down to 'Displaying the final results'. Focus on these two lines in particular: kf = KFold(n_splits=k, shuffle=True, random_state=42): This creates the cross-validation object. Note the parameters for the number of splits and shuffling. scores = cross_val_score(model, X, y, cv=kf, ...): This is the key function call. It takes the model, the data, and the cross-validation object (kf) and returns an array of scores.
As you saw in the article, cross_val_score returns an array of scores, one for each fold. You can then calculate the mean and standard deviation of these scores to get a robust estimate of your model's performance.
average_score = scores.mean()score_std_dev = scores.std()
The mean tells you the average performance, while the standard deviation tells you how much the performance varied across the different folds. A low standard deviation is desirable, as it suggests the model's performance is stable and not dependent on a particular data split.
Test your understanding!
You run the following code:from sklearn.model_selection import cross_val_scorefrom sklearn.linear_model import LogisticRegression
model = LogisticRegression()# X and y are your feature matrix and target vectorscores = cross_val_score(model, X, y, cv=10, scoring='accuracy')
What will the scores variable contain? What does scores.mean() represent?
Show answer
The scores variable will be a NumPy array containing 10 floating-point numbers. Each number is the accuracy score from one of the 10 folds of the cross-validation process.
scores.mean() represents the average accuracy across all 10 folds. This average value is a more reliable estimate of the model's generalization accuracy than a score from a single train-test split.
The KFold Class (The Manual Way)
While cross_val_score is convenient, sometimes you need more control over the loop. The KFold class allows you to generate the indices for the training and validation sets for each fold, which you can then use in a manual for loop. This is useful if you need to perform custom operations within each fold.
The following video demonstrates both the manual loop using KFold and the simpler cross_val_score function, showing they achieve the same thing.
Machine Learning Tutorial Python 12 - K Fold Cross Validation
Let's return to the 'codebasics' tutorial. This segment will walk you through the Python code, first showing the manual 'for loop' approach and then the much cleaner cross_val_score function.
Watch from 08:06 to 21:18. The first part (until 19:19) shows how to use KFold and StratifiedKFold inside a for loop to get scores. The second part (from 19:19 onwards) introduces cross_val_score as a simple, one-line alternative that does all that work for you. Notice how it's used to compare Logistic Regression, SVM, and Random Forest.
4. Key Considerations
When using k-fold cross-validation, there are a few important details to keep in mind.
-
Choosing K: The number of folds, k, is a hyperparameter.
- A small k (e.g., 3) is computationally cheaper but gives a less reliable estimate (higher bias).
- A large k (e.g., setting k to the number of samples, known as Leave-One-Out CV) is computationally expensive but gives a low-bias estimate.
- In practice, k=5 or k=10 are considered good defaults that balance this trade-off.
-
Shuffling: If your data has some inherent order (e.g., sorted by class label), it's crucial to shuffle the data before splitting it into folds. In
scikit-learn'sKFold, you can do this by settingshuffle=True. This ensures your folds are representative of the overall data distribution. The one exception is for time-series data, where the order is meaningful and must be preserved. -
Stratification: In classification problems, especially with imbalanced classes, you should use Stratified K-Fold. This variant ensures that each fold has the same percentage of samples for each class as the complete dataset. In
scikit-learn,cross_val_scoreautomatically uses stratified folds for classification models. For manual control, you would use theStratifiedKFoldclass instead ofKFold.
Conclusion
You've now learned a cornerstone of applied machine learning! K-fold cross-validation is the standard for getting a reliable picture of how your model will perform in the real world. It is the go-to method for comparing models and for tuning hyperparameters (like the alpha from our last lesson).
Key Takeaways:
- A single train-test split can produce misleading results due to the random nature of the split.
- K-fold cross-validation provides a more robust performance estimate by training and testing the model on k different subsets of the data and averaging the results.
- The mean score from cross-validation gives you a better idea of the model's true performance, while the standard deviation tells you how stable that performance is.
- In
scikit-learn, thecross_val_scorefunction is the easiest and most common way to perform k-fold cross-validation. - For classification, stratified k-fold is preferred to handle class imbalances.
Preview of the Next Lesson:
We've been talking about how a model's score can vary depending on the sample of data it's tested on. This idea of sample-to-sample variability is a core concept in statistics. In the next lesson, we will step back and look at a fundamental statistical principle that governs this behavior: the Central Limit Theorem. Understanding it will help you understand how sample averages (like our average cross-validation score) relate to the "true" value we're trying to estimate, laying the groundwork for statistical tests and confidence intervals.