🧠 Classical ML · Tier 2 🟡 Intermediate MODULE 05

Dimensionality Reduction

⏱️ 2.5 hours
📉 PCA · t-SNE · UMAP
🧩 5 Quiz Questions
Classical ML — Module 5 of 100%
🎯 What you'll learn: Why high-dimensional data creates problems (the curse of dimensionality), how PCA finds the directions of maximum variance, choosing how many components to keep, using t-SNE and UMAP for 2D visualisation, and knowing when dimensionality reduction before modelling helps vs. hurts.

Why Adding Features Can Hurt

Adding features to a dataset seems obviously helpful — more information, right? But as dimensionality grows, something counterintuitive happens: data becomes sparse. In high dimensions, all points become roughly equidistant from each other. Distance-based algorithms (K-Means, KNN, SVMs) lose their ability to distinguish "nearby" from "far" — because nothing is nearby anymore.

Practically: a dataset with 1,000 samples is dense in 5 dimensions but almost empty in 500 dimensions. You'd need exponentially more data to maintain the same density. Since we can't always collect more data, we reduce dimensions instead.

🎲
The volume intuition
In 1D, a random point in [0,1] has a 10% chance of being within 0.1 of center. In 2D, the probability drops to 1%. In 10D, it drops to 0.0000001%. All your data points end up in the corners of the hypercube. This is why KNN (K nearest neighbours) often works well in 5-20 dimensions but degrades sharply beyond ~30.

Rotate Features to Maximise Variance

PCA finds the directions in feature space that explain the most variance. The first principal component (PC1) points in the direction of maximum variance. PC2 points in the direction of maximum remaining variance, orthogonal to PC1. And so on.

Each principal component is a linear combination of the original features. PCA is a rotation of the coordinate system, not a selection of original features. You lose interpretability but gain a compact representation that captures most of the signal.

PCA — fit, variance explained, scree plotPYTHON
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
import numpy as np

# Always scale before PCA — variance is scale-dependent
X_scaled = StandardScaler().fit_transform(X)

# Step 1: fit full PCA to inspect variance
pca_full = PCA()
pca_full.fit(X_scaled)

# Cumulative explained variance — choose where it crosses 0.95
cumvar = np.cumsum(pca_full.explained_variance_ratio_)
n_components_95 = np.argmax(cumvar >= 0.95) + 1
print(f"{n_components_95} components explain 95% of variance")

# Step 2: fit PCA with chosen components
pca = PCA(n_components=n_components_95)
X_pca = pca.fit_transform(X_scaled)
print(f"Reduced: {X_scaled.shape[1]}D → {X_pca.shape[1]}D")

# Shorthand: keep enough for 95% variance automatically
pca_auto = PCA(n_components=0.95)
X_pca2 = pca_auto.fit_transform(X_scaled)
PCA in a Pipeline — correct way to avoid leakagePYTHON
from sklearn.pipeline import Pipeline
from sklearn.decomposition import PCA
from sklearn.ensemble import RandomForestClassifier

pipe = Pipeline([
    ('scaler', StandardScaler()),
    ('pca',    PCA(n_components=0.95)),  # fit on train fold only
    ('model',  RandomForestClassifier(n_estimators=100))
])
# PCA fitted on each training fold — no test data leaks into components
⚠️
PCA destroys interpretability
After PCA, your features are PC1, PC2, PC3... — linear combinations of originals. You can no longer say "salary was the most important feature." If interpretability matters for your use case, use feature selection instead of PCA.

Visualise High-Dimensional Clusters in 2D

PCA is linear — it can only capture linear structure. t-SNE and UMAP are non-linear methods designed primarily for visualisation, reducing data to 2D or 3D while preserving local neighbourhood structure (nearby points in high dimensions stay nearby in 2D).

PCA
Linear, fast, preserves global variance. Use for preprocessing before modelling. Reproducible.
t-SNE
Non-linear, preserves local neighbourhoods. Great for visualisation only. Slow O(n²), not reproducible.
UMAP
Non-linear, faster than t-SNE, preserves more global structure. Can be used as preprocessing step.
t-SNE and UMAP visualisationPYTHON
from sklearn.manifold import TSNE
import matplotlib.pyplot as plt

# t-SNE: perplexity ≈ expected cluster size (5–50)
tsne = TSNE(n_components=2, perplexity=30, random_state=42)
X_2d = tsne.fit_transform(X_scaled)

plt.figure(figsize=(8, 6))
plt.scatter(X_2d[:, 0], X_2d[:, 1], c=y, cmap='tab10', s=15)
plt.title('t-SNE 2D projection')
plt.show()

# UMAP — pip install umap-learn
import umap
reducer = umap.UMAP(n_components=2, random_state=42)
X_umap = reducer.fit_transform(X_scaled)
⚠️
Do NOT use t-SNE output as model input features
t-SNE results are non-deterministic and optimised for visualisation, not prediction. Distances in t-SNE space are not meaningful for modelling. Use t-SNE only to understand your data visually — use PCA or UMAP if you need a reduction that you'll feed into a model.

Reduction Helps Sometimes — and Hurts Other Times

Dimensionality reduction is not a step you should apply by default. Here's the decision:

  • Good use cases: features > samples (genomics, NLP bag-of-words), preprocessing for distance-based models (KNN, K-Means, SVM), visualising cluster structure, compressing storage for many-feature datasets
  • Bad use cases: you care about which original features matter (PCA removes that), you have few features already, you're using tree-based models (they handle high dimensions natively)

The canonical rule: tree-based models (Random Forest, XGBoost) handle high dimensions well — don't apply PCA before them. Distance-based models (SVM with RBF, KNN, K-Means) benefit significantly from dimensionality reduction.

🎉
Module 5 Complete!
Unsupervised methods covered. Next: the most impactful skill in real ML — building better features.
Module 6: Feature Engineering → Course Home
🧩 Module 5 Check
5 questions · instant feedback
1. What does "explained variance ratio" in PCA tell you?
2. Why must you scale features before applying PCA?
3. Which dimensionality reduction method is safest to use as preprocessing before training a supervised model?
4. The "curse of dimensionality" primarily explains why which type of model degrades most in high dimensions?
5. You have 200 features and want to train an SVM. Which preprocessing approach is best?