Thomas Piacentini
← Workshop

Cheat sheet

Classical Models Compared

Original text · English

Linear and logistic regression, trees and forests, SVM, KNN and Naive Bayes side by side, with when to use each.

Models side by side

ModelTrains withBoundary, prediction cost and memory
Linear regressionGradient descentA hyperplane. Normal equation is O(n^3) in features
Logistic regressionbinary cross-entropyAlways linear. Boundary where p = 0.5
Decision treeGini impurityRectangular regions from greedy splits. High variance
Random forestBaggingMajority vote or average of many trees
SVMHinge lossMaximum margin. Stores only the support vectors
KNNLazyNo training. O(n \cdot d) per query, stores all data
Naive BayesCount frequenciesLinear. Prediction is one matrix multiply
Sources

Scaling and best data

ModelScale featuresWins on
Linear regressionyesBaselines for every regression task
Trees and forestsnoTabular data, mixed types, under 10k rows
SVMyesSmall or high-dimensional sparse data
KNNyesSmall data, up to about 20-50 features
Multinomial NBnoText with few training samples
Gaussian NBnoContinuous features near a bell curve
Sources

Use each model when

  • Use linear regression as the baseline for every regression task.
  • Use logistic regression for yes-or-no answers with probabilities and a linear boundary.
  • Use a random forest for flat tables. It needs almost no hyperparameter tuning.
  • Use an SVM for small data or sparse text with TF-IDF features.
  • Use KNN when the data changes often and you want zero training time.
  • Use TF-IDF with MultinomialNB for text with fewer than 10,000 training samples.
  • Use BernoulliNB for short text. Set binary=True in CountVectorizer.
Sources

Losses and formulas

MSE
\frac{1}{n} \sum (\hat{y} - y)^2. The gradient for w is \frac{2}{n} \sum (\hat{y} - y) x.
R squared
1 - SS_{\text{res}} / SS_{\text{tot}}. 1.0 is perfect. 0.0 equals the mean.
Sigmoid
\sigma(z) = 1 / (1 + e^{-z}). At z = 0 it gives 0.5.
Binary cross-entropy
-\frac{1}{n} \sum (y \log p + (1-y) \log(1-p)). Gradient \frac{1}{n} \sum (p - y) x.
Gini
1 - \sum_k p_k^2. 6 cats and 4 dogs give 0.48.
Hinge
\max(0, 1 - y f(x)). Zero beyond the margin.
RBF kernel
\exp(-\gamma \lVert x - z \rVert^2). Near 1 for close points.
Multinomial NB
(\text{count} + \alpha) / (\text{total} + \alpha \cdot V), summed in log space.
Sources

Scale, then fit

clf = Pipeline([
("scaler", StandardScaler()),SVM and KNN need it
("svm", SVC(kernel="rbf", C=1.0, gamma="scale")),dual form, kernels
])
clf.fit(X_train, y_train)
clf.score(X_test, y_test)accuracy
clf['svm'].n_support_support vectors
("svm", LinearSVC(C=1.0, max_iter=10000))large data, primal
("knn", KNeighborsClassifier(n_neighbors=5, metric="euclidean"))
mnb = MultinomialNB(alpha=1.0)counts, no scaling
mnb.fit(X_train_counts, y_train)
Sources

Grow a random forest

  1. Bootstrap sample rows with replacement. About 63% of rows appear.
  2. Out-of-bag the other rows can validate the tree.
  3. Feature subset each split sees \sqrt{n_{\text{features}}} features for classification.
  4. Greedy split pick the feature and threshold with the highest information gain.
  5. Stop a pure node or a pre-pruning limit ends the branch.
  6. Repeat build n_trees trees. The default is 100.
  7. Aggregate majority vote for classes, average for regression.
Sources

Knobs that trade bias and variance

CommandWhat it does
Large CNarrow margin, fewer misclassifications. Overfits
Small CWide margin, more violations. Underfits
K = 1Zero training error. High variance
K = NPredicts the majority class. Maximum bias
Max depthStops the tree early. Pre-pruning
NB alphaHigher alpha gives stronger smoothing
Ridge \lambdaHigher gives smaller weights
SVR \epsilonWider tube, fewer support vectors
Sources

Defaults in the lesson code

SettingDefaultNote
Tree max_depthNoneGrows until every leaf is pure
Tree min_samples_split2A pre-pruning control
Tree criterion"gini"Gini and entropy split almost the same
Forest n_trees100scikit-learn uses n_estimators=100
Forest max_features"sqrt"Regression uses n_features/3
KNN k5Start near sqrt(N). Odd K for binary
SVM rbf_kernel gamma0.5polynomial_kernel degree 3
GaussianNB var_smoothing1e-9Stops division by zero variance
Sources

Failures and fixes

SymptomCauseFix
Logistic fails on circlesThe boundary is always linearAdd polynomial features
SVM accuracy is poorUnscaled features distort the marginStandardScaler in a Pipeline
SVC too slowDual form is O(n^2) to O(n^3)LinearSVC primal form
KNN degrades with many featuresCurse of dimensionalityPCA or UMAP first
One tree changes with the dataA single tree is high varianceUse a random forest
MDI ranks a noise feature highBias to high cardinalityPermutation importance
NB gives probability 0Unseen word in a classLaplace smoothing, alpha 1
MultinomialNB rejects featuresNegative feature valuesGaussianNB or shift values
Sources

Questions

Why not MSE for logistic regression?
With a sigmoid, MSE is non-convex. Binary cross-entropy is convex.
Why does NB work with a wrong assumption?
Classification needs correct rankings, not correct probabilities.
Why does a forest beat one tree?
Averaging decorrelated trees reduces variance without more bias.
Why do only support vectors count?
Points beyond the margin have zero hinge loss.
NB or logistic regression?
Start with NB. Switch when data is large and NB plateaus.
Normal equation or gradient descent?
Normal equation for small data. Gradient descent for large data.
Do I trust NB probabilities?
No. Use CalibratedClassifierCV with cv=5.
Sources

From-scratch classes

TaskCode
Closed-form lineLinearRegressionNormal()
Node impuritygini_impurity(labels)
Kernel valuerbf_kernel(x, z, gamma=0.5)
Batch hinge losshinge_loss(X, y, w, b)
Text classifierMultinomialNB(alpha=1.0)
Sources
Original source
---
id: ml-model-comparison
title: Classical Models Compared
code: CC
subtitle: Linear and logistic regression, trees and forests, SVM, KNN and Naive Bayes side by side, with when to use each.
hue: 30
sources: phases/02-ml-fundamentals/02-linear-regression, phases/02-ml-fundamentals/03-logistic-regression, phases/02-ml-fundamentals/04-decision-trees, phases/02-ml-fundamentals/05-support-vector-machines, phases/02-ml-fundamentals/06-knn-and-distances, phases/02-ml-fundamentals/14-naive-bayes
source_hash: e76464be4e3d4e8a
---

## Models side by side
type: comparison
span: 2
from: phases/02-ml-fundamentals/02-linear-regression/docs/en.md, phases/02-ml-fundamentals/03-logistic-regression/docs/en.md, phases/02-ml-fundamentals/04-decision-trees/docs/en.md, phases/02-ml-fundamentals/05-support-vector-machines/docs/en.md, phases/02-ml-fundamentals/06-knn-and-distances/docs/en.md, phases/02-ml-fundamentals/14-naive-bayes/docs/en.md

| Model | Trains with | Boundary, prediction cost and memory |
|---|---|---|
| Linear regression | Gradient descent | A hyperplane. Normal equation is $O(n^3)$ in features |
| Logistic regression | binary cross-entropy | Always linear. Boundary where p = 0.5 |
| Decision tree | Gini impurity | Rectangular regions from greedy splits. High variance |
| Random forest | Bagging | Majority vote or average of many trees |
| SVM | Hinge loss | Maximum margin. Stores only the support vectors |
| KNN | Lazy | No training. $O(n \cdot d)$ per query, stores all data |
| Naive Bayes | Count frequencies | Linear. Prediction is one matrix multiply |

## Scaling and best data
type: comparison
from: phases/02-ml-fundamentals/02-linear-regression/docs/en.md, phases/02-ml-fundamentals/04-decision-trees/docs/en.md, phases/02-ml-fundamentals/05-support-vector-machines/docs/en.md, phases/02-ml-fundamentals/06-knn-and-distances/docs/en.md, phases/02-ml-fundamentals/14-naive-bayes/docs/en.md

| Model | Scale features | Wins on |
|---|---|---|
| Linear regression | yes | Baselines for every regression task |
| Trees and forests | no | Tabular data, mixed types, under 10k rows |
| SVM | yes | Small or high-dimensional sparse data |
| KNN | yes | Small data, up to about 20-50 features |
| Multinomial NB | no | Text with few training samples |
| Gaussian NB | no | Continuous features near a bell curve |

## Use each model when
type: tips
from: phases/02-ml-fundamentals/02-linear-regression/docs/en.md, phases/02-ml-fundamentals/03-logistic-regression/docs/en.md, phases/02-ml-fundamentals/04-decision-trees/docs/en.md, phases/02-ml-fundamentals/05-support-vector-machines/docs/en.md, phases/02-ml-fundamentals/06-knn-and-distances/docs/en.md, phases/02-ml-fundamentals/14-naive-bayes/docs/en.md

- Use linear regression as the baseline for every regression task.
- Use logistic regression for yes-or-no answers with probabilities and a linear boundary.
- Use a random forest for flat tables. It needs almost no hyperparameter tuning.
- Use an SVM for small data or sparse text with TF-IDF features.
- Use KNN when the data changes often and you want zero training time.
- Use TF-IDF with MultinomialNB for text with fewer than 10,000 training samples.
- Use BernoulliNB for short text. Set `binary=True` in CountVectorizer.

## Losses and formulas
type: concepts
from: phases/02-ml-fundamentals/02-linear-regression/docs/en.md, phases/02-ml-fundamentals/03-logistic-regression/docs/en.md, phases/02-ml-fundamentals/04-decision-trees/docs/en.md, phases/02-ml-fundamentals/05-support-vector-machines/docs/en.md, phases/02-ml-fundamentals/06-knn-and-distances/docs/en.md, phases/02-ml-fundamentals/14-naive-bayes/docs/en.md

- **MSE**: $\frac{1}{n} \sum (\hat{y} - y)^2$. The gradient for w is $\frac{2}{n} \sum (\hat{y} - y) x$.
- **R squared**: $1 - SS_{\text{res}} / SS_{\text{tot}}$. 1.0 is perfect. 0.0 equals the mean.
- **Sigmoid**: $\sigma(z) = 1 / (1 + e^{-z})$. At $z = 0$ it gives 0.5.
- **Binary cross-entropy**: $-\frac{1}{n} \sum (y \log p + (1-y) \log(1-p))$. Gradient $\frac{1}{n} \sum (p - y) x$.
- **Gini**: $1 - \sum_k p_k^2$. 6 cats and 4 dogs give 0.48.
- **Hinge**: $\max(0, 1 - y f(x))$. Zero beyond the margin.
- **RBF kernel**: $\exp(-\gamma \lVert x - z \rVert^2)$. Near 1 for close points.
- **Multinomial NB**: $(\text{count} + \alpha) / (\text{total} + \alpha \cdot V)$, summed in log space.

## Scale, then fit
type: annotated-code
lang: python
from: phases/02-ml-fundamentals/05-support-vector-machines/docs/en.md, phases/02-ml-fundamentals/06-knn-and-distances/docs/en.md, phases/02-ml-fundamentals/14-naive-bayes/docs/en.md

```python
clf = Pipeline([
    ("scaler", StandardScaler()),                       # SVM and KNN need it
    ("svm", SVC(kernel="rbf", C=1.0, gamma="scale")),   # dual form, kernels
])
clf.fit(X_train, y_train)
clf.score(X_test, y_test)                               # accuracy
clf['svm'].n_support_                                   # support vectors
("svm", LinearSVC(C=1.0, max_iter=10000))               # large data, primal
("knn", KNeighborsClassifier(n_neighbors=5, metric="euclidean"))
mnb = MultinomialNB(alpha=1.0)                          # counts, no scaling
mnb.fit(X_train_counts, y_train)
```

## Grow a random forest
type: flow
from: phases/02-ml-fundamentals/04-decision-trees/docs/en.md, phases/02-ml-fundamentals/04-decision-trees/code/trees.py

1. **Bootstrap**: sample rows with replacement. About 63% of rows appear.
2. **Out-of-bag**: the other rows can validate the tree.
3. **Feature subset**: each split sees $\sqrt{n_{\text{features}}}$ features for classification.
4. **Greedy split**: pick the feature and threshold with the highest information gain.
5. **Stop**: a pure node or a pre-pruning limit ends the branch.
6. **Repeat**: build `n_trees` trees. The default is 100.
7. **Aggregate**: majority vote for classes, average for regression.

## Knobs that trade bias and variance
type: command-table
from: phases/02-ml-fundamentals/05-support-vector-machines/docs/en.md, phases/02-ml-fundamentals/06-knn-and-distances/docs/en.md, phases/02-ml-fundamentals/04-decision-trees/docs/en.md, phases/02-ml-fundamentals/14-naive-bayes/docs/en.md, phases/02-ml-fundamentals/02-linear-regression/docs/en.md

| Command | What it does |
|---|---|
| Large `C` | Narrow margin, fewer misclassifications. Overfits |
| Small `C` | Wide margin, more violations. Underfits |
| `K = 1` | Zero training error. High variance |
| `K = N` | Predicts the majority class. Maximum bias |
| Max depth | Stops the tree early. Pre-pruning |
| NB `alpha` | Higher alpha gives stronger smoothing |
| Ridge $\lambda$ | Higher gives smaller weights |
| SVR $\epsilon$ | Wider tube, fewer support vectors |

## Defaults in the lesson code
type: defaults
from: phases/02-ml-fundamentals/04-decision-trees/code/trees.py, phases/02-ml-fundamentals/04-decision-trees/docs/en.md, phases/02-ml-fundamentals/06-knn-and-distances/code/knn.py, phases/02-ml-fundamentals/06-knn-and-distances/docs/en.md, phases/02-ml-fundamentals/05-support-vector-machines/code/svm.py, phases/02-ml-fundamentals/14-naive-bayes/code/naive_bayes.py, phases/02-ml-fundamentals/14-naive-bayes/docs/en.md

| Setting | Default | Note |
|---|---|---|
| Tree `max_depth` | None | Grows until every leaf is pure |
| Tree `min_samples_split` | 2 | A pre-pruning control |
| Tree `criterion` | "gini" | Gini and entropy split almost the same |
| Forest `n_trees` | 100 | scikit-learn uses `n_estimators=100` |
| Forest `max_features` | "sqrt" | Regression uses n_features/3 |
| KNN `k` | 5 | Start near sqrt(N). Odd K for binary |
| SVM `rbf_kernel` gamma | 0.5 | `polynomial_kernel` degree 3 |
| GaussianNB `var_smoothing` | 1e-9 | Stops division by zero variance |

## Failures and fixes
type: troubleshooting
from: phases/02-ml-fundamentals/03-logistic-regression/docs/en.md, phases/02-ml-fundamentals/04-decision-trees/docs/en.md, phases/02-ml-fundamentals/05-support-vector-machines/docs/en.md, phases/02-ml-fundamentals/06-knn-and-distances/docs/en.md, phases/02-ml-fundamentals/14-naive-bayes/docs/en.md

| Symptom | Cause | Fix |
|---|---|---|
| Logistic fails on circles | The boundary is always linear | Add polynomial features |
| SVM accuracy is poor | Unscaled features distort the margin | `StandardScaler` in a `Pipeline` |
| `SVC` too slow | Dual form is $O(n^2)$ to $O(n^3)$ | `LinearSVC` primal form |
| KNN degrades with many features | Curse of dimensionality | PCA or UMAP first |
| One tree changes with the data | A single tree is high variance | Use a random forest |
| MDI ranks a noise feature high | Bias to high cardinality | Permutation importance |
| NB gives probability 0 | Unseen word in a class | Laplace smoothing, alpha 1 |
| MultinomialNB rejects features | Negative feature values | GaussianNB or shift values |

## Questions
type: qa
from: phases/02-ml-fundamentals/02-linear-regression/docs/en.md, phases/02-ml-fundamentals/03-logistic-regression/docs/en.md, phases/02-ml-fundamentals/04-decision-trees/docs/en.md, phases/02-ml-fundamentals/05-support-vector-machines/docs/en.md, phases/02-ml-fundamentals/14-naive-bayes/docs/en.md

- **Why not MSE for logistic regression?** With a sigmoid, MSE is non-convex. Binary cross-entropy is convex.
- **Why does NB work with a wrong assumption?** Classification needs correct rankings, not correct probabilities.
- **Why does a forest beat one tree?** Averaging decorrelated trees reduces variance without more bias.
- **Why do only support vectors count?** Points beyond the margin have zero hinge loss.
- **NB or logistic regression?** Start with NB. Switch when data is large and NB plateaus.
- **Normal equation or gradient descent?** Normal equation for small data. Gradient descent for large data.
- **Do I trust NB probabilities?** No. Use `CalibratedClassifierCV` with `cv=5`.

## From-scratch classes
type: task-table
from: phases/02-ml-fundamentals/02-linear-regression/code/linear_regression.py, phases/02-ml-fundamentals/03-logistic-regression/code/logistic_regression.py, phases/02-ml-fundamentals/04-decision-trees/code/trees.py, phases/02-ml-fundamentals/05-support-vector-machines/code/svm.py, phases/02-ml-fundamentals/14-naive-bayes/code/naive_bayes.py

| Task | Code |
|---|---|
| Closed-form line | `LinearRegressionNormal()` |
| Node impurity | `gini_impurity(labels)` |
| Kernel value | `rbf_kernel(x, z, gamma=0.5)` |
| Batch hinge loss | `hinge_loss(X, y, w, b)` |
| Text classifier | `MultinomialNB(alpha=1.0)` |
Code and artifacts 1
What you take away

Saved in your notebook on this device.

Sources and limits

Reading checkpoints are self-reported. Test results are recorded separately and apply to the executed cases.

AI Engineering from Scratch · 3f9715c · MIT

Download this file ↓