A self-contained Jupyter notebook that teaches scikit-learn — Python's core library for classical machine learning — from first principles up to an undergraduate ("degree level 5") depth. It's written as a learning exercise, not just a reference: every step includes plain-English explanations of what the code does and why, and backs up each claim with a worked, numeric demonstration rather than just asserting it.
It starts by writing a classifier by hand to feel the problem scikit-learn solves, then builds
up through the Estimator API, preprocessing, evaluation, pipelines, and hyperparameter search,
finishing with a capstone that trains a real neural network (MLPClassifier) on the same
handwritten digit images used in the companion
NumPy_Fundamentals notebook — so the two
notebooks can be read together as "build it by hand, then see the toolkit that does it for you."
Part of a series on machine learning fundamentals, each solving a related problem at a different level of the stack:
- NumPy_Fundamentals — build a neural network from scratch using nothing but NumPy
- Scikit_Learn_Guide (this notebook) — the same handwritten-digit dataset, solved with scikit-learn's toolkit
- HandwrittenTensorflow — a full digit-recognition project built with TensorFlow/Keras
- HandwrittenPyTorch — the same digit-recognition project built with PyTorch
They're independent and don't require reading in order, but each links back to the others where the connection is most relevant.
- Import scikit-learn and see what it gives you
- The problem scikit-learn solves — implementing k-nearest neighbors by hand, then
confirming it matches
KNeighborsClassifierexactly - The core API — Estimators, Transformers, Predictors (
fit/predict/transform) - Loading and splitting data — the Iris dataset,
train_test_split - Why the API matters — five different algorithms, trained and scored with identical code
- Why preprocessing matters — a deliberately extreme demo where feature scaling alone turns a 43%-accurate model into a 99%-accurate one
- Training and evaluating a classifier —
classification_report, confusion matrices - Why one train/test split isn't enough — measuring split-to-split variance directly,
then fixing it with
cross_val_score - Pipelines and data leakage — a leaky feature-selection pipeline claims ~70% accuracy on pure random noise; the correct pipeline correctly reports ~50% (chance)
- Hyperparameter tuning — a hand-rolled grid search vs.
GridSearchCV, confirmed to agree on the same best answer - Capstone: training
MLPClassifier(scikit-learn's neural network) on 1,797 real handwritten digit images, benchmarked against logistic regression, a random forest, and an SVM — with a direct comparison to the from-scratch NumPy network's accuracy - How scikit-learn fits alongside deep learning frameworks — TensorFlow/Keras and PyTorch, with an illustrative (non-executed) Keras snippet
It finishes with a Summary recapping the whole notebook and a glossary of key terms
(Estimator, Transformer, Pipeline, cross-validation, data leakage, hyperparameter, MLP), plus
Ideas to extend — RandomizedSearchCV, ColumnTransformer, SciKeras, model persistence
with joblib, and scaling up to full MNIST.
- Python 3.9+
- pip
-
Clone or download this repository.
-
Create a virtual environment in the project folder:
python -m venv .venv
-
Activate it.
Windows (PowerShell/cmd):
.venv\Scripts\activate
macOS/Linux:
source .venv/bin/activate -
Install the dependencies:
pip install -r requirements.txt
-
Set up
nbstripout, which this repository uses to strip notebook cell outputs before they're committed (so diffs stay readable and outputs never get checked into git):nbstripout --install
This registers a git filter scoped to this repository only — it doesn't affect any other project on your machine.
-
Register the environment as a Jupyter kernel (so the notebook can find your installed packages):
python -m ipykernel install --user --name=scikit-learn-guide-venv --display-name "Python (scikit-learn-guide-venv)"
Launch Jupyter Lab using the venv's own executable rather than relying on activate alone
(if another Python install is earlier on your PATH, a plain jupyter lab command can silently
launch the wrong environment):
.venv\Scripts\jupyter-lab.exe(macOS/Linux: .venv/bin/jupyter-lab, after activating the venv.)
Open scikit_learn_guide.ipynb, and make sure it's using the "Python
(scikit-learn-guide-venv)" kernel (in VS Code: click the kernel picker in the top-right of the
notebook; in Jupyter Lab: use the Kernel → Change Kernel menu).
Then run the cells from top to bottom, reading the explanations as you go. The whole notebook (including training the capstone neural network) runs in well under a minute on a typical CPU. Every dataset used (Iris, the synthetic scaling/leakage demos, and the handwritten digits) is either built into scikit-learn or generated on the fly, so nothing needs to be downloaded — the notebook works fully offline.
- The capstone (Step 11) deliberately reuses the same 8x8 handwritten digits dataset as the
NumPy_Fundamentalsnotebook's capstone, so the two can be compared directly: a from-scratch NumPy network there, and several one-line scikit-learn models here. - Step 9's data-leakage demo uses 500 purely random features and purely random labels on purpose — the "correct" accuracy really should sit around 50%, and the notebook shows exactly how easy it is to accidentally report something far higher.
- Use
RandomizedSearchCVon a much larger hyperparameter grid and compare how close it gets to the true best score in a fraction of the time - Try
ColumnTransformeron a dataset with mixed numeric and categorical features - Install
tensorflowand run Step 12's illustrative Keras snippet for real, then compare its accuracy against Step 11'sMLPClassifier - Look up SciKeras, which lets a Keras model be tuned with
GridSearchCVjust likeRandomForestClassifierwas in Step 10 - Save a trained pipeline with
joblib.dump/joblib.loadand reload it in a fresh session - Rerun the capstone on full-resolution MNIST (
sklearn.datasets.fetch_openml('mnist_784')) and compare training time and accuracy against the smaller digits dataset used here
Each of these has a detailed, step-by-step walkthrough with full explanations and runnable code
in ideas_to_extend/.
Copyright © 2026 Trevor Smith. All rights reserved. Released under a Personal Use License.
In plain terms:
- ✅ You can download it from this repository and use it for free, for personal use, study or at work (including teaching).
- ✅ You can change it for your own private use.
- ❌ You can't share, copy, upload or distribute it, modified or not. To tell someone about it, send them a link to this repository.
- ❌ You can't sell it, or charge for a product or service based on it.
- ❌ You can't remove the copyright notice or present it as your own work.
The full LICENSE text is the legally binding version; this summary is just a guide. This is proprietary material, not open source. It replaces the earlier MIT and CC BY-NC 4.0 licences.