Comparing Models Fairly
Part of the Supervised Learning section of Coddy's Machine Learning journey. Lesson 38 of 58.
Comparing models on one split is a coin toss: one may land a lucky test set. Give every model the same five folds instead. For 150 banknotes, real or fake:
k-NN and logistic tie within their wobble, and k-NN is steadier. The tree trails.
A KFold splitter shuffles the rows once and hands each model identical folds:
from sklearn.model_selection import KFold
folds = KFold(n_splits=5, shuffle=True, random_state=0)
for model in [knn, logistic, tree]:
scores = cross_val_score(model, X, y, cv=folds)
print(f"{scores.mean():.3f} {scores.std():.3f}")It prints the numbers in the chart:
0.867 0.042
0.873 0.074
0.807 0.077Pick the highest mean; when means are close, the smaller std.
Challenge
MediumA cooking site predicts which visitors cook a recipe they open. The starter scores three models on one split, and the tree wins. Check it fairly; the program reads the number of folds.
- Make a
KFoldwith that many splits,shuffle=Trueandrandom_state=0. - Cross-validate each model on those folds; print its mean and std, 3 decimals.
- Print the model with the highest mean.
For other visitors and 5:
One split picks: k-NN
k-NN: mean 0.833, std 0.045
logistic: mean 0.860, std 0.044
tree: mean 0.787, std 0.029
Cross-validation picks: logisticTry it yourself
import numpy as np
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split, cross_val_score, KFold
from sklearn.neighbors import KNeighborsClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
n_folds = int(input())
# Don't change the lines below: 300 visitors, 6 browsing habits; label 1 means they cooked the recipe
X, y = make_classification(n_samples=300, n_features=6, n_informative=4, n_redundant=0,
flip_y=0.06, class_sep=0.8, random_state=0)
names = ["k-NN", "logistic", "tree"]
models = [KNeighborsClassifier(), LogisticRegression(max_iter=1000),
DecisionTreeClassifier(max_depth=4, random_state=0)]
# One split crowns a winner
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=0)
single = []
for model in models:
model.fit(X_train, y_train)
single.append(model.score(X_test, y_test))
print(f"One split picks: {names[np.argmax(single)]}")
# Write your code below
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Supervised Learning
1Your First Model
Learning from ExamplesTrain and Test SetsFit and PredictScoring a ModelRecap: Seed Sorter2Nearest Neighbors
How k-NN DecidesChoosing kDecision BoundariesScaling for NeighborsRecap: Wine Neighbors5Measuring Classifiers
The Confusion MatrixPrecision and RecallThe F1 ScoreImbalanced ClassesROC CurvesRecap: Screening Test11Project: Penguin Species
Meet the PenguinsPrepare the DataChoose a ModelTune the WinnerShip the ModelPractice on your own: Online Python compiler