Stratified K-fold is a way to split data for training and testing. It keeps the same class balance in each split. This helps us get fair and stable results for classification tasks. The main metrics to check are accuracy, precision, recall, and F1 score. These metrics tell us how well the model works on each fold. Because the splits keep class proportions, the metrics better reflect real performance.
Stratified K-fold in ML Python - Model Metrics & Evaluation
Fold 1 Confusion Matrix:
+-----------------+-------+-------+
| | Pred+ | Pred- |
+-----------------+-------+-------+
| Actual + (TP) | 40 | 10 |
| Actual - (FP/FN)| 5 | 45 |
+-----------------+-------+-------+
Fold 2 Confusion Matrix:
+-----------------+-------+-------+
| | Pred+ | Pred- |
+-----------------+-------+-------+
| Actual + (TP) | 38 | 12 |
| Actual - (FP/FN)| 7 | 43 |
+-----------------+-------+-------+
Total samples per fold remain balanced by class.
Stratified K-fold helps us see how precision and recall change across different splits. For example, in spam detection:
- Precision means how many emails marked as spam really are spam.
- Recall means how many actual spam emails we caught.
Because each fold keeps the spam and non-spam ratio, we get a true picture of this tradeoff. If precision is high but recall is low, the model misses many spam emails. If recall is high but precision is low, many good emails are wrongly marked as spam.
Good: Metrics like accuracy, precision, recall, and F1 score are consistent across folds. For example, accuracy around 85-90%, precision and recall both above 80%, and F1 score close to these values.
Bad: Large differences in metrics between folds, like accuracy 90% in one fold and 60% in another. This means the model is unstable or the data split is not representative. Also, very low recall or precision indicates poor model performance.
- Ignoring class imbalance: Without stratification, some folds may have very few samples of a class, misleading metrics.
- Data leakage: If data from the same source appears in both train and test folds, metrics look better but model won't generalize.
- Overfitting: High training metrics but low test metrics across folds show overfitting.
- Accuracy paradox: High accuracy can be misleading if classes are imbalanced; precision and recall give better insight.
No, this model is not good for fraud detection. Even though accuracy is high, recall is very low. This means the model misses most fraud cases, which is dangerous. Stratified K-Fold would help reveal this problem by keeping fraud cases balanced in each fold and showing low recall consistently.
Practice
Stratified K-fold in machine learning?Solution
Step 1: Understand Stratified K-fold concept
Stratified K-fold splits data into parts (folds) while keeping the proportion of each class the same in every fold.Step 2: Compare options with concept
Only To keep the class distribution balanced in each fold describes this balancing of class distribution. Other options describe unrelated tasks.Final Answer:
To keep the class distribution balanced in each fold -> Option CQuick Check:
Stratified K-fold = Balanced class distribution [OK]
- Thinking it just shuffles data randomly
- Confusing with data augmentation
- Assuming it changes feature numbers
Solution
Step 1: Recall correct import syntax
In scikit-learn, StratifiedKFold is in the model_selection module, imported as: from sklearn.model_selection import StratifiedKFold.Step 2: Check each option
from sklearn.model_selection import StratifiedKFold matches the correct syntax. Options A, B, and C use wrong import style or deprecated module.Final Answer:
from sklearn.model_selection import StratifiedKFold -> Option BQuick Check:
Correct import = from sklearn.model_selection import StratifiedKFold [OK]
- Using old module cross_validation
- Wrong import order (import ... from ...)
- Misspelling module or class name
from sklearn.model_selection import StratifiedKFold
import numpy as np
X = np.arange(10)
y = np.array([0,0,1,1,0,1,0,1,0,1])
skf = StratifiedKFold(n_splits=2)
for train_index, test_index in skf.split(X, y):
print(len(train_index), len(test_index))Solution
Step 1: Understand StratifiedKFold split sizes
With n_splits=2, data is split into 2 folds. Total data size is 10.Step 2: Calculate train and test sizes per fold
Each fold has 5 samples. For each split, test set is one fold (5 samples), train set is the other fold (5 samples). So train=5, test=5.Step 3: Check actual output
However, the code prints lengths of train_index and test_index. For each fold, train_index length is 8 and test_index length is 2 because StratifiedKFold with n_splits=2 splits data into 2 folds, but the test fold size is 2 due to stratification and class distribution.Final Answer:
8 2 -> Option AQuick Check:
Train + Test = 10, test size = 2 [OK]
- Assuming equal split without stratification
- Confusing train and test sizes
- Ignoring class balance effect on fold sizes
from sklearn.model_selection import StratifiedKFold
X = [[1],[2],[3],[4]]
y = [0, 0, 1, 1]
skf = StratifiedKFold(n_splits=3)
for train_idx, test_idx in skf.split(X, y):
print(train_idx, test_idx)Solution
Step 1: Check n_splits vs class counts
StratifiedKFold requires n_splits ≤ number of samples in the smallest class. Here, smallest class has 2 samples but n_splits=3.Step 2: Validate other options
X can be list or array, y can be labels, loop syntax is correct, and one-hot encoding is not required.Final Answer:
n_splits cannot be greater than the number of members in any class -> Option AQuick Check:
n_splits ≤ smallest class size [OK]
- Thinking data type of X causes error
- Believing one-hot encoding is needed
- Misreading loop syntax as wrong
Solution
Step 1: Calculate class 1 samples per fold
Total class 1 samples = 10. With 5 splits, each fold should have 10 / 5 = 2 samples of class 1 in total, but test fold is one part.Step 2: Understand stratification in test fold
Each test fold is 1/5th of data, so it should have 10 * (1/5) = 2 class 1 samples. But since 10 class 1 samples split evenly, each fold gets 2.Final Answer:
2 -> Option DQuick Check:
Class 1 per fold = total class 1 / splits [OK]
- Assuming equal class counts in all folds without stratification
- Confusing total samples with class samples
- Ignoring that test fold is 1 split
Ready to prove it?
Pass the test and this pattern moves unknown
