Start here · How to use this guide
A field guide to the algorithms you'll actually meet
Every entry here follows the same dissection: the idea in plain English, the maths derived from first principles rather than just stated, how it works step by step, and an honest set of strengths and weaknesses.
Pick a family below, or use the index on the left. Each specimen is colour-tagged by family, so as you move through the guide the colour itself tells you what kind of problem you're looking at.
REG-01 · Regression
Simple Linear Regression
Fitting the best straight line through one predictor and one outcome.
“Standard Definition
Simple linear regression is a statistical technique that models the relationship between one independent variable and one continuous dependent variable by fitting the straight line that minimises the sum of squared vertical distances between the line and the observed data points.
The Idea
You have one input x and one continuous output y, and you believe the relationship between them is roughly a straight line. Simple linear regression finds the specific line that fits the data best, in the sense of minimising the total squared vertical distance between the line and every point.
The Maths
The model is:
$$y = b_0 + b_1 x + \varepsilon$$
where b0 is the intercept, b1 is the slope, and ε is irreducible noise. We choose b0, b1 by minimising the Ordinary Least Squares (OLS) cost function:
$$J(b_0,b_1)=\sum_{i=1}^{n}\left(y_i-(b_0+b_1x_i)\right)^2$$
Taking partial derivatives and setting both to zero (the normal equations):
$$\frac{\partial J}{\partial b_1}=-2\sum x_i(y_i-b_0-b_1x_i)=0 \qquad \frac{\partial J}{\partial b_0}=-2\sum (y_i-b_0-b_1x_i)=0$$
Solving this pair of equations gives closed-form estimates:
$$b_1=\frac{\sum(x_i-\bar{x})(y_i-\bar{y})}{\sum(x_i-\bar{x})^2}=\frac{\text{Cov}(x,y)}{\text{Var}(x)} \qquad b_0=\bar{y}-b_1\bar{x}$$
How It Works
- Compute the mean of
x and y.
- Compute the covariance of
x and y, and the variance of x.
- Plug both into the closed-form formulas above to get
b0 and b1 directly, no iteration needed.
Strengths
- Fully interpretable:
b1 is literally "change in y per unit of x".
- Closed-form solution, instant to fit.
- A great sanity-check baseline before trying anything fancier.
Weaknesses
- Only captures a linear relationship.
- Very sensitive to outliers (squared error punishes big misses heavily).
- Assumes constant error variance (homoscedasticity) and independent, normally-distributed residuals for valid inference.
When to use it: exactly one predictor, and a scatter plot that already looks roughly like a line.
Five students report hours studied (x) and their exam score (y):
| x (hours) | 1 | 2 | 3 | 4 | 5 |
|---|
| y (score) | 52 | 58 | 65 | 68 | 80 |
|---|
Step 1, the means: $\bar{x}=3$, $\bar{y}=64.6$.
Step 2, deviations and their product (needed for the covariance):
| x-x̄ | -2 | -1 | 0 | 1 | 2 |
|---|
| y-ȳ | -12.6 | -6.6 | 0.4 | 3.4 | 15.4 |
|---|
| product | 25.2 | 6.6 | 0 | 3.4 | 30.8 |
|---|
Sum of products = 66.0. Sum of $(x-\bar{x})^2$ = 10.
Step 3, solve for the slope and intercept:
$$b_1=\frac{66.0}{10}=6.6 \qquad b_0=64.6-6.6(3)=44.8$$
So the fitted line is $y=44.8+6.6x$. Predicting for a student who studies 6 hours: $y=44.8+6.6(6)=84.4$.
Checking the fit on the training data itself (predicted vs actual): 51.4 vs 52, 58.0 vs 58, 64.6 vs 65, 71.2 vs 68, 77.8 vs 80. Summing the squared residuals gives 15.6, against a total variance of 451.2, so $R^2 = 1-15.6/451.2 = 0.965$, the line explains 96.5% of the variation in exam scores.
Result: each extra hour of study is associated with roughly 6.6 extra points, and the line explains 96.5% of the spread in scores.
REG-02 · Regression
Multiple Linear Regression
The same idea as simple linear regression, extended to many predictors at once.
“Standard Definition
Multiple linear regression is a statistical technique that models a continuous dependent variable as a linear combination of two or more independent variables, with coefficients estimated by minimising the total sum of squared residuals across all predictors simultaneously.
The Idea
Most real outcomes depend on more than one input. Multiple linear regression fits a hyperplane, rather than a line, across p predictors simultaneously, while still assuming the relationship is linear in the coefficients.
The Maths
In matrix form, with X as the design matrix (one column per feature, plus a column of 1s for the intercept):
$$y = X\beta + \varepsilon$$
Minimising the sum of squared residuals ‖y - Xβ‖² with respect to β and setting the gradient to zero:
$$\frac{\partial}{\partial \beta}\|y-X\beta\|^2 = -2X^T(y-X\beta)=0 \;\;\Longrightarrow\;\; X^TX\beta = X^Ty$$
giving the closed-form normal equation solution:
$$\hat{\beta} = (X^TX)^{-1}X^Ty$$
This requires X^TX to be invertible, which fails under perfect multicollinearity (see the Dummy Variable Trap entry in Foundations).
How It Works
- Build the design matrix
X, including an intercept column of 1s.
- Check for problematic collinearity between predictors.
- Solve the normal equation directly, or use QR/SVD decomposition for numerical stability on larger problems.
- Interpret each coefficient as "the effect of this feature, holding all other features constant".
Strengths
- Handles many predictors while staying fully interpretable.
- Closed-form, no hyperparameters to tune.
Weaknesses
- Sensitive to multicollinearity between predictors.
- Still assumes a linear relationship and additive effects.
- Outliers and non-constant error variance both distort the fit.
When to use it: several plausibly-linear predictors, and you want to understand each one's individual contribution.
Four houses, with size in square metres (x1), bedroom count (x2), and price in £1,000s (y):
| Size (x1) | 50 | 60 | 80 | 100 |
|---|
| Bedrooms (x2) | 1 | 2 | 3 | 3 |
|---|
| Price (y) | 150 | 180 | 240 | 260 |
|---|
Step 1: build the design matrix X with an intercept column of 1s, then compute $X^TX$ and $X^Ty$:
$$X^TX=\begin{bmatrix}4 & 290 & 9\\290 & 22500 & 710\\9 & 710 & 23\end{bmatrix} \qquad X^Ty=\begin{bmatrix}830\\63500\\2010\end{bmatrix}$$
Step 2: solve $\hat{\beta}=(X^TX)^{-1}X^Ty$, which gives:
$$\hat{\beta} = [\,58.67,\;\; 1.27,\;\; 25.33\,]$$
So the fitted model is price = 58.67 + 1.27·size + 25.33·bedrooms. Each extra square metre adds about £1,270 to the predicted price, and each extra bedroom adds about £25,330, holding the other predictor fixed.
Checking against the training rows: predicted prices are 147.3, 185.3, 236.0, 261.3 against actual 150, 180, 240, 260, residuals of just 2.7, -5.3, 4.0, and -1.3.
Result: a fifth house of 70 sqm with 2 bedrooms would be predicted at $58.67+1.27(70)+25.33(2) = 58.67+88.9+50.66 = \pounds198,230$.
REG-03 · Regression
Polynomial Regression
Fitting a curve using the same linear machinery, just with extra engineered columns.
“Standard Definition
Polynomial regression is a form of regression analysis in which the relationship between the independent variable and the dependent variable is modelled as an nth-degree polynomial, while the model remains linear in its coefficients.
The Idea
When the relationship between x and y is visibly curved rather than straight, we don't need a new algorithm, we just feed the linear regression machinery extra columns: x², x³, and so on. The model is still linear in its coefficients, only the input features are non-linear transformations of x.
The Maths
$$y = b_0 + b_1x + b_2x^2 + \dots + b_nx^n + \varepsilon$$
Because this is linear in b0...bn, it's fitted with exactly the same normal equation as multiple linear regression, once you build the design matrix as [1, x, x², ..., xⁿ]:
$$\hat{\beta} = (X^TX)^{-1}X^Ty$$
How It Works
- Generate polynomial feature columns up to degree
n.
- Fit ordinary least squares on this expanded feature set.
- Choose
n using cross-validation, since it directly controls the bias-variance tradeoff.
Strengths
- Captures curvature without leaving the linear-regression toolbox.
- Degree
n gives direct, dial-like control over flexibility.
Weaknesses
- Extrapolation is dangerous, the curve can shoot off wildly just outside the training range.
- High degrees overfit and oscillate wildly between points (Runge's phenomenon).
When to use it: one or two features with an obviously curved, but still smooth, relationship to the target.
Consider this data:
A straight line clearly won't fit this: the jump from x=4 to x=5 (+9) is much bigger than from x=1 to x=2 (+3), the growth itself is accelerating. Fitting y=b0+b1x by OLS would leave large, systematically curved residuals.
Instead, fit y=b0+b1x+b2x² by building the design matrix [1, x, x²] and solving the same normal equation as multiple linear regression. Solving it here gives, exactly:
$$b_0=1,\qquad b_1=0,\qquad b_2=1 \;\;\Longrightarrow\;\; y=1+x^2$$
Checking: at x=1, $1+1=2$✓. At x=4, $1+16=17$✓. At x=5, $1+25=26$✓. Every point matches exactly, this data was generated by $y=x^2+1$, and the degree-2 polynomial recovers that relationship perfectly, something no straight line could do.
Result: predicting at x=6 gives $y=1+36=37$, but be cautious: this is extrapolation, and polynomial curves can behave wildly just outside the fitted range.
REG-04 · Regression
Support Vector Regression (SVR)
Fit a tube around the data, and only worry about points that fall outside it.
“Standard Definition
Support Vector Regression is a regression technique that fits a function so that all training points lying within a specified margin (epsilon) of the function incur zero loss, penalising only the points that fall outside that margin, while keeping the fitted function as flat as possible.
The Idea
Instead of trying to make every prediction as close as possible to the truth, SVR draws a tube of width 2ε around the fitted function and simply doesn't penalise any point that falls inside it. Only points outside the tube contribute to the loss, and the fitted function is chosen to be as flat as possible subject to that constraint.
The Maths
The optimisation problem (soft margin, allowing some points outside the tube via slack variables ξ, ξ*):
$$\min_{w,b}\; \tfrac{1}{2}\|w\|^2 + C\sum_i(\xi_i+\xi_i^*)$$
$$\text{subject to } \; y_i-(w\cdot x_i+b)\le \varepsilon+\xi_i, \quad (w\cdot x_i+b)-y_i\le \varepsilon+\xi_i^*, \quad \xi_i,\xi_i^*\ge 0$$
This is the ε-insensitive loss: L(y, f(x)) = max(0, |y - f(x)| - ε). The problem is convex and solved via Lagrangian duality, which also opens the door to the kernel trick (see Kernel SVM) for non-linear SVR.
How It Works
- Choose a kernel (linear, polynomial, RBF) if the relationship is non-linear.
- Tune
C (how much to penalise points outside the tube) and ε (tube width).
- Solve the dual quadratic programming problem to find the support vectors, the points that actually define the tube's boundary.
Strengths
- Naturally robust to small errors, points inside the tube are simply ignored.
- The kernel trick lets it fit non-linear relationships.
Weaknesses
- Doesn't scale comfortably to very large datasets.
- Needs careful feature scaling and hyperparameter tuning (
C, ε, kernel parameters).
When to use it: moderate-sized datasets where you want robustness to small noisy errors and possibly a non-linear fit.
Suppose SVR has already fitted the line $f(x)=2x$ with an epsilon-tube of width $\varepsilon=0.5$. Six new observations arrive:
| x | 1 | 2 | 3 | 4 | 5 | 6 |
|---|
| y (actual) | 2.1 | 3.9 | 6.2 | 7.8 | 10.3 | 13.5 |
|---|
| f(x) | 2 | 4 | 6 | 8 | 10 | 12 |
|---|
| |y-f(x)| | 0.1 | 0.1 | 0.2 | 0.2 | 0.3 | 1.5 |
|---|
For each point, the epsilon-insensitive loss is $L=\max(0,|y-f(x)|-\varepsilon)$. For the first five points, $|y-f(x)|$ never exceeds $\varepsilon=0.5$, so every one of them incurs zero loss, they're inside the tube and simply ignored, even though none of them sit exactly on the line.
The sixth point has $|13.5-12|=1.5$, which exceeds $\varepsilon=0.5$ by $1.5-0.5=1.0$. This point becomes a support vector with slack $\xi=1.0$, and contributes $C\times 1.0$ to the objective, pulling the fitted line to account for it.
Result: five of the six points are "free" (zero loss inside the tube); only the outlier at x=6 actually influences the fit, which is exactly the robustness SVR is designed to provide.
REG-05 · Regression
Decision Tree Regression
Carving the feature space into boxes, and predicting the average value inside each one.
“Standard Definition
Decision tree regression is a non-parametric method that predicts a continuous target by recursively partitioning the feature space into regions, and assigning each region the mean of the training targets that fall within it.
The Idea
A decision tree repeatedly asks yes/no questions about the features ("is x1 < 5?") to split the data into increasingly pure regions, then predicts the mean target value of whichever region a new point lands in.
The Maths
At every node, the algorithm searches over every feature j and threshold s to find the split that minimises the combined squared error of the two resulting regions:
$$\min_{j,s}\left[\sum_{x_i\in R_1(j,s)}(y_i-\bar{y}_{R_1})^2 + \sum_{x_i\in R_2(j,s)}(y_i-\bar{y}_{R_2})^2\right]$$
This is applied recursively to each child region until a stopping rule is met (maximum depth, minimum samples per leaf). The prediction at a leaf is simply the mean of the training targets that landed there.
How It Works
- Start with all data in one root node.
- Find the single best (feature, threshold) split that most reduces squared error.
- Split the data into two child nodes, and repeat recursively.
- Stop by depth limit or minimum leaf size; predict using the leaf's mean.
Strengths
- Captures non-linear relationships and feature interactions automatically.
- No feature scaling required.
- Fully interpretable, you can literally draw the tree.
Weaknesses
- Prone to overfitting (high variance) if grown too deep.
- Unstable, a small change in data can produce a very different tree.
- Predictions are step-functions and cannot extrapolate beyond the training range.
When to use it: when you want an interpretable non-linear model, or as the building block for Random Forest below.
Four houses by size (x) and price in £1,000s (y):
| Size (x) | 30 | 50 | 70 | 90 |
|---|
| Price (y) | 100 | 150 | 140 | 200 |
|---|
With no split, the parent's prediction is the overall mean, 147.5, giving a total squared error of 5,075. The algorithm searches every candidate threshold:
| Split at | Left group | Right group | Weighted SSE | Reduction |
| x = 40 | {30} | {50,70,90} | 2,067.3 | 3,007.7 |
| x = 60 | {30,50} | {70,90} | 3,050.0 | 2,025.0 |
| x = 80 | {30,50,70} | {90} | 1,400.0 | 3,675.0 |
The split at x=80 gives the largest reduction in squared error (3,675, the biggest drop from the parent's 5,075), so the tree chooses it: houses under 80 sqm go left (predicted price = mean of 100, 150, 140 = 130), houses at 80 sqm or above go right (predicted price = 200, since it's alone in that leaf).
Result: a new 75 sqm house would be predicted at £130,000; a 95 sqm house would be predicted at £200,000.
REG-06 · Regression
Random Forest Regression
Many imperfect trees, averaged, are more reliable than one perfect-looking tree.
“Standard Definition
Random forest regression is an ensemble method that trains many decision trees on bootstrap-resampled versions of the training data, each considering only a random subset of features at every split, and predicts by averaging all the trees' outputs.
The Idea
A single decision tree overfits easily. Random Forest trains many trees on different random samples of the data (and different random subsets of features at each split), then averages their predictions, trading a little bias for a large reduction in variance.
The Maths
Bagging: draw B bootstrap samples (sampling with replacement) from the training data, train a tree T_b on each, and predict with the average:
$$\hat{y}(x)=\frac{1}{B}\sum_{b=1}^{B}T_b(x)$$
The reason this helps is variance reduction. For B trees with pairwise correlation ρ and individual variance σ², the variance of their average is:
$$\text{Var}\left(\frac{1}{B}\sum T_b\right) = \rho\sigma^2 + \frac{1-\rho}{B}\sigma^2$$
Averaging alone (bagging) shrinks the second term, but the first term, driven by correlation between trees, remains. Random Forest additionally restricts each split to consider only a random subset of m < p features, which decorrelates the trees (lowers ρ) and drives the variance down further than bagging alone.
How It Works
- For each of
B trees: draw a bootstrap sample of the training rows.
- Grow the tree, but at each split only consider a random subset of features.
- Average all
B trees' predictions for the final output.
Strengths
- Much lower variance than a single tree, strong general-purpose accuracy.
- Provides feature importance essentially for free.
Weaknesses
- Loses the single-tree's easy interpretability.
- Slower to predict with, since every tree must be evaluated.
- Still can't extrapolate meaningfully beyond the training data's range.
When to use it: your default, hard-to-beat baseline for tabular regression problems.
With 5 training rows (indices 0-4), one bootstrap draw (sampling with replacement, 5 draws) might land on indices [4, 1, 3, 3, 4]. That means:
- Rows 1, 3, and 4 are used to grow this particular tree (row 3 and row 4 are each drawn twice, so they get extra weight in this tree).
- Rows 0 and 2 were never drawn, they are this tree's out-of-bag (OOB) sample, and can be used to validate this specific tree "for free".
Now suppose the forest has grown 5 such trees, and for a new test house they each predict a price (in £1,000s):
| Tree 1 | Tree 2 | Tree 3 | Tree 4 | Tree 5 |
|---|
| 210 | 225 | 198 | 230 | 215 |
The forest's final prediction is simply the average: $(210+225+198+230+215)/5 = 215.6$.
Result: the forest predicts £215,600, smoothing out the disagreement between individual trees (which ranged from £198,000 to £230,000) into a single, lower-variance estimate.
CLF-01 · Classification
Logistic Regression
Squashing a straight line through an S-curve to predict a probability.
“Standard Definition
Logistic regression is a statistical classification method that models the probability of a binary outcome as a sigmoid function applied to a linear combination of the input features, with parameters estimated by maximising the likelihood of the observed labels.
The Idea
We want to predict a probability between 0 and 1, but a straight line runs off to ±∞. Logistic regression fixes this by fitting a linear combination of features, then passing it through the sigmoid function, which squashes any real number into the (0,1) range.
The Maths
$$p(y=1\mid x)=\sigma(z)=\frac{1}{1+e^{-z}}, \qquad z = b_0+b_1x_1+\dots+b_px_p$$
Rearranging shows why it's called "logistic": the log-odds (logit) of the outcome is exactly linear in the features:
$$\log\left(\frac{p}{1-p}\right) = z$$
Unlike linear regression, there's no closed-form solution. Coefficients are found by maximising the likelihood of the observed labels, equivalently minimising the binary cross-entropy loss:
$$L(b) = -\sum_{i=1}^{n}\Big[y_i\log(p_i)+(1-y_i)\log(1-p_i)\Big]$$
This is minimised numerically (gradient descent, or Newton's method / IRLS), using the gradient with respect to each weight:
$$\frac{\partial L}{\partial b_j}=\sum_i (p_i-y_i)\,x_{ij}$$
How It Works
- Initialise weights (often at zero).
- Compute predicted probabilities via the sigmoid.
- Compute the gradient of the cross-entropy loss and update the weights.
- Repeat until convergence; classify using a threshold (usually 0.5) on the output probability.
Strengths
- Outputs a genuinely interpretable, calibrated probability.
- Coefficients read directly as log-odds ratios.
- Fast, and a strong, sensible baseline for classification.
Weaknesses
- Assumes a linear decision boundary in log-odds space.
- Struggles with complex non-linear relationships unless features are engineered first.
- Sensitive to strong class imbalance.
When to use it: binary (or multiclass, via softmax) classification where interpretable probabilities matter.
Four students, hours studied (x) and whether they passed (y):
| x (hours) | 1 | 2 | 3 | 4 |
|---|
| y (passed) | 0 | 0 | 1 | 1 |
|---|
Step 1: initialise both weights at zero, $b_0=0, b_1=0$. Every prediction starts at $\sigma(0)=0.5$, total ignorance.
Step 2: compute the gradient of the cross-entropy loss, $\partial L/\partial b_j=\sum_i(p_i-y_i)x_{ij}$. With every $p_i=0.5$:
$$\frac{\partial L}{\partial b_0}=\sum(p_i-y_i)=(0.5-0)+(0.5-0)+(0.5-1)+(0.5-1)=0$$
$$\frac{\partial L}{\partial b_1}=\sum(p_i-y_i)x_i=0.5(1)+0.5(2)-0.5(3)-0.5(4)=-2$$
Step 3: take one gradient descent step with learning rate 0.1: $b_1 \leftarrow 0 - 0.1(-2) = 0.2$; $b_0$ stays at 0 (its gradient was zero).
Recomputing probabilities with the updated $b_1=0.2$: $\sigma(0.2\times1)=0.550$, $\sigma(0.4)=0.599$, $\sigma(0.6)=0.646$, $\sigma(0.8)=0.690$.
Result: after just one step, predicted pass-probability already climbs with hours studied (0.55 → 0.60 → 0.65 → 0.69). Repeating this update hundreds of times is exactly how logistic regression is actually trained.
CLF-02 · Classification
K-Nearest Neighbours (KNN)
You are who your neighbours are: classify by majority vote of the closest points.
“Standard Definition
K-Nearest Neighbours is a non-parametric, instance-based classification method that assigns a new observation the majority class among its k closest points in the training data, according to a chosen distance metric.
The Idea
KNN has no real "training" phase. To classify a new point, it simply looks at the k closest points in the training data and takes a majority vote of their labels. It's often called a "lazy learner" because all the work happens at prediction time.
The Maths
Distance is usually Euclidean, though other metrics generalise this via the Minkowski distance:
$$d(x,x')=\left(\sum_{i=1}^{n}|x_i-x_i'|^p\right)^{1/p}$$
(p=2 gives Euclidean distance, p=1 gives Manhattan distance.) The prediction rule is simply:
$$\hat{y} = \text{mode}\{y_i : x_i \in N_k(x)\}$$
where N_k(x) is the set of k training points closest to x. Choosing k is a direct bias-variance decision: small k gives low bias but high variance (it overfits to noise); large k gives high bias but low variance (it oversmooths the boundary).
How It Works
- Store the training data (that's the entire "training" step).
- At prediction time, compute the distance from the new point to every training point.
- Take the
k closest, and predict the majority class among them.
Strengths
- Extremely simple, with no training phase.
- Naturally handles multi-class problems and non-linear boundaries.
Weaknesses
- Expensive at prediction time, especially with large datasets.
- Suffers badly from the curse of dimensionality: distances become less meaningful as dimensions grow.
- Requires careful feature scaling, since large-scale features dominate the distance calculation.
When to use it: smaller, lower-dimensional datasets, or as a quick non-linear baseline.
Six labelled points, and a new point to classify at (4,4), using $k=3$:
| Point | (1,2) | (2,3) | (3,3) | (6,6) | (7,7) | (8,6) |
|---|
| Class | A | A | A | B | B | B |
|---|
Compute the Euclidean distance from (4,4) to every point:
| Point | (1,2) | (2,3) | (3,3) | (6,6) | (7,7) | (8,6) |
|---|
| Distance | 3.61 | 2.24 | 1.41 | 2.83 | 4.24 | 4.47 |
|---|
Sorted by distance: (3,3) at 1.41 [A], (2,3) at 2.24 [A], (6,6) at 2.83 [B], (1,2) at 3.61 [A], (7,7) at 4.24 [B], (8,6) at 4.47 [B].
The 3 nearest neighbours are (3,3), (2,3), and (6,6), classes A, A, B. That's a 2-to-1 majority for A, even though the third-nearest neighbour is actually from class B.
Result: the new point (4,4) is classified as A. Note that with $k=1$ it would also be A, but with $k=5$ the vote becomes 3 B's vs 2 A's, flipping the answer, which is exactly why choosing $k$ matters.
CLF-03 · Classification
Support Vector Machine (SVM)
Don't just separate the classes, separate them by the widest possible margin.
“Standard Definition
A Support Vector Machine is a supervised classification method that finds the hyperplane separating two classes with the maximum possible margin, a boundary determined entirely by the closest points from each class, known as the support vectors.
The Idea
Many lines can separate two linearly-separable classes. SVM specifically finds the one that maximises the distance (the "margin") to the closest points of either class, those closest points are the support vectors, and they alone determine the boundary.
The Maths
For a hyperplane w·x + b = 0, the margin width is 2/‖w‖. Maximising the margin is equivalent to minimising ‖w‖, subject to every point being correctly classified with room to spare:
$$\min_{w,b}\;\tfrac{1}{2}\|w\|^2 \quad \text{s.t.} \quad y_i(w\cdot x_i+b)\ge 1 \;\;\forall i$$
Real data usually isn't perfectly separable, so the soft margin version allows some violations via slack variables ξ_i, penalised by a cost C:
$$\min_{w,b}\;\tfrac{1}{2}\|w\|^2+C\sum_i\xi_i \quad \text{s.t.}\quad y_i(w\cdot x_i+b)\ge 1-\xi_i,\;\; \xi_i\ge 0$$
Solved via Lagrangian duality, the dual problem depends on the data only through pairwise dot products x_i · x_j, which is precisely what makes the kernel trick (see Kernel SVM) possible.
How It Works
- Solve the convex quadratic optimisation problem (dual form) for the Lagrange multipliers
α_i.
- Points with
α_i > 0 are the support vectors, everything else can be discarded.
- Classify new points using the sign of
w·x + b.
Strengths
- Effective in high-dimensional spaces.
- Margin maximisation tends to generalise well.
Weaknesses
- Doesn't scale comfortably to very large datasets.
- No probability output natively (needs extra calibration).
- Performance is sensitive to the choice of
C.
When to use it: classification with a reasonably clear margin between classes, especially in high-dimensional data.
Class +1 has points (2,2) and (3,3); Class −1 has points (0,0) and (1,0).
Step 1: find the closest pair of points across the two classes. Checking all pairs, the closest is (2,2) and (1,0), at distance $\sqrt{(2-1)^2+(2-0)^2}=\sqrt5=2.236$.
Step 2: for two well-separated point clusters, the maximum-margin hyperplane is the perpendicular bisector of the segment joining the closest pair. The midpoint of (2,2) and (1,0) is (1.5, 1), and the direction between them is (1,2), giving the unit normal vector $\hat{w}=(0.447, 0.894)$ and intercept $b=-1.565$.
Step 3: verify the other two points aren't closer to this boundary than the pair we used. Signed distances: (2,2) → +1.118, (1,0) → -1.118 (these two are the support vectors, sitting exactly on the margin), (3,3) → +2.460, (0,0) → -1.565. Both are further from the boundary than the margin, so they don't violate it.
Result: the maximum margin is $2\times1.118=2.236$ wide (matching the full distance between the two support vectors), and only (2,2) and (1,0) actually define the boundary, (3,3) and (0,0) could be deleted entirely without changing the decision boundary at all.
CLF-04 · Classification
Kernel SVM
Bend space itself so a straight cut becomes a curved boundary.
“Standard Definition
Kernel SVM is an extension of the Support Vector Machine that uses a kernel function to implicitly map data into a higher-dimensional feature space, so that a linear separator in that space corresponds to a non-linear decision boundary back in the original space.
The Idea
Plain SVM only draws straight lines. Kernel SVM handles classes that can't be separated by any straight line by implicitly mapping the data into a much higher-dimensional space, where a straight separator does exist, without ever actually computing that expensive mapping.
The Maths
Because the SVM dual problem only ever needs dot products x_i · x_j, we can replace that dot product with a kernel function K(x_i, x_j) = φ(x_i)·φ(x_j), computing the result as if the mapping φ had happened, without ever forming it:
$$\text{RBF: } K(x,x')=\exp(-\gamma\|x-x'\|^2) \qquad \text{Polynomial: } K(x,x')=(\gamma\, x\cdot x'+r)^d$$
Mercer's theorem guarantees that any symmetric, positive semi-definite function K corresponds to a genuine dot product in some feature space, which is why this substitution is mathematically valid rather than just a convenient hack. The final decision function becomes:
$$f(x)=\text{sign}\left(\sum_i \alpha_i y_i K(x_i,x)+b\right)$$
How It Works
- Pick a kernel (RBF is the common default) and its hyperparameters (e.g.
γ).
- Solve the same dual optimisation as linear SVM, but with
K(x_i,x_j) replacing every dot product.
- Classify new points by evaluating the kernel against the stored support vectors.
Strengths
- Captures genuinely non-linear class boundaries.
- Still built on a convex, globally-solvable optimisation problem.
Weaknesses
- More hyperparameters (kernel choice,
γ, C) to tune carefully.
- Loses interpretability entirely.
- Can overfit badly with a poorly-chosen kernel or parameters.
When to use it: classification problems where the boundary is clearly non-linear.
The classic case a linear SVM cannot handle at all: the XOR pattern.
| Point (x1,x2) | (1,1) | (-1,-1) | (1,-1) | (-1,1) |
|---|
| Class | +1 | +1 | -1 | -1 |
|---|
Plot these four points: the two +1's sit in opposite corners, and so do the two -1's. No straight line in this 2D plane can separate them, whichever line you draw, it will always have one point of each class on both sides.
Now apply the simple feature map $\phi(x_1,x_2)=(x_1,x_2,x_1x_2)$, which is exactly the kind of combination a degree-2 polynomial kernel captures. Compute the new third coordinate, $x_1x_2$, for every point:
| Point | (1,1) | (-1,-1) | (1,-1) | (-1,1) |
|---|
| x1·x2 | +1 | +1 | -1 | -1 |
|---|
| Class | +1 | +1 | -1 | -1 |
|---|
Result: the sign of $x_1x_2$ alone perfectly separates the two classes. A single extra, non-linear coordinate, exactly what a polynomial kernel provides implicitly, turns an impossible 2D problem into a trivial one.
CLF-05 · Classification
Naive Bayes
Assume every feature acts independently, then let Bayes' theorem do the rest.
“Standard Definition
Naive Bayes is a family of probabilistic classifiers based on applying Bayes' theorem under the "naive" assumption that every feature is conditionally independent of every other feature, given the class label.
The Idea
Naive Bayes is a generative classifier: it models how each class produces its features, then inverts that with Bayes' theorem to find the most probable class given the observed features. The "naive" part is assuming every feature is conditionally independent of every other, given the class.
The Maths
Starting from Bayes' theorem and dropping the class-independent denominator, the decision rule (Maximum A Posteriori) is:
$$\hat{y} = \arg\max_{y}\; P(y)\prod_{i=1}^{n}P(x_i\mid y)$$
computed in log-space for numerical stability:
$$\hat{y} = \arg\max_{y}\left[\log P(y) + \sum_{i=1}^{n}\log P(x_i\mid y)\right]$$
The likelihood P(x_i | y) takes a different shape depending on the feature type: Gaussian (continuous features), Multinomial (word counts), or Bernoulli (binary features). Zero-frequency likelihoods are handled with Laplace smoothing, derived from a Dirichlet prior over the class-conditional distribution:
$$P(x_i\mid y=c) = \frac{\text{count}(x_i,c)+\alpha}{\text{count}(c)+\alpha\cdot|\text{features}|}$$
How It Works
- Estimate the class priors and per-feature likelihoods directly by counting.
- Apply Laplace smoothing so no probability is ever exactly zero.
- For a new point, compute the log-posterior score for every class and pick the largest.
Strengths
- Extremely fast to train, just counting, no optimisation loop.
- Performs very well on high-dimensional, sparse data like text.
Weaknesses
- The independence assumption is almost always technically false.
- Probability outputs are poorly calibrated, often overconfident.
Want the full derivation? Every step here, including a hand-worked spam classification example and the proof that Gaussian Naive Bayes reduces to a linear decision boundary, is in the standalone Naive Bayes deep-dive from earlier in this series.
Vocabulary: {offer, money, meeting, project}. Three spam emails contain "offer" 4 times and "money" 4 times in total (8 words); three ham emails contain "meeting" 4 times and "project" 3 times in total (7 words). Priors: $P(\text{spam})=P(\text{ham})=0.5$.
Classify the email "offer meeting", using Laplace smoothing ($\alpha=1$, vocabulary size 4):
$$P(\text{offer}\mid\text{spam})=\frac{4+1}{8+4}=0.417 \qquad P(\text{meeting}\mid\text{spam})=\frac{0+1}{8+4}=0.083$$
$$P(\text{offer}\mid\text{ham})=\frac{0+1}{7+4}=0.091 \qquad P(\text{meeting}\mid\text{ham})=\frac{4+1}{7+4}=0.455$$
Score for spam: $0.5\times0.417\times0.083=0.0174$. Score for ham: $0.5\times0.091\times0.455=0.0207$.
Result: ham wins, despite "offer" being a strong spam signal, "meeting" is an even stronger ham signal, and Naive Bayes correctly weighs both rather than fixating on just one word.
CLF-06 · Classification
Decision Tree Classification
The same recursive splitting as tree regression, but scored by class purity instead of variance.
“Standard Definition
Decision tree classification is a non-parametric method that predicts a categorical target by recursively splitting the feature space to maximise the purity of the resulting groups, typically measured using Gini impurity or entropy.
The Idea
A classification tree asks a sequence of yes/no questions about the features, at each step choosing the split that makes the resulting groups as "pure" as possible (dominated by a single class), and predicts using the majority class in whichever leaf a point lands in.
The Maths
Purity is usually measured with the Gini index or entropy, for a node with class proportions p_k:
$$\text{Gini}=1-\sum_{k}p_k^2 \qquad \text{Entropy}=-\sum_k p_k\log_2 p_k$$
A split is chosen to maximise information gain, the reduction in impurity from parent to weighted children:
$$\text{Gain} = H(\text{parent}) - \sum_{\text{children}} \frac{n_{\text{child}}}{n_{\text{parent}}}H(\text{child})$$
How It Works
- At each node, evaluate every possible (feature, threshold) split and compute its information gain.
- Choose the split with the highest gain, and recurse on both children.
- Stop by depth or minimum leaf size; predict using the majority class at the leaf.
Strengths
- Fully interpretable, handles numerical and categorical features without preprocessing.
- No feature scaling required.
Weaknesses
- Prone to overfitting without pruning or depth limits.
- Unstable: small data changes can produce a very different tree.
- Information gain is biased toward features with many distinct values.
When to use it: when interpretability matters, or as a building block for Random Forest below.
A parent node has 10 samples: 6 of class A, 4 of class B. A candidate split produces a left child of 5 samples (all class A) and a right child of 5 samples (1 A, 4 B).
Parent impurity: $\text{Gini}=1-(0.6^2+0.4^2)=0.48$, $\text{Entropy}=-(0.6\log_2 0.6+0.4\log_2 0.4)=0.971$.
Left child (5A, 0B): perfectly pure, $\text{Gini}=0$, $\text{Entropy}=0$.
Right child (1A, 4B): $\text{Gini}=1-(0.2^2+0.8^2)=0.32$, $\text{Entropy}=-(0.2\log_2 0.2+0.8\log_2 0.8)=0.722$.
Weighted child impurity (each child is half the data): $\text{Gini}=0.5(0)+0.5(0.32)=0.16$, $\text{Entropy}=0.5(0)+0.5(0.722)=0.361$.
$$\text{Gini gain}=0.48-0.16=0.32 \qquad \text{Information gain}=0.971-0.361=0.610$$
Result: this split reduces Gini impurity by 0.32 and increases information by 0.610 bits, a strong candidate split, since it isolates a perfectly pure left leaf.
CLF-07 · Classification
Random Forest Classification
Bagging and feature-randomness, applied to classification trees, decided by majority vote.
“Standard Definition
Random forest classification is an ensemble method that trains many decision trees on bootstrap-resampled data with random feature subsets per split, and classifies a new observation by majority vote across all the trees.
The Idea
Exactly the same recipe as Random Forest Regression, many decision trees trained on bootstrap samples with random feature subsets at each split, except the final prediction is decided by majority vote instead of averaging.
The Maths
$$\hat{y}(x)=\text{mode}\{T_b(x)\}_{b=1}^{B}$$
Since each tree is trained on a bootstrap sample, roughly 1 - 1/e ≈ 63.2% of the rows are used, leaving about 36.8% of rows unseen by any given tree ((1-1/n)^n → e^{-1} as n grows). These out-of-bag (OOB) rows give a free, built-in estimate of generalisation error without needing a separate validation set. Feature importance is typically measured by the average impurity decrease a feature contributes across all trees, or by permutation importance (shuffle a feature's values and measure the resulting drop in accuracy).
How It Works
- Grow
B classification trees, each on a bootstrap sample with random feature subsets per split.
- Predict the majority vote across all trees.
- Use the out-of-bag rows to sanity-check generalisation performance for free.
Strengths
- Strong, robust general-purpose classifier.
- Built-in feature importance and OOB validation.
Weaknesses
- Much less interpretable than a single tree.
- Can be slow to predict with many deep trees.
When to use it: the default strong baseline for tabular classification problems.
A forest of 5 trees, each trained on a different bootstrap sample with a random feature subset, is asked to classify whether a new loan applicant will default:
| Tree 1 | Tree 2 | Tree 3 | Tree 4 | Tree 5 |
|---|
| No default | Default | No default | No default | Default |
Tallying the votes: "No default" gets 3 votes, "Default" gets 2 votes.
Result: the forest predicts No default by majority vote (3 to 2), even though two individual trees disagreed, a single overruled tree doesn't change the outcome, which is exactly the variance-reduction benefit over relying on any one tree alone.
CLU-01 · Clustering
K-Means Clustering
No labels, no problem: group points by how close they sit to each other.
“Standard Definition
K-Means clustering is an unsupervised algorithm that partitions a dataset into K clusters by iteratively assigning each point to its nearest centroid and updating each centroid to the mean of its assigned points, minimising the total within-cluster sum of squares.
The Idea
K-Means partitions unlabelled data into K groups by repeatedly assigning each point to its nearest centroid, then moving each centroid to the average of the points assigned to it, until nothing changes.
The Maths
The objective is to minimise the within-cluster sum of squares (WCSS):
$$J = \sum_{k=1}^{K}\sum_{x_i\in C_k}\|x_i-\mu_k\|^2$$
This is minimised via Lloyd's algorithm, alternating between two steps until convergence:
$$\text{Assign: } C_k=\{x_i : k=\arg\min_j\|x_i-\mu_j\|^2\} \qquad \text{Update: } \mu_k=\frac{1}{|C_k|}\sum_{x_i\in C_k}x_i$$
Each step can only decrease or maintain J, so the algorithm always converges, but only to a local minimum, which is why smart initialisation (k-means++) and multiple random restarts are used in practice. Choosing K itself is typically done with the elbow method (plotting WCSS against K and looking for the point of diminishing returns) or the silhouette score.
How It Works
- Initialise
K centroids.
- Assign every point to its nearest centroid.
- Recompute each centroid as the mean of its assigned points.
- Repeat steps 2-3 until assignments stop changing.
Strengths
- Simple, fast, and scales well to large datasets.
Weaknesses
K must be chosen in advance.
- Assumes roughly spherical, similarly-sized clusters, struggles with irregular shapes.
- Sensitive to initialisation, outliers, and feature scaling.
When to use it: exploratory segmentation where clusters are expected to be roughly round and similar in size.
Six points, $K=2$, initial centroids placed directly on two of the points: $c_1=(1,2)$, $c_2=(5,8)$.
Iteration 1, assign: compute each point's distance to both centroids and assign to the nearer one. Points (1,2), (1.5,1.8), and (1,0.6) go to $c_1$; points (5,8), (8,8), and (9,11) go to $c_2$.
Iteration 1, update: recompute each centroid as the mean of its assigned points: $c_1=(1.17, 1.47)$, $c_2=(7.33, 9.0)$.
Iteration 2, assign: re-checking distances with the updated centroids produces the exact same assignment as before, nothing has changed, so the algorithm has converged.
Result: two clusters: {(1,2),(1.5,1.8),(1,0.6)} centred at (1.17, 1.47), and {(5,8),(8,8),(9,11)} centred at (7.33, 9.0), reached in just one update step from a reasonable starting point.
CLU-02 · Clustering
Hierarchical Clustering
Build the whole family tree of your data, then decide how many branches you actually want.
“Standard Definition
Hierarchical clustering is an unsupervised method that builds a nested sequence of clusters, visualised as a dendrogram, by successively merging the two closest clusters (agglomerative) until only one cluster remains.
The Idea
Rather than committing to a number of clusters upfront, hierarchical clustering builds a full nested tree (a dendrogram) by repeatedly merging the two closest clusters, starting from every point as its own cluster. You choose the final number of clusters afterwards, by deciding where to "cut" the tree.
The Maths
The key choice is the linkage criterion, how "distance between two clusters" is defined:
- Single linkage: the minimum distance between any pair of points across the two clusters.
- Complete linkage: the maximum such distance.
- Average linkage: the mean of all pairwise distances.
- Ward's method: merge whichever pair of clusters causes the smallest increase in total within-cluster variance.
The algorithm greedily merges the closest pair of clusters at every step, recording the merge distance, until only one cluster remains. Cutting the dendrogram at a chosen height yields a chosen number of clusters, often picked visually by finding the tallest vertical gap that no horizontal line crosses.
How It Works
- Start with every point as its own cluster.
- Repeatedly merge the two closest clusters, per the chosen linkage rule.
- Record every merge to build the dendrogram.
- Cut the tree at the desired height to get a specific number of clusters.
Strengths
- No need to pre-specify the number of clusters.
- The dendrogram itself is a rich, visual summary of structure.
Weaknesses
- Expensive on large datasets.
- Single linkage is prone to "chaining" through noisy points.
- Merges are greedy and irreversible.
When to use it: smaller datasets where a nested, hierarchical relationship between groups genuinely matters.
Five points, using single linkage: A(1,1), B(1.5,1.2), C(5,5), D(5.5,5.2), E(3,3).
Step 1: the distance matrix shows a tie for the smallest distance, 0.54, shared by both A-B and C-D. Suppose the algorithm merges both: {A,B} and {C,D}.
Step 2: recompute distances to the new clusters using single linkage (the minimum distance between any pair of points across clusters): distance({A,B}, E) = 2.34, distance({C,D}, E) = 2.83, distance({A,B}, {C,D}) = 5.17. The smallest is {A,B} to E, so merge: {A, B, E}.
Step 3: only two clusters remain, {A,B,E} and {C,D}, at distance 2.83. Merge them into one final cluster containing everything.
Result: the dendrogram shows A-B and C-D merging first (tightest pairs, both at height 0.54), then E joining the A-B side (height 2.34), and finally everything merging together (height 2.83). Cutting the tree at height 2.5, for instance, would recover exactly two clusters: {A,B,E} and {C,D}.
ARL-01 · Association Rule Learning
Apriori
"People who bought bread and butter also bought milk", found systematically.
“Standard Definition
Apriori is an algorithm for mining frequent itemsets and association rules from transactional data, relying on the principle that every subset of a frequent itemset must itself be frequent, to prune the search space.
The Idea
Apriori mines transaction data (shopping baskets, browsing sessions) to find frequently co-occurring items, then converts those into "if this, then that" association rules.
The Maths
Three quantities define every rule X → Y:
$$\text{Support}(X)=\frac{\text{transactions containing }X}{\text{total transactions}}$$
$$\text{Confidence}(X\to Y)=\frac{\text{Support}(X\cup Y)}{\text{Support}(X)}=P(Y\mid X)$$
$$\text{Lift}(X\to Y)=\frac{\text{Confidence}(X\to Y)}{\text{Support}(Y)}$$
Lift above 1 means X and Y co-occur more than chance would predict; lift near 1 means they're essentially independent. The whole algorithm rests on the Apriori principle: if an itemset is frequent, every subset of it must also be frequent (equivalently, any superset of an infrequent itemset is also infrequent). This lets the search prune huge portions of the itemset space rather than checking every possible combination.
How It Works
- Find all frequent single items (support above a minimum threshold).
- Combine frequent itemsets into candidate pairs, keep only those meeting the support threshold.
- Repeat for triples, quadruples, and so on, pruning any candidate whose subset isn't already frequent.
- From the final frequent itemsets, generate rules that meet a minimum confidence.
Strengths
- Produces genuinely interpretable "if-then" rules.
- Well-established and easy to explain to non-technical stakeholders.
Weaknesses
- Expensive with large numbers of items or transactions, many repeated database scans.
- Result quality is sensitive to the chosen support/confidence thresholds.
When to use it: market basket analysis and rule-based recommendation mining.
Five shopping baskets:
| T1 | bread, butter, milk |
|---|
| T2 | bread, butter |
|---|
| T3 | bread, milk |
|---|
| T4 | butter, milk |
|---|
| T5 | bread, butter, milk, eggs |
|---|
Step 1, support of single items: bread appears in 4 of 5 baskets (support 0.80), as does butter (0.80) and milk (0.80); eggs appears in just 1 (support 0.20).
Step 2, support of the pair {bread, butter}: it appears in T1, T2, and T5, so $\text{Support}=3/5=0.60$.
Step 3, confidence and lift of the rule bread → butter:
$$\text{Confidence}=\frac{\text{Support(bread, butter)}}{\text{Support(bread)}}=\frac{0.60}{0.80}=0.75 \qquad \text{Lift}=\frac{0.75}{\text{Support(butter)}}=\frac{0.75}{0.80}=0.94$$
Result: 75% of baskets containing bread also contain butter, but the lift of 0.94 (just under 1) reveals this isn't actually a meaningful association, butter is so common (80% of all baskets) that seeing it alongside bread is barely better than chance.
ARL-02 · Association Rule Learning
Eclat
Same goal as Apriori, a faster route there using set intersections.
“Standard Definition
Eclat is an algorithm for mining frequent itemsets that represents each item by the set of transaction IDs in which it appears (its tid-set), computing the support of any combined itemset directly via the intersection of the relevant tid-sets.
The Idea
Eclat finds the same frequent itemsets as Apriori, but stores the data differently: instead of scanning the whole transaction list repeatedly, it represents each item by the set of transaction IDs it appears in, and finds itemset support via simple set intersection.
The Maths
Each item i is represented by its tid-set, the set of transaction IDs containing it. Support of a combined itemset comes directly from intersecting tid-sets:
$$\text{tid-set}(X\cup Y) = \text{tid-set}(X)\cap \text{tid-set}(Y), \qquad \text{Support}(X)=\frac{|\text{tid-set}(X)|}{\text{total transactions}}$$
This avoids re-scanning the full database at every level, unlike Apriori's horizontal approach, while relying on the same anti-monotonicity pruning principle underneath.
How It Works
- Convert the transaction data into vertical tid-sets, one per item.
- Depth-first search through combinations of items, computing support via tid-set intersection.
- Prune any branch that falls below the minimum support threshold.
Strengths
- Typically faster than Apriori, avoiding repeated full database scans.
Weaknesses
- Tid-sets can consume significant memory on large or dense datasets.
- Only produces frequent itemsets directly, confidence/lift rules are still a separate step.
When to use it: the same problems as Apriori, when speed matters more than the memory cost of storing tid-sets.
Using the same five baskets as the Apriori example (transactions numbered 0-4), first convert to vertical tid-sets:
| bread | {0, 1, 2, 4} |
|---|
| butter | {0, 1, 3, 4} |
|---|
| milk | {0, 2, 3, 4} |
|---|
| eggs | {4} |
|---|
To find the support of {bread, butter}, simply intersect their tid-sets, no re-scanning the original transaction list required:
$$\text{tid-set(bread)} \cap \text{tid-set(butter)} = \{0,1,2,4\}\cap\{0,1,3,4\} = \{0,1,4\}$$
$$\text{Support(bread, butter)} = \frac{|\{0,1,4\}|}{5} = 0.60$$
Result: exactly the same support value Apriori found (0.60), reached through a single set intersection rather than rescanning every transaction, this is where Eclat's speed advantage comes from.
DR-01 · Dimensionality Reduction
Principal Component Analysis (PCA)
Rotate the axes so the first few directions capture nearly all the spread.
“Standard Definition
Principal Component Analysis is an unsupervised dimensionality reduction technique that finds new orthogonal axes, ordered by the variance they capture, allowing data to be projected onto fewer dimensions with minimal information loss.
The Idea
PCA finds new, orthogonal axes, ordered by how much variance they capture, so that most of a dataset's information can be kept using far fewer dimensions than the original features.
The Maths
With data X mean-centred, compute the covariance matrix and solve its eigenvalue problem:
$$\Sigma = \frac{1}{n}X^TX, \qquad \Sigma v_i = \lambda_i v_i$$
The eigenvectors v_i are the principal components (the new axes); the eigenvalues λ_i are how much variance each axis explains. Sorting by descending eigenvalue and keeping the top k gives the reduced representation:
$$Z = X V_k$$
In practice this is computed via the numerically stable Singular Value Decomposition, X = UΣV^T, where the columns of V are exactly the principal component directions. The proportion of variance each component explains, λ_i / Σλ_j, is used to decide how many components to keep (commonly enough for 95% cumulative variance).
How It Works
- Standardise the data (mean 0).
- Compute the covariance matrix (or run SVD directly on the data matrix).
- Sort eigenvectors by eigenvalue, keep the top
k.
- Project the original data onto these
k components.
Strengths
- Removes multicollinearity, since components are uncorrelated by construction.
- Speeds up downstream models and enables 2D/3D visualisation.
Weaknesses
- Components are linear blends of the original features, interpretability is lost.
- Only captures linear structure, and is unsupervised (ignores class labels entirely, unlike LDA).
When to use it: preprocessing for high-dimensional or collinear data, noise reduction, or visualisation.
Ten 2D points with mean (1.81, 1.91) (a classic illustrative dataset).
Step 1: after mean-centring, compute the covariance matrix:
$$\Sigma = \begin{bmatrix}0.617 & 0.615\\0.615 & 0.717\end{bmatrix}$$
The near-equal off-diagonal values show the two original features are strongly correlated, exactly the redundancy PCA is designed to remove.
Step 2: solving the eigenvalue problem gives eigenvalues 1.284 and 0.049, with the first eigenvector (0.678, 0.735).
Step 3: the explained variance ratio is $1.284/(1.284+0.049)=96.3\%$ for the first component alone, and just 3.7% for the second.
Result: a single principal component captures 96.3% of the total spread in the data, so the two original correlated features can be replaced with one new uncorrelated one, losing less than 4% of the information.
DR-02 · Dimensionality Reduction
Kernel PCA
PCA's kernel trick: uncover curved structure that straight-line PCA can't see.
“Standard Definition
Kernel PCA is a non-linear extension of Principal Component Analysis that applies the kernel trick to implicitly map data into a higher-dimensional feature space before extracting principal components, revealing non-linear structure that ordinary PCA cannot capture.
The Idea
Ordinary PCA can only find linear structure. Kernel PCA applies the same kernel trick used in Kernel SVM: implicitly map the data to a higher-dimensional space using a kernel function, then perform PCA there, all without ever explicitly computing the mapping.
The Maths
Instead of the covariance matrix, work directly with the kernel matrix K_{ij}=K(x_i,x_j). After centring it in feature space:
$$K' = K - \mathbf{1}_nK - K\mathbf{1}_n + \mathbf{1}_nK\mathbf{1}_n$$
solve the eigenvalue problem on K' directly, and project a point x onto the i-th component using only kernel evaluations against the training points:
$$z_i(x) = \sum_j \alpha_{ij}\,K(x_j,x)$$
This never requires the explicit feature mapping φ(x), exactly the same trick, and the same underlying theoretical guarantee (Mercer's theorem), as Kernel SVM.
How It Works
- Choose a kernel (RBF is common) and its hyperparameters.
- Build and centre the kernel matrix.
- Solve its eigenvalue problem to get the non-linear components.
Strengths
- Uncovers non-linear manifolds (e.g. concentric circles) that linear PCA cannot separate.
Weaknesses
- Highly sensitive to kernel choice and hyperparameters.
- No simple "explained variance" interpretation, and harder to invert back to the original space.
When to use it: data with obvious non-linear structure where linear PCA fails to separate anything meaningful.
Eight points forming two concentric rings: an inner ring at (±1,0), (0,±1), and an outer ring at (±2,0), (0,±2).
Plot these: every inner point is exactly distance 1 from the centre, every outer point is exactly distance 2. But no straight line can separate "inner" from "outer", the two rings are interleaved by angle, so ordinary linear PCA (which only finds straight-line directions of variance) cannot pull them apart.
Now compute one non-linear quantity for every point, its squared distance from the origin, $x_1^2+x_2^2$:
| Inner ring points | (1,0)→1 | (0,1)→1 | (-1,0)→1 | (0,-1)→1 |
|---|
| Outer ring points | (2,0)→4 | (0,2)→4 | (-2,0)→4 | (0,-2)→4 |
|---|
Result: this single non-linear quantity separates the two rings perfectly, 1 vs 4, with no overlap. An RBF kernel, which measures similarity based on squared distance, gives Kernel PCA implicit access to exactly this kind of feature, which is precisely why it can succeed where linear PCA fails.
DR-03 · Dimensionality Reduction
Linear Discriminant Analysis (LDA)
Unlike PCA, this one is told the labels, and uses them to separate the classes.
“Standard Definition
Linear Discriminant Analysis is a supervised dimensionality reduction technique that finds the linear projection maximising the ratio of between-class variance to within-class variance, so as to separate known classes as much as possible.
The Idea
PCA finds directions of maximum variance without caring about class labels. LDA is supervised: it finds the projection that best separates known classes, by maximising the distance between class means while minimising the spread within each class.
The Maths
Define the within-class and between-class scatter matrices:
$$S_W=\sum_k\sum_{i\in \text{class }k}(x_i-\mu_k)(x_i-\mu_k)^T \qquad S_B=\sum_k n_k(\mu_k-\mu)(\mu_k-\mu)^T$$
LDA seeks the projection w that maximises Fisher's criterion, the ratio of between-class to within-class variance:
$$J(w)=\frac{w^TS_Bw}{w^TS_Ww}$$
which is solved as a generalised eigenvalue problem, equivalently the eigenvectors of S_W⁻¹S_B, sorted by descending eigenvalue. With C classes, at most C-1 useful discriminant directions exist, since S_B has rank at most C-1.
How It Works
- Compute the within-class and between-class scatter matrices.
- Solve the generalised eigenvalue problem for
S_W⁻¹S_B.
- Project the data onto the top eigenvectors (up to
C-1 of them).
Strengths
- Uses label information, so components tend to be much better suited for downstream classification than PCA's.
- Can double as a classifier itself.
Weaknesses
- Assumes classes are Gaussian with a shared covariance matrix.
- Limited to at most
C-1 dimensions.
When to use it: supervised dimensionality reduction ahead of classification, especially when class shapes are similar but their centres differ.
Two classes with 3 points each: Class 0 at (2,3), (3,4), (4,5); Class 1 at (6,7), (7,8), (8,6).
Step 1: class means are $\mu_0=(3,4)$, $\mu_1=(7,7)$.
Step 2: the within-class scatter matrix (spread inside each class) and between-class scatter matrix (spread between the class means) come out to:
$$S_W=\begin{bmatrix}4&1\\1&4\end{bmatrix} \qquad S_B=\begin{bmatrix}24&18\\18&13.5\end{bmatrix}$$
Step 3: solving for the direction that maximises $w^TS_Bw/w^TS_Ww$ gives the (normalised) discriminant direction $w=(0.852, 0.524)$.
Step 4: projecting every point onto this single direction: Class 0 becomes 3.28, 4.65, 6.03; Class 1 becomes 8.78, 10.15, 9.96.
Result: on this single new axis, every Class 0 point (3.28 to 6.03) is clearly below every Class 1 point (8.78 to 10.15), the two classes are now completely separated using just one dimension, down from two.
DR-04 · Dimensionality Reduction
t-SNE
Built purely to make a beautiful, honest 2D picture of neighbourhood structure.
“Standard Definition
t-SNE is a non-linear dimensionality reduction technique designed for visualisation, converting high-dimensional pairwise distances into neighbour probabilities and arranging points in a low-dimensional map to preserve those neighbour relationships as closely as possible.
The Idea
t-SNE (t-distributed Stochastic Neighbour Embedding) is designed specifically for visualisation: it tries to keep points that are close together in high dimensions close together in a 2D or 3D map, at the deliberate cost of not preserving global distances faithfully.
The Maths
In the high-dimensional space, convert distances into neighbour probabilities using a Gaussian centred on each point, then symmetrise:
$$p_{j|i}=\frac{\exp(-\|x_i-x_j\|^2/2\sigma_i^2)}{\sum_{k\ne i}\exp(-\|x_i-x_k\|^2/2\sigma_i^2)}, \qquad p_{ij}=\frac{p_{j|i}+p_{i|j}}{2n}$$
In the low-dimensional map, use a heavier-tailed Student-t distribution instead of a Gaussian, specifically to avoid the "crowding problem" where moderate high-dimensional distances get artificially squeezed together:
$$q_{ij}=\frac{(1+\|y_i-y_j\|^2)^{-1}}{\sum_{k\ne l}(1+\|y_k-y_l\|^2)^{-1}}$$
The 2D coordinates y_i are then optimised by gradient descent to minimise the KL divergence between the two distributions:
$$KL(P\|Q)=\sum_{i\ne j}p_{ij}\log\frac{p_{ij}}{q_{ij}}$$
How It Works
- Compute high-dimensional neighbour probabilities, tuned via the perplexity hyperparameter.
- Initialise a random low-dimensional layout.
- Iteratively adjust the layout with gradient descent to minimise the KL divergence between high- and low-dimensional neighbour distributions.
Strengths
- Exceptionally good at revealing genuine cluster structure visually.
Weaknesses
- Cluster sizes and inter-cluster gaps in the resulting plot are not reliably meaningful.
- Stochastic, different runs give different layouts, and it's expensive on large datasets.
- Not intended as a preprocessing step for a downstream predictive model, unlike PCA.
When to use it: exploratory visualisation of high-dimensional data (embeddings, gene expression), never as a feature-reduction step before another model.
Three points on a single axis: $x=0$, $x=1$, and $x=5$, with $\sigma=1$.
From point 0's perspective, point 1 is very close (distance 1) and point 5 is far (distance 5). Computing the Gaussian-based neighbour probabilities:
$$p_{1|0}=1.000 \qquad p_{5|0}\approx 0.000$$
From point 1's perspective, both neighbours are visible but point 0 is much closer than point 5:
$$p_{0|1}=0.999 \qquad p_{5|1}=0.001$$
From point 5's perspective, both other points are far away, but point 1 is comparatively closer than point 0:
$$p_{0|5}=0.011 \qquad p_{1|5}=0.989$$
Result: even though point 5 is distant from everything, its (small) probability mass still overwhelmingly favours point 1 over point 0, since 1 is comparatively nearer. This is exactly the signal t-SNE uses to decide how to arrange points 0, 1, and 5 in the low-dimensional map: keep 0 and 1 close together, and place 5 further away but nearer to 1 than to 0.
ENS-01 · Ensemble & Boosting
Gradient Boosting
Build models sequentially, each one trained purely to fix what the last one got wrong.
“Standard Definition
Gradient Boosting is an ensemble technique that builds an additive model by sequentially fitting new weak learners to the negative gradient (the residual errors) of the loss function with respect to the current ensemble's predictions.
The Idea
Where Random Forest builds many independent trees and averages them, Gradient Boosting builds trees sequentially: each new tree is trained specifically to predict the errors of the ensemble so far, gradually correcting the combined model. This is the foundation XGBoost, AdaBoost, and CatBoost all build on.
The Maths
Start with a simple initial prediction F₀(x) (e.g. the mean of y). At each stage m, compute the pseudo-residuals, the negative gradient of the loss with respect to the current prediction:
$$r_{im} = -\left[\frac{\partial L(y_i,F(x_i))}{\partial F(x_i)}\right]_{F=F_{m-1}}$$
(for squared-error loss, this is simply the ordinary residual y_i - F_{m-1}(x_i)). Fit a new weak learner h_m(x) (usually a shallow tree) to predict these residuals, then update the ensemble with a shrinkage factor ν (the learning rate):
$$F_m(x) = F_{m-1}(x) + \nu \cdot h_m(x)$$
This is literally gradient descent, just performed in "function space" rather than parameter space: each tree approximates the direction that most reduces the overall loss.
How It Works
- Start with a simple baseline prediction.
- Compute the residuals between predictions and true values.
- Fit a small tree to predict those residuals, and add a shrunk version of it to the ensemble.
- Repeat for a fixed number of rounds, or until validation performance stops improving.
Strengths
- Very high predictive accuracy on structured/tabular data.
- Flexible to different loss functions.
Weaknesses
- Sequential by nature, harder to parallelise than bagging.
- Easy to overfit if the learning rate, tree count, and depth aren't tuned carefully.
When to use it: as the conceptual base for the three specific implementations below, or directly when top predictive accuracy on tabular data matters most.
Four targets: $y=[10, 20, 30, 40]$, learning rate $\nu=0.5$.
Round 0: start with the simplest possible prediction, the mean: $F_0=25$ for every point. Residuals: $[-15,-5,5,15]$.
Round 1: fit a small stump that predicts the mean residual of each half: $h_1=[-10,-10,10,10]$. Update: $F_1=F_0+0.5h_1=[20,20,30,30]$. New residuals: $[-10,0,0,10]$, already much smaller than round 0's residuals.
Round 2: fit another stump to these new residuals: $h_2=[-5,-5,5,5]$. Update: $F_2=F_1+0.5h_2=[17.5,17.5,32.5,32.5]$.
Result: after just two rounds, predictions have moved from a flat 25 for everyone to $[17.5, 17.5, 32.5, 32.5]$, closing in on the true values $[10,20,30,40]$ a little more with each round, exactly the sequential error-correction gradient boosting is built on.
ENS-02 · Ensemble & Boosting
XGBoost
Gradient Boosting, engineered for speed, with regularisation built directly into the maths.
“Standard Definition
XGBoost is a regularised, scalable implementation of gradient boosting that uses a second-order Taylor approximation of the loss and an explicit penalty on tree complexity to choose splits and leaf weights.
The Idea
XGBoost (Extreme Gradient Boosting) is a heavily optimised, regularised implementation of gradient boosting. Its key mathematical difference is using a second-order (Newton's method) approximation of the loss at every step, plus an explicit complexity penalty on each tree.
The Maths
At each round, XGBoost minimises a regularised objective, with tree complexity penalty Ω:
$$\text{Obj}^{(m)} = \sum_i L(y_i,F_{m-1}(x_i)+h_m(x_i)) + \Omega(h_m), \qquad \Omega(h)=\gamma T + \tfrac{1}{2}\lambda\sum_j w_j^2$$
(T = number of leaves, w_j = leaf weights). Using a second-order Taylor expansion of the loss around the current prediction, with gradient g_i and Hessian h_i:
$$L(y_i,F_{m-1}+h_m)\approx L(y_i,F_{m-1}) + g_ih_m(x_i)+\tfrac{1}{2}h_ih_m(x_i)^2$$
For a fixed tree structure, this gives a closed-form optimal leaf weight:
$$w_j^{*}=-\frac{\sum_{i\in \text{leaf }j}g_i}{\sum_{i\in \text{leaf }j}h_i+\lambda}$$
Plugging this back in produces a closed-form "gain" score for any candidate split, the direct analogue of information gain, but derived from the actual loss function's curvature rather than a generic impurity measure.
How It Works
- Compute the gradient and Hessian of the loss for every point, given current predictions.
- Greedily grow each tree using the closed-form gain formula to choose splits.
- Apply shrinkage and the
γ, λ regularisation penalties to control overfitting.
Strengths
- Extremely fast and accurate, with regularisation baked directly into the split-finding maths.
- Handles missing values natively.
Weaknesses
- Many hyperparameters to tune.
- Less interpretable than a single tree, and still capable of overfitting without early stopping.
When to use it: tabular data problems where predictive performance is the priority.
Four targets $y=[10,20,30,40]$, current prediction is the mean (25) for everyone, using squared-error loss (so the gradient $g_i=\text{pred}-y_i$ and the Hessian $h_i=1$ for every point), and $\lambda=1$.
Gradients: $g=[15, 5, -5, -15]$. Consider splitting the first two points from the last two:
$$G_L=15+5=20,\;\; H_L=2 \qquad G_R=-5-15=-20,\;\; H_R=2 \qquad G=0,\;\;H=4$$
Plugging into the gain formula:
$$\text{Gain}=\tfrac12\left(\frac{20^2}{2+1}+\frac{(-20)^2}{2+1}-\frac{0^2}{4+1}\right)=\tfrac12(133.3+133.3-0)=133.3$$
The optimal leaf weights for this split are $w_L=-G_L/(H_L+\lambda)=-6.67$ and $w_R=-G_R/(H_R+\lambda)=6.67$.
Result: this split scores a gain of 133.3, a large positive number, meaning XGBoost's tree-building algorithm would readily accept it, with the left leaf nudging predictions down by 6.67 and the right leaf nudging them up by 6.67.
ENS-03 · Ensemble & Boosting
AdaBoost
The original boosting algorithm: reweight the data so the next weak learner focuses on your mistakes.
“Standard Definition
AdaBoost is a boosting algorithm that combines a sequence of weak classifiers, each trained on a reweighted version of the data emphasising previous misclassifications, into a single weighted-majority-vote strong classifier.
The Idea
AdaBoost (Adaptive Boosting) trains a sequence of very simple weak learners, often single-split "decision stumps", where each new learner is trained on a reweighted version of the data that emphasises whatever the previous learners got wrong.
The Maths
Initialise equal weights w_i = 1/n for every sample. At each round m:
- Train a weak learner
h_m on the current weighted data.
- Compute its weighted error rate:
ε_m = Σ w_i · 𝟙(h_m(x_i)≠y_i) / Σ w_i
- Compute its vote weight:
α_m = ½ ln((1-ε_m)/ε_m), better-than-random learners get a positive vote, and the smaller the error the larger the vote.
- Update the weights:
w_i ← w_i · exp(-α_m y_i h_m(x_i)), then renormalise.
This last step is the heart of the algorithm: misclassified points get their weight boosted, so the next learner is forced to pay them more attention. The final prediction is a weighted vote:
$$H(x)=\text{sign}\left(\sum_{m=1}^{M}\alpha_mh_m(x)\right)$$
How It Works
- Train a weak learner, measure its weighted error, and assign it a vote weight based on that error.
- Boost the weights of the points it got wrong.
- Repeat, then combine all learners via their weighted vote.
Strengths
- Simple, with very few hyperparameters.
- Surprisingly effective even with extremely weak learners.
Weaknesses
- Sensitive to noisy data and outliers, since misclassified points keep gaining weight round after round.
When to use it: reasonably clean data, binary classification, when a fast and simple boosting method beats a full gradient boosting setup.
Five points, true labels $y=[+1,+1,+1,-1,-1]$, all starting with equal weight 0.2.
Round 1: weak learner $h_1=[+1,+1,-1,-1,-1]$ misclassifies point 3 only (predicts $-1$, truth is $+1$). Weighted error $\varepsilon_1=0.2$, so its vote weight is $\alpha_1=\tfrac12\ln\frac{1-0.2}{0.2}=0.693$.
Updating weights, boosting the misclassified point and shrinking the rest: new weights become $[0.125, 0.125, 0.5, 0.125, 0.125]$, point 3 now carries 4× the weight of any other point.
Round 2: weak learner $h_2=[+1,+1,+1,-1,+1]$ now gets point 3 right, but misclassifies point 5 instead (weight 0.125). Weighted error $\varepsilon_2=0.125$, giving $\alpha_2=\tfrac12\ln\frac{1-0.125}{0.125}=0.973$.
Final vote: combine both learners: $\text{sign}(0.693\,h_1+0.973\,h_2)$. For point 3: $0.693(-1)+0.973(+1)=+0.280 \to$ correctly $+1$ now. For point 5: $0.693(-1)+0.973(+1)=+0.280 \to$ incorrectly $+1$ (true label is $-1$).
Result: boosting fixed the mistake on point 3 (which $h_1$ got wrong) but introduced a new mistake on point 5, an honest illustration that a couple of rounds don't guarantee perfection, each round shifts the ensemble's attention rather than solving everything at once.
ENS-04 · Ensemble & Boosting
CatBoost
Gradient boosting engineered specifically to stop leaking information from a point's own target.
“Standard Definition
CatBoost is a gradient boosting implementation designed to handle categorical features natively and avoid target leakage, using ordered target statistics for encoding and ordered boosting for tree fitting.
The Idea
CatBoost (Categorical Boosting) tackles a subtle problem in ordinary gradient boosting: when encoding categorical features using target statistics, or when fitting each new tree's residuals, standard approaches can leak information about a sample's own target value into its own features, quietly causing overfitting. CatBoost's core innovations exist specifically to remove that leakage.
The Maths
Ordered Target Statistics: instead of encoding a category using the mean target across the whole dataset (which uses each row's own label to encode itself), CatBoost computes each row's category statistic using only rows that came before it in a random permutation:
$$TS(x_i)=\frac{\sum_{j
(P a global prior, a a smoothing weight). This mimics how the statistic would look if it were computed causally, in time order, rather than leaking future information backwards.
Ordered Boosting: applies the same idea to the boosting process itself, each tree's residuals are computed using a model that never saw that particular row during training, using multiple random data permutations to make this efficient in practice.
CatBoost also grows symmetric (oblivious) trees, where the same split condition is applied across an entire level of the tree, trading some flexibility for speed and a built-in regularising effect.
How It Works
- Encode categorical features using ordered target statistics, rather than naive target means.
- Grow trees using ordered boosting, so no tree ever benefits from a point's own label.
- Use symmetric trees for fast, regularised splits.
Strengths
- Excellent out-of-the-box handling of categorical features, no manual encoding required.
- Less prone to the subtle overfitting from target leakage than naive gradient boosting.
Weaknesses
- Can be slower to train than XGBoost on purely numerical data.
- Oblivious trees are sometimes less flexible than fully-grown ones.
When to use it: tabular datasets with many categorical features, customer records, product catalogues, and similar.
Six rows, in a random permutation order, with a "city" category and a target label:
| Row | 1 | 2 | 3 | 4 | 5 | 6 |
|---|
| City | A | B | A | A | B | C |
|---|
| Target | 1 | 0 | 1 | 0 | 1 | 0 |
|---|
Global prior $P=0.5$ (the overall average target), smoothing weight $a=1$. For each row, the ordered target statistic only looks at earlier rows sharing the same city:
| Row 1 (city A, no prior A rows) | $(0+1\times0.5)/(0+1)=0.500$ |
| Row 2 (city B, no prior B rows) | $(0+1\times0.5)/(0+1)=0.500$ |
| Row 3 (city A, 1 prior A row with target 1) | $(1+0.5)/(1+1)=0.750$ |
| Row 4 (city A, 2 prior A rows, targets 1,1) | $(2+0.5)/(2+1)=0.833$ |
| Row 5 (city B, 1 prior B row with target 0) | $(0+0.5)/(1+1)=0.250$ |
| Row 6 (city C, no prior C rows) | $(0+0.5)/(0+1)=0.500$ |
|---|
Result: row 4's encoding (0.833) is built only from rows 1 and 3 that came before it, never from its own target, unlike a naive "mean target per city" encoding, which would let row 4's own label leak into its own feature value.
TS-01 · Time Series
ARIMA
Forecast a series from its own past values and its own past mistakes.
“Standard Definition
ARIMA is a class of statistical models for univariate time series forecasting that combines autoregression on a series' own past values, moving-average terms on past forecast errors, and differencing to remove trend and achieve stationarity.
The Idea
ARIMA (AutoRegressive Integrated Moving Average) forecasts a time series using three ingredients: its own lagged values (AutoRegressive), its own past forecast errors (Moving Average), and differencing to strip out trend so the series becomes stationary (Integrated).
The Maths
An AR(p) model predicts the current value from its own past p values:
$$X_t = c + \phi_1X_{t-1}+\dots+\phi_pX_{t-p}+\varepsilon_t$$
An MA(q) model instead predicts it from past forecast errors:
$$X_t = \mu + \varepsilon_t+\theta_1\varepsilon_{t-1}+\dots+\theta_q\varepsilon_{t-q}$$
Differencing (I, order d) removes trend so the mean and variance stop changing over time: ∇X_t = X_t - X_{t-1}, applied d times if needed, and checked with a stationarity test such as the Augmented Dickey-Fuller test. The full ARIMA(p,d,q) model combines all three, applied to the d-times-differenced series Y_t:
$$Y_t = c+\phi_1Y_{t-1}+\dots+\phi_pY_{t-p}+\varepsilon_t+\theta_1\varepsilon_{t-1}+\dots+\theta_q\varepsilon_{t-q}$$
Orders p and q are chosen by inspecting ACF/PACF plots or comparing candidate models with AIC/BIC; parameters are then fit via Maximum Likelihood Estimation, since the unobserved error terms rule out a simple closed form once MA terms are involved.
How It Works
- Test for stationarity, and difference the series until it holds.
- Use ACF/PACF plots to propose candidate
p and q orders.
- Fit candidate models via maximum likelihood, and compare with AIC/BIC.
- Forecast forward, then reverse the differencing to return to the original scale.
Strengths
- A mature, well-understood, interpretable framework for trended univariate series.
Weaknesses
- Assumes linear relationships and requires careful manual order selection.
- Doesn't natively model seasonality, that's SARIMA below.
When to use it: univariate forecasting with trend but no strong recurring seasonal pattern.
A series already confirmed stationary: $[10, 12, 13, 12, 15, 16, 15, 18, 20, 19]$. Fitting a simple AR(1) model, $X_t=c+\phi X_{t-1}+\varepsilon_t$, means regressing each value on the one immediately before it.
Step 1: pair up every value with its predecessor (9 pairs), then run ordinary least squares exactly as in Simple Linear Regression, treating $X_{t-1}$ as the input and $X_t$ as the output.
Step 2: solving gives $\phi=0.801$ and $c=3.903$.
Step 3: forecast the next value using the last observed point (19): $\hat{X}_{11}=3.903+0.801(19)=19.11$.
Result: the model expects the series to continue near 19.1, a modest pullback from 19, since $\phi=0.80$ means the series tends to partially revert rather than keep climbing indefinitely.
TS-02 · Time Series
SARIMA
ARIMA, plus an explicit memory for whatever happened this time last season.
“Standard Definition
SARIMA extends ARIMA with an additional seasonal autoregressive, differencing, and moving-average structure applied at lags corresponding to a fixed seasonal period, modelling both trend and recurring seasonal patterns together.
The Idea
SARIMA (Seasonal ARIMA) extends ARIMA with a second, parallel AR/I/MA structure that operates specifically at seasonal lags, letting it model repeating cycles like weekly, monthly, or yearly patterns on top of trend.
The Maths
Written SARIMA(p,d,q)(P,D,Q)ₘ, where m is the season length (e.g. 12 for monthly data with yearly seasonality), and (P,D,Q) mirror (p,d,q) but operate at lag multiples of m. Seasonal differencing removes the seasonal pattern the same way ordinary differencing removes trend:
$$\nabla_mX_t = X_t - X_{t-m}$$
The full model, using the lag operator L (where LX_t = X_{t-1}), combines both the regular and seasonal AR/MA polynomials:
$$\phi_p(L)\,\Phi_P(L^m)\,(1-L)^d(1-L^m)^D\,X_t = \theta_q(L)\,\Theta_Q(L^m)\,\varepsilon_t$$
Order selection follows the same ACF/PACF and AIC/BIC logic as ARIMA, but examined additionally at the seasonal lags (multiples of m) to identify P and Q.
How It Works
- Identify the seasonal period
m (weekly, monthly, yearly).
- Apply both regular and seasonal differencing until the series is stationary.
- Select
(p,d,q) and (P,D,Q) using ACF/PACF at regular and seasonal lags.
- Fit via maximum likelihood and forecast forward.
Strengths
- Handles trend and seasonality together in one coherent, interpretable framework.
Weaknesses
- Seven hyperparameters to select, and heavier to fit than plain ARIMA.
- Struggles with multiple overlapping seasonalities (e.g. daily and weekly and yearly at once).
When to use it: univariate series with one clear, dominant seasonal cycle, retail sales, electricity demand, tourism numbers.
A toy series with an obvious 4-period seasonal cycle: $[20, 22, 25, 19,\; 23, 25, 28, 22]$ (two repeating "seasons" of length 4).
Apply seasonal differencing at lag $m=4$: subtract each value from the one exactly one season earlier, $\nabla_4X_t=X_t-X_{t-4}$:
$$23-20=3 \qquad 25-22=3 \qquad 28-25=3 \qquad 22-19=3$$
Result: the differenced series is a perfectly constant $[3,3,3,3]$. The seasonal pattern (which peaked and dipped identically each cycle) has been completely removed, leaving only a flat upward shift of +3 per season, exactly the stationary signal ARIMA's ordinary machinery can then model.
FND-01 · Foundations & Model Building
Feature Scaling
Put every feature on the same footing, before distance or gradients get involved.
“Standard Definition
Feature scaling is a data preprocessing step that transforms numeric features onto a common scale, typically via min-max normalisation to a fixed range or standardisation to zero mean and unit variance, without distorting the relative ordering of values.
The Idea
Many algorithms are sensitive to the raw scale of a feature. A "salary in pounds" column can numerically dwarf an "age in years" column purely because of units, not because it's more important. Scaling fixes that before it distorts distance calculations or gradient-based optimisation.
The Maths
Normalisation (min-max scaling) rescales into a fixed range, usually [0,1]:
$$x' = \frac{x-\min(x)}{\max(x)-\min(x)}$$
Standardisation (Z-score scaling) rescales to mean 0 and standard deviation 1:
$$x' = \frac{x-\mu}{\sigma}$$
Normalisation is sensitive to outliers, since one extreme value compresses everything else into a tiny range. Standardisation doesn't bound values to a fixed range but is more robust to outliers, and is the more common default.
Where It Matters
- Essential for: KNN, K-Means, SVM, PCA (all distance-based), and gradient-descent-optimised models like logistic regression and neural networks (unscaled features distort the loss surface and slow convergence).
- Not required for: Decision Trees, Random Forest, Gradient Boosting, since splits depend only on the ordering of values within a feature, not their scale.
Rule of thumb: if the algorithm measures distance or follows a gradient, scale first.
Four job applicants, by salary (£) and age (years):
| Salary | 20,000 | 35,000 | 50,000 | 120,000 |
|---|
| Age | 25 | 32 | 41 | 29 |
|---|
Min-max normalisation ($x'=(x-\min)/(\max-\min)$): salary becomes $[0, 0.15, 0.30, 1.00]$; age becomes $[0, 0.44, 1.00, 0.25]$.
Standardisation ($x'=(x-\mu)/\sigma$, with salary mean £56,250, std £38,304, and age mean 31.75, std 5.89): salary becomes $[-0.95, -0.55, -0.16, 1.66]$; age becomes $[-1.15, 0.04, 1.57, -0.47]$.
Before scaling, salary differences (tens of thousands) would completely swamp age differences (single digits) in any distance calculation, KNN or K-Means would essentially ignore age entirely. After either transform, both features contribute on a comparable footing.
Result: the £100,000 gap between the first and last applicant's salary and the 16-year gap in their ages now carry similar weight, roughly 1.66-(-0.95)=2.61 standardised units apart on salary vs 1.57-(-1.15)=2.72 units apart on age, instead of one variable dominating purely due to units.
FND-02 · Foundations & Model Building
The Dummy Variable Trap
A silent way to accidentally make your regression matrix un-invertible.
“Standard Definition
The dummy variable trap is a form of perfect multicollinearity that arises when all one-hot-encoded categories of a variable are included in a regression alongside an intercept term, making the design matrix singular and non-invertible.
The Idea
Turning a categorical feature with k categories into k one-hot dummy columns, then feeding all k into a regression alongside an intercept, creates a subtle but serious problem: perfect multicollinearity.
The Maths
By construction, one-hot dummies for every row always sum to exactly 1:
$$D_1+D_2+\dots+D_k = 1 \quad \text{for every row}$$
If the model also has an intercept term (a column of all 1s), one column becomes an exact linear combination of the others, meaning X^TX is singular and cannot be inverted, breaking the normal equation β̂ = (X^TX)⁻¹X^Ty from Multiple Linear Regression entirely.
The Fix
Drop exactly one dummy category. That dropped category becomes the implicit "reference" or "baseline" that the intercept and every other coefficient are measured relative to, leaving k-1 dummy variables for k categories.
Where it matters: linear and logistic regression, and anything relying on matrix inversion. Tree-based models handle redundant dummy columns without any numerical issue.
A "City" feature with three categories (London, Paris, Tokyo), one-hot encoded, alongside an intercept column:
| Intercept | London | Paris | Tokyo |
|---|
| 1 | 1 | 0 | 0 |
| 1 | 0 | 1 | 0 |
| 1 | 0 | 0 | 1 |
| 1 | 1 | 0 | 0 |
Computing $X^TX$ with all three dummy columns present and taking its determinant gives exactly 0, the matrix is singular, because London + Paris + Tokyo always sums to 1, exactly matching the intercept column.
Now drop the Tokyo column (keeping it as the implicit reference category) and recompute:
$$X^TX=\begin{bmatrix}4&2&1\\2&2&0\\1&0&1\end{bmatrix}, \qquad \det(X^TX)=2$$
Result: with all three dummies, the determinant is exactly zero, the normal equation $(X^TX)^{-1}X^Ty$ cannot be solved at all. Dropping just one dummy column restores a non-zero determinant (2) and a perfectly solvable regression.
FND-03 · Foundations & Model Building
Backward Elimination
Start with every predictor in the model, and prune away whatever isn't earning its place.
“Standard Definition
Backward elimination is a stepwise regression procedure that begins with every candidate predictor in the model and iteratively removes the least statistically significant one until every remaining predictor meets a chosen significance threshold.
The Idea
A stepwise feature selection method for regression: begin with every candidate predictor included, then remove the least statistically useful one at a time, until only genuinely useful predictors remain.
The Procedure
- Choose a significance level to stay in the model (commonly
SL = 0.05).
- Fit the model with every candidate predictor.
- Find the predictor with the highest p-value. If it's greater than
SL, remove it.
- Refit the model without that predictor.
- Repeat steps 3-4 until every remaining predictor has a p-value at or below
SL.
The p-value comes from a t-test on each coefficient (H₀: βⱼ = 0), testing whether that predictor still contributes once every other current predictor is accounted for.
Strengths
- Simple, and starts from the most information-rich model.
Weaknesses
- Greedy, a removed feature is never reconsidered.
- Needs the full model to be fittable, which fails if there are more features than rows.
Suppose you're modelling salary from 5 candidate predictors, with a significance threshold $SL=0.05$. Fitting the full model gives these p-values:
| Round 1 | Experience: 0.001 | Education: 0.03 | Department: 0.09 | Age: 0.44 | Commute distance: 0.81 |
|---|
Round 1: "Commute distance" has the highest p-value (0.81), far above 0.05, remove it and refit.
| Round 2 | Experience: 0.001 | Education: 0.02 | Department: 0.07 | Age: 0.31 |
|---|
Round 2: "Age" is now the worst offender (0.31), remove it and refit.
| Round 3 | Experience: 0.001 | Education: 0.02 | Department: 0.045 |
|---|
Round 3: every remaining predictor, including Department (0.045), now sits at or below 0.05. Stop here.
Result: the final model keeps Experience, Education, and Department, having discarded Age and Commute distance across two elimination rounds, purely on the basis of their p-values.
FND-04 · Foundations & Model Building
Forward Selection
The mirror image of Backward Elimination: start empty, and add only what earns its place.
“Standard Definition
Forward selection is a stepwise regression procedure that begins with no predictors and iteratively adds whichever candidate most improves the model, stopping once no remaining candidate meets a chosen significance threshold to enter.
The Idea
Start with no predictors at all, and add the single most useful one at each step, stopping as soon as no remaining candidate is good enough to justify adding.
The Procedure
- Choose a significance level to enter the model (commonly
SL = 0.05).
- Fit every possible simple regression of y on one predictor; keep whichever has the lowest p-value below
SL.
- Fit every model adding one more predictor to those already kept; keep the new addition if its p-value is below
SL.
- Repeat step 3 until the best remaining candidate no longer clears the threshold, then keep the model from the previous step.
Bidirectional Elimination (Stepwise Regression) combines both directions: at every step a feature can be added (if it clears the threshold to enter) or removed (if it later rises above the threshold to stay), giving a more thorough, if more expensive, search than either method alone.
Strengths
- Cheaper to start than Backward Elimination, and works even when there are more features than rows.
Weaknesses
- Also greedy, a feature added early is never removed even if it becomes redundant later.
Same 5 candidates as the Backward Elimination example, threshold $SL=0.05$, but building up from nothing.
Round 1: fit five separate single-predictor models. Experience alone gives the lowest p-value (0.001), well under 0.05, add it.
Round 2: with Experience already in, try adding each remaining candidate one at a time. Education gives the best additional p-value (0.02), add it.
Round 3: with Experience and Education in, Department now gives p=0.045 (just under 0.05), add it.
Round 4: with all three in, the best remaining candidate, Age, comes in at p=0.31, above the threshold. Stop, and keep the model from round 3.
Result: forward selection lands on the same final model, Experience, Education, and Department, as backward elimination did, though it built up to it one predictor at a time rather than trimming down. This won't always happen, the two methods can diverge on messier data, which is exactly why Bidirectional Elimination exists as a middle ground.
FND-05 · Foundations & Model Building
Regularisation: Ridge, Lasso & Elastic Net
Penalise big coefficients, and overfitting gets quieter.
“Standard Definition
Regularisation refers to a family of techniques, including Ridge (L2), Lasso (L1), and Elastic Net, that add a penalty on coefficient magnitude to a regression's loss function in order to reduce overfitting and control model complexity.
The Idea
Regularisation adds a penalty on coefficient size directly into the regression loss function, trading a small amount of bias for a meaningful reduction in variance, a direct, practical application of the Bias-Variance Tradeoff.
The Maths
Ridge (L2 penalty): shrinks all coefficients smoothly toward zero, rarely to exactly zero:
$$\min_\beta \sum_i(y_i-\hat{y}_i)^2 + \lambda\sum_j\beta_j^2 \;\;\Longrightarrow\;\; \hat{\beta}=(X^TX+\lambda I)^{-1}X^Ty$$
The added λI term also fixes multicollinearity directly, X^TX + λI is always invertible for λ > 0, even when X^TX alone isn't.
Lasso (L1 penalty): because the penalty has sharp corners at zero geometrically, it tends to push some coefficients to exactly zero, performing automatic feature selection:
$$\min_\beta \sum_i(y_i-\hat{y}_i)^2 + \lambda\sum_j|\beta_j|$$
Elastic Net blends both, keeping Lasso's feature-selection tendency while adding Ridge's stability when features are highly correlated:
$$\min_\beta \sum_i(y_i-\hat{y}_i)^2 + \lambda_1\sum_j|\beta_j| + \lambda_2\sum_j\beta_j^2$$
Strengths
- Directly combats overfitting in linear models.
- Lasso performs feature selection as a side effect.
Weaknesses
- Requires tuning
λ via cross-validation.
- Lasso alone tends to arbitrarily pick one from a group of correlated features.
When to use it: whenever a linear model overfits, or the feature set is large or collinear.
Two nearly-identical, highly correlated predictors ($x_1\approx x_2$) fitted against a target, using plain OLS first:
$$\text{OLS: } \beta = [0.772,\; 1.179]$$
Because the two predictors are so collinear, OLS arbitrarily assigns more weight to one than the other, a classic multicollinearity symptom. Now apply Ridge at increasing $\lambda$:
| λ=1 | β=[0.825, 0.829] |
|---|
| λ=5 | β=[0.514, 0.514] |
|---|
Ridge pulls the two coefficients toward each other (and toward zero) as $\lambda$ grows, correctly recognising that two near-identical features should share credit roughly equally.
Applying Lasso instead, at increasing $\alpha$:
| α=0.01 | β=[0.778, 1.155] |
|---|
| α=0.1 | β=[0.731, 1.041] |
|---|
| α=0.5 | β=[0.521, 0.533] |
|---|
Result: Ridge shrinks both coefficients smoothly and keeps both non-zero; Lasso shrinks them too, but at high enough regularisation strength (beyond what's shown here) it would drive one of these two redundant coefficients to exactly zero, performing feature selection Ridge alone never does.
FND-06 · Foundations & Model Building
The Bias-Variance Tradeoff
The single idea underneath almost every technique in this guide.
“Standard Definition
The bias-variance tradeoff is the decomposition of a model's expected prediction error into error from incorrect assumptions (bias), error from sensitivity to the specific training sample (variance), and irreducible noise, such that reducing one often increases the other.
The Idea
Every model's prediction error breaks down into three sources: how wrong its assumptions are on average (bias), how much its predictions swing across different training samples (variance), and irreducible noise in the data itself.
The Maths
For a model f̂ estimating true function f with noise variance σ², the expected squared error at a point decomposes exactly as:
$$E\big[(y-\hat{f}(x))^2\big] = \big(\text{Bias}[\hat{f}(x)]\big)^2 + \text{Var}[\hat{f}(x)] + \sigma^2$$
where Bias[f̂(x)] = E[f̂(x)] - f(x) (how far the average prediction, across many possible training sets, sits from the truth), and Var[f̂(x)] = E[(f̂(x)-E[f̂(x)])²] (how much predictions actually vary across those different training sets).
Why It Matters
Simple models (linear regression, shallow trees, high k in KNN) tend toward high bias, low variance, underfitting, consistently wrong in the same way. Complex models (deep trees, low k in KNN, high-degree polynomials) tend toward low bias, high variance, overfitting, accurate on training data but wildly different if retrained on a new sample.
This single decomposition is the theoretical justification behind nearly everything else in this guide: Regularisation (Ridge/Lasso) trades variance for bias directly; Random Forest reduces variance through averaging; Boosting reduces bias by sequentially correcting errors; and Cross-Validation exists specifically to help find the sweet spot between the two.
The true value we're trying to predict is 3.0. Two different models are each retrained on three different random samples of data, giving three predictions each:
| High-variance model | 1.0, 3.0, 5.0 |
|---|
| High-bias model | 4.6, 4.4, 4.5 |
|---|
High-variance model: average prediction $=3.0$, so bias $=3.0-3.0=0$ (correct on average!). But the spread is huge: variance $=2.67$. Total error contribution: $0^2+2.67=2.67$.
High-bias model: average prediction $=4.5$, so bias $=4.5-3.0=1.5$, bias$^2=2.25$. But the predictions barely move between samples: variance $=0.007$. Total error contribution: $2.25+0.007=2.257$.
Result: the high-bias model actually has slightly lower total expected error here (2.257 vs 2.667), despite never once landing on the correct average, because its consistency (low variance) outweighs its systematic error. This is precisely why a "worse-looking" simple model sometimes generalises better than a flexible one that's right on average but wildly inconsistent.
FND-07 · Foundations & Model Building
Cross-Validation & Grid Search
Estimate generalisation honestly, and search for hyperparameters systematically.
“Standard Definition
Cross-validation is a model evaluation technique that partitions data into multiple folds and repeatedly trains on some folds while validating on the remainder to obtain a robust estimate of generalisation performance; grid search uses this estimate to compare hyperparameter combinations.
The Idea
A single train/validation split gives a noisy, luck-dependent estimate of how well a model generalises. Cross-validation averages that estimate over multiple splits; grid search then uses that more reliable estimate to systematically compare hyperparameter choices.
The Maths
k-Fold Cross-Validation: split the training data into k equal folds. For each fold in turn, train on the remaining k-1 folds and validate on the held-out one, then average all k scores:
$$\text{CV score} = \frac{1}{k}\sum_{i=1}^{k}\text{Score}(\text{model trained without fold }i,\text{ evaluated on fold }i)$$
Every point is used for validation exactly once, giving a lower-variance estimate than any single split. Grid Search then defines a grid of candidate hyperparameter combinations (e.g. C ∈ {0.1, 1, 10}, kernel ∈ {linear, rbf}), evaluates every combination with k-fold cross-validation, and picks whichever combination scores best on average.
Strengths
- Far more reliable than a single arbitrary split, both for performance estimates and hyperparameter choices.
Weaknesses
- Computationally expensive, training happens (number of combinations) ×
k times.
- Only checks the specific points on the grid, random search or Bayesian optimisation scale better to large search spaces.
5-fold cross-validation: a model is trained 5 times, each time holding out a different fifth of the data for validation, giving 5 accuracy scores: 0.82, 0.79, 0.85, 0.81, 0.83.
$$\text{CV score} = \frac{0.82+0.79+0.85+0.81+0.83}{5} = 0.82, \qquad \text{std} = 0.02$$
Grid search then repeats this whole process for every combination of hyperparameters. Searching over an SVM's $C$ and kernel:
| C | Kernel | Mean CV accuracy |
| 0.1 | linear | 0.76 |
| 1 | linear | 0.81 |
| 10 | linear | 0.80 |
| 0.1 | rbf | 0.74 |
| 1 | rbf | 0.85 |
| 10 | rbf | 0.83 |
Result: $C=1$ with an RBF kernel wins, at a mean CV accuracy of 0.85, chosen from 6 candidates each evaluated across 5 folds (30 total model fits) rather than trusting any single lucky (or unlucky) train/test split.
FND-08 · Foundations & Model Building
Model Evaluation Metrics
"Good" is not one number, it depends entirely on what mistake costs you the most.
“Standard Definition
Model evaluation metrics are quantitative measures, such as R² and Adjusted R² for regression or Accuracy, Precision, Recall, F1, and AUC for classification, used to assess how well a model's predictions match observed outcomes.
Regression Metrics
R² (coefficient of determination) is the proportion of variance in y explained by the model:
$$R^2 = 1-\frac{SS_{res}}{SS_{tot}}, \qquad SS_{res}=\sum(y_i-\hat{y}_i)^2, \;\; SS_{tot}=\sum(y_i-\bar{y})^2$$
Adjusted R² penalises adding predictors that don't genuinely help, unlike plain R² which can only rise or stay flat as more predictors are added, even useless ones:
$$R^2_{adj} = 1-(1-R^2)\frac{n-1}{n-p-1}$$
Classification Metrics
Built from the Confusion Matrix (True Positives, True Negatives, False Positives, False Negatives):
$$\text{Accuracy}=\frac{TP+TN}{TP+TN+FP+FN} \qquad \text{Precision}=\frac{TP}{TP+FP} \qquad \text{Recall}=\frac{TP}{TP+FN}$$
$$F_1 = 2\cdot\frac{\text{Precision}\cdot\text{Recall}}{\text{Precision}+\text{Recall}}$$
The ROC curve plots Recall against the False Positive Rate across every possible classification threshold; the AUC (area under that curve) condenses it into one number, where 0.5 is random guessing and 1.0 is perfect separation, measuring how well the model ranks positives above negatives regardless of the specific threshold used.
Which One To Use
- Accuracy: fine for balanced classes with equal error costs.
- Precision: when false positives are expensive (e.g. spam filtering).
- Recall: when false negatives are expensive (e.g. disease screening).
- F1 / AUC: imbalanced classes, or when you need one balanced summary number.
Regression: recall the exam-score model from Simple Linear Regression, which had $SS_{res}=15.6$ and $SS_{tot}=451.2$ across $n=5$ students with $p=1$ predictor:
$$R^2 = 1-\frac{15.6}{451.2}=0.965 \qquad R^2_{adj}=1-(1-0.965)\frac{5-1}{5-1-1}=1-0.0346(1.333)=0.954$$
Adjusted R² (0.954) sits slightly below plain R² (0.965), correctly reflecting that some of that fit could be due to having only 5 data points for 1 predictor.
Classification: a model with 100 test cases produces this confusion matrix: TP=40, TN=50, FP=5, FN=5.
$$\text{Accuracy}=\frac{40+50}{100}=0.90 \qquad \text{Precision}=\frac{40}{40+5}=0.889 \qquad \text{Recall}=\frac{40}{40+5}=0.889$$
$$F_1=2\times\frac{0.889\times0.889}{0.889+0.889}=0.889$$
Result: precision and recall land on exactly the same value here (0.889) because false positives and false negatives happen to be equal (5 each); whenever that's not the case, F1's harmonic mean will sit closer to whichever of the two is lower, correctly punishing models that are lopsided in one direction.