Chapter 15 — Introduction to Machine Learning with Scikit-Learn
Machine learning builds models that learn patterns from data. Scikit-Learn provides a uniform, well-documented API for classical ML. This chapter introduces the landscape and the estimator interface, then trains and evaluates a first model end-to-end.
Learning Objectives
- Distinguish supervised, unsupervised, and reinforcement learning.
- Distinguish classification from regression.
- Use the scikit-learn estimator API:
fit,predict,transform,score. - Split data into training and test sets.
- Scale features and explain why it matters.
- Train, evaluate, and inspect a k-NN classifier.
- Build a preprocessing + model Pipeline.
Prerequisites / Imports
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
from sklearn.pipeline import Pipeline
from sklearn.metrics import accuracy_score, classification_report
1 What Is Machine Learning?
ML learns a mapping from inputs $X$ to outputs $y$ (supervised) or structure in $X$ (unsupervised) from data, then generalizes to new data.
- Supervised: classification (discrete labels), regression (continuous target).
- Unsupervised: clustering, dimensionality reduction.
- Reinforcement: learning by reward (not covered here).
2 The Estimator API
Every model is an object with the same interface: fit(X, y) to train, predict(X) to infer, and score(X, y) to evaluate. Preprocessors add transform(X).
3 The Iris Dataset
A classic benchmark: 150 iris flowers, 4 measurements, 3 species.
iris = load_iris(as_frame=True)
X = iris.data
y = iris.target
print('feature names:', list(iris.feature_names))
print('target names:', list(iris.target_names))
print('shape:', X.shape)
X.head()
feature names: ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)'] target names: ['setosa', 'versicolor', 'virginica'] shape: (150, 4)
| sepal length (cm) | sepal width (cm) | petal length (cm) | petal width (cm) | |
|---|---|---|---|---|
| 0 | 5.1 | 3.5 | 1.4 | 0.2 |
| 1 | 4.9 | 3.0 | 1.4 | 0.2 |
| 2 | 4.7 | 3.2 | 1.3 | 0.2 |
| 3 | 4.6 | 3.1 | 1.5 | 0.2 |
| 4 | 5.0 | 3.6 | 1.4 | 0.2 |
4 Train/Test Split
Hold out a portion of data to evaluate generalization. Always split before scaling or training to avoid data leakage.
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42, stratify=y)
print('train:', X_train.shape, 'test:', X_test.shape)
train: (105, 4) test: (45, 4)
5 Feature Scaling
Distance-based models (k-NN, SVM, k-means) need features on the same scale. StandardScaler standardizes to zero mean, unit variance.
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test) # use train statistics!
print('scaled train mean (should be ~0):', X_train_scaled.mean(axis=0).round(3))
print('scaled train std (should be ~1):', X_train_scaled.std(axis=0).round(3))
scaled train mean (should be ~0): [ 0. -0. -0. -0.] scaled train std (should be ~1): [1. 1. 1. 1.]
6 A First Model: k-Nearest Neighbors
k-NN classifies a point by the majority label among its $k$ nearest neighbors.
knn = KNeighborsClassifier(n_neighbors=5)
knn.fit(X_train_scaled, y_train)
y_pred = knn.predict(X_test_scaled)
print('accuracy:', round(accuracy_score(y_test, y_pred), 3))
print(classification_report(y_test, y_pred, target_names=iris.target_names))
accuracy: 0.911
precision recall f1-score support
setosa 1.00 1.00 1.00 15
versicolor 0.79 1.00 0.88 15
virginica 1.00 0.73 0.85 15
accuracy 0.91 45
macro avg 0.93 0.91 0.91 45
weighted avg 0.93 0.91 0.91 45
7 Pipelines Prevent Leakage
A Pipeline bundles scaling + modeling so the test set is never used to fit the scaler.
pipe = Pipeline([('scaler', StandardScaler()), ('knn', KNeighborsClassifier(n_neighbors=5))])
pipe.fit(X_train, y_train)
print('pipeline test accuracy:', round(pipe.score(X_test, y_test), 3))
pipeline test accuracy: 0.911
8 Choosing k
Compare accuracy across values of $k$ to select a good one.
ks = range(1, 21)
accs = []
for k in ks:
p = Pipeline([('scaler', StandardScaler()), ('knn', KNeighborsClassifier(n_neighbors=k))])
p.fit(X_train, y_train)
accs.append(p.score(X_test, y_test))
plt.figure(figsize=(7,4))
plt.plot(ks, accs, marker='o')
plt.title('k-NN accuracy vs k'); plt.xlabel('k'); plt.ylabel('test accuracy')
plt.show()
print('best k:', ks[int(np.argmax(accs))], 'accuracy:', round(max(accs), 3))
best k: 9 accuracy: 0.956
Case Study: Predicting Iris Species
Put it all together: load, split, pipeline, train, evaluate, and inspect a few predictions.
pipe = Pipeline([('scaler', StandardScaler()), ('knn', KNeighborsClassifier(n_neighbors=7))])
pipe.fit(X_train, y_train)
sample = X_test.iloc[:5]
print('predictions:', pipe.predict(sample))
print('true labels:', y_test.iloc[:5].values)
print('overall accuracy:', round(pipe.score(X_test, y_test), 3))
result = pd.DataFrame({'predicted': iris.target_names[pipe.predict(sample)], 'true': iris.target_names[y_test.iloc[:5].values]})
result
predictions: [2 1 1 1 2] true labels: [2 1 2 1 2] overall accuracy: 0.933
| predicted | true | |
|---|---|---|
| 0 | virginica | virginica |
| 1 | versicolor | versicolor |
| 2 | versicolor | virginica |
| 3 | versicolor | versicolor |
| 4 | virginica | virginica |
Exercises
- List three differences between supervised and unsupervised learning.
- Split the iris data 80/20 with stratification and print the shapes.
- Explain why
fit_transformis used on the training set buttransformon the test set. - Train a k-NN with $k=1$ and $k=15$ and compare accuracies.
- Build a
PipelinewithStandardScalerandKNeighborsClassifier. - Plot test accuracy vs $k$ for $k=1\dots25$.
- Print a classification report and identify which class has the lowest F1-score.
- Why is data leakage a problem when scaling before splitting?
- Replace k-NN with
LogisticRegressionin the pipeline and compare. - Describe the estimator API in two sentences.
Python Data Science: From Foundations to Applications — Chapter 15