ML Train Test
Learn how train_test_split lets you honestly measure a model's performance and spot overfitting before it costs you.
Why You Need a Train/Test Split
A model's real job is to make good predictions on data it has never seen. If you train it and then measure its accuracy on the very same rows, you aren't testing that ability — you're just checking how well it memorized the answers. Overfitting happens when a model does exactly that: it captures the noise and quirks of the training set rather than the general pattern, so its training score looks great while its performance on new data is much worse.
scikit-learn's train_test_split function solves this by randomly splitting your dataset into two pieces before any training happens. The model only ever sees the training portion during fit(); the test portion is held back and used purely to check how the model behaves on data it has never touched.
- test_size (or train_size) controls the split ratio — 0.2 to 0.3 for the test set is a common starting point.
- random_state fixes the random shuffle so the same split — and the same results — can be reproduced later.
- stratify=y keeps class proportions in classification problems consistent between the train and test sets.
- shuffle=True (the default) randomizes row order before splitting; leave it off only for ordered data like time series.
Using train_test_split
Example
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
X, y = load_iris(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.25, random_state=42
)
print("Training rows:", X_train.shape[0])
print("Test rows: ", X_test.shape[0])Overfitting vs Underfitting
Example
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score
deep_tree = DecisionTreeClassifier(max_depth=None, random_state=42)
deep_tree.fit(X_train, y_train)
print("Train accuracy:", accuracy_score(y_train, deep_tree.predict(X_train)))
print("Test accuracy: ", accuracy_score(y_test, deep_tree.predict(X_test)))
shallow_tree = DecisionTreeClassifier(max_depth=2, random_state=42)
shallow_tree.fit(X_train, y_train)
print("Shallow train accuracy:", accuracy_score(y_train, shallow_tree.predict(X_train)))
print("Shallow test accuracy: ", accuracy_score(y_test, shallow_tree.predict(X_test)))Example
from sklearn.datasets import make_classification
from collections import Counter
X_imb, y_imb = make_classification(
n_samples=200, weights=[0.9, 0.1], random_state=1
)
X_tr, X_te, y_tr, y_te = train_test_split(
X_imb, y_imb, test_size=0.2, random_state=1, stratify=y_imb
)
print("Original distribution:", Counter(y_imb))
print("Test distribution: ", Counter(y_te))Exercise: ML Train Test
Why is a dataset typically split into training and test sets?