Skip to content
learn
  1. Learn
  2. Machine Learning
  3. Unsupervised Learning

Machine Learning ML-07.04

Principal Component Analysis

Find the directions where data varies most, project onto the top few, and read the explained variance ratio to see how much you kept. Plus whitening.

Intermediate 14 min Last reviewed

The big idea

A dataset with 64 features is a cloud of points in 64 dimensions. You cannot look at it, many models slow down on it, and a lot of those dimensions are near copies of each other. Most real data is like that: the points do not fill the space, they lie close to a much flatter shape inside it.

Principal Component AnalysisPrincipal Component Analysis: a linear method that finds orthogonal directions of maximum variance in the data and projects the data onto the top few of them. (PCA) finds that flatter shape when it is flat in a straight-line sense. Think of photographing a long, thin baguette. Shot end-on, it is a circle and you learn nothing. Shot from the side, one picture shows almost everything about it. PCA picks the camera angle that shows the most spread, then the next best angle at right angles to the first, and so on.

You keep the first few angles and drop the rest. The explained variance ratioThe fraction of the data's total variance that lies along one principal component. Summed over the kept components, it tells you how much spread the reduced data retains. tells you exactly how much of the spread you kept. PCA is used for compression, for plotting high-dimensional data, for removing noise and for speeding up other models.

How it works

Two principal components of a tilted cloud Thirty centred points form a cloud stretched along a line tilted about 31 degrees upward. A glowing violet arrow PC1 points along the long direction, twice as long as the spread there. A shorter cyan arrow PC2 points at right angles, across the narrow direction. For every third point a pink line drops it at a right angle onto the dashed PC1 line, where a violet dot marks its projection. -4-2024-202feature 1 (centred)feature 2 (centred) PC1 PC2 Figure 1. PC1 runs along the longest spread, PC2 at right angles across it (arrows span two standard deviations). Projecting onto PC1 turns each 2D point into one number, here keeping 94 percent of the variance.

Step 1: Centre (and usually scale) the data

Subtract each feature's mean so the cloud sits around the origin. PCA measures spread around the centre, so without this step the first component just points at the mean. If features use different units (metres and grams, say), also divide by each feature's standard deviation; otherwise the feature with the biggest numbers dominates every component.

Step 2: Find the direction of maximum variance

Pick a unit vector u. Each centred point x lands on the line through u at position u . x, its projectionThe coordinate of a point along a direction: the dot product of the point with a unit vector, which drops the point onto that line at a right angle.. The variance of those positions measures how much spread that direction captures:

where C is the covariance matrixA d by d matrix whose entry (j, k) is the average product of centred features j and k. The diagonal holds each feature's variance; off-diagonal entries show how features move together. of the data. The u that makes this as large as possible is the eigenvector of C with the largest eigenvalue, and the eigenvalue is the variance it captures. That eigenvector is the first principal componentOne of the orthogonal directions found by PCA, ordered by how much variance the data has along it. They are the eigenvectors of the covariance matrix. (PC1).

The rest follow the same rule: PC2 is the direction of most remaining variance at right angles to PC1, and so on. All of them are eigenvectors of C, sorted by eigenvalue. In practice libraries compute them with the SVD of the centred data matrix, which is faster and more stable than forming C.

Step 3: Read the explained variance ratio

Each eigenvalue divided by their sum is that component's explained variance ratio. On the 500 tilted 2D points in the code, the eigenvalues are 3.692 and 0.185. The total is 3.877, so PC1 explains 3.692 / 3.877 = 95.2 percent and PC2 the remaining 4.8 percent. Dropping PC2 loses under 5 percent of the spread.

Step 4: Project to k dimensions, and reconstruct

Stack the top k components as columns of a d by k matrix W. Then:

z is the compressed point with k numbers instead of d. x-hat maps it back to the original space. The squared distance between x and x-hat is exactly the variance you dropped, so PCA is also the best linear compression in the least-squares sense.

Cumulative explained variance on digit images A rising curve for 8 by 8 handwritten digit images with 64 pixel features. Two components keep 28.5 percent of the variance, the curve climbs steeply then flattens, crossing a green dashed 90 percent line at 21 components, and reaches 98.8 percent at 40 components and 100 percent near 50. 081624324048566400.20.40.60.81number of components keptcumulative variance kept 2 PCs: 28.5% 21 PCs: 90% 40 PCs: 98.8% Figure 2. Cumulative explained variance for the 64-pixel digits in the code. The curve bends early: 21 of 64 components keep 90 percent of the variance, and the last dozen add almost nothing.

Step 5: Choose k

Common rules: keep enough components to reach 90 or 95 percent of the variance; look for the elbow in a scree plotA plot of each principal component's explained variance in order. An elbow where the curve flattens suggests how many components carry signal.; or, best of all, treat k as a hyperparameter and pick the value that gives the best validation score for the model that uses the components. On the digits, 21 components reach 90 percent and 29 reach 95 percent.

Try it

This interactive needs JavaScript. The diagrams and text above cover the same idea.

Try this:

  1. Drag the angle slowly from 0 to 179 degrees. Where is the captured share largest, and where is it smallest? How far apart are those two angles?
  2. Set the axis at right angles to PC1. The share you see is what PC2 would explain. Add it to PC1's share. What do you get, and why?
  3. Watch the violet projected dots as you turn the axis. When the variance is highest, are the dots more spread out or more bunched?

Going deeper

Code: PCA by hand, whitening and digits

pca.pyruns with python3 + numpy + scikit-learn
import numpy as np
from sklearn.datasets import load_digits
from sklearn.decomposition import PCA
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler

# PCA by hand on 2D data: eigenvectors of the covariance matrix
rng = np.random.default_rng(0)
X = rng.multivariate_normal([0, 0], [[3, 1.5], [1.5, 1]], 500)
Xc = X - X.mean(0)
vals, vecs = np.linalg.eigh(np.cov(Xc.T))
order = vals.argsort()[::-1]
vals, vecs = vals[order], vecs[:, order]
print("eigenvalues (variance along each PC):", np.round(vals, 3))
print("explained variance ratio:", np.round(vals / vals.sum(), 3))
print("PC1 direction:", np.round(vecs[:, 0], 3))
p = PCA().fit(X)
print("sklearn agrees:", np.round(p.explained_variance_, 3), np.round(np.abs(p.components_[0]), 3))

# Whitening: decorrelate and scale to unit variance
Z = PCA(whiten=True).fit_transform(X)
print("covariance after whitening:", np.round(np.cov(Z.T), 3).tolist())

# 8x8 digit images: 64 pixel features
D, y = load_digits(return_X_y=True)
pca = PCA().fit(D)
cum = np.cumsum(pca.explained_variance_ratio_)
for k in [2, 10, 20, 40]:
    print(f"{k:>2} components keep {cum[k - 1]:.1%} of the variance")
print(f"components needed for 90%: {np.searchsorted(cum, 0.90) + 1}, for 95%: {np.searchsorted(cum, 0.95) + 1}")

for k in [5, 20, 64]:
    rec = PCA(k).fit(D)
    err = np.mean((D - rec.inverse_transform(rec.transform(D))) ** 2)
    acc = cross_val_score(make_pipeline(StandardScaler(), PCA(k), LogisticRegression(max_iter=2000)), D, y, cv=5).mean()
    print(f"k={k:>2}: reconstruction MSE {err:6.2f}, classifier accuracy {acc:.3f}")

Output

eigenvalues (variance along each PC): [3.692 0.185]
explained variance ratio: [0.952 0.048]
PC1 direction: [-0.882 -0.47 ]
sklearn agrees: [3.692 0.185] [0.882 0.47 ]
covariance after whitening: [[1.0, 0.0], [0.0, 1.0]]
 2 components keep 28.5% of the variance
10 components keep 73.8% of the variance
20 components keep 89.4% of the variance
40 components keep 98.8% of the variance
components needed for 90%: 21, for 95%: 29
k= 5: reconstruction MSE   8.54, classifier accuracy 0.771
k=20: reconstruction MSE   1.98, classifier accuracy 0.899
k=64: reconstruction MSE   0.00, classifier accuracy 0.920

The eigenvalues from the covariance matrix match scikit-learn's explained_variance_ exactly. The sign of a component is arbitrary (here numpy returns (-0.882, -0.47) and scikit-learn (0.882, 0.47)): u and -u describe the same line, so never read meaning into the sign.

Whitening

WhiteningA transform that decorrelates features and scales each to unit variance, so the covariance matrix becomes the identity. In PCA it means dividing each component score by the square root of its eigenvalue. goes one step further: after projecting, divide each component by the square root of its eigenvalue. The result has no correlation between features and unit variance in every direction, which the code confirms with a covariance of exactly [[1, 0], [0, 1]]. Some algorithms (independent component analysis, some older image pipelines) need whitened inputs. The catch: whitening blows up tiny low-variance directions, which are often noise, to the same size as the signal, so combine it with dropping the smallest components.

Compression versus accuracy

On the digits, keeping 5 components gives a reconstruction error (mean squared, pixel values from 0 to 16) of 8.54 and a classifier accuracy of 0.771. With 20 components the error falls to 1.98 and accuracy rises to 0.899, close to the 0.920 from all 64 pixels. Fewer features train faster and can help models that overfit, but PCA picks directions by variance, not by usefulness for your labels. A low-variance direction can be the one that separates the classes, and PCA will throw it away.

Limits

  • Linear only. PCA finds flat subspaces. Data on a curved surface, like a rolled-up sheet, needs a non-linear method ( t-SNE and UMAP for visualization, autoencoders for learned compression).
  • Sensitive to scale and outliers. One huge outlier can swing PC1 towards itself, because variance squares distances.
  • Components are mixtures. Each component blends all original features, which makes it harder to explain than picking a subset of features.
  • Fit on training data only. Fit the PCA inside your pipeline on the training fold, then apply it to validation and test data, or you leak information.

Trade-offs

OptionWins whenLoses when
PCA Correlated numeric features, linear structure, fast compression or denoising Curved structure; the useful signal has low variance
Feature selection You need to explain the model in terms of original features Many weak, correlated features that are useful together
t-SNE or UMAP 2D pictures of clusters in high-dimensional data Compression for modelling; distances between clusters
Autoencoder Large data with non-linear structure, such as images Small data; needs training and tuning

Common mistakes

  • Running PCA on unscaled features with different units, so the largest-unit feature becomes PC1.
  • Forgetting to centre the data when implementing PCA by hand.
  • Fitting PCA on the whole dataset before the train-test split, leaking test information.
  • Assuming high-variance directions are the predictive ones; the class signal can hide in a small component.
  • Reading meaning into the sign of a component, which is arbitrary.

In the wild

PCA is one of the most used tools in data work. Geneticists project hundreds of thousands of genetic markers onto two components, and the plot often lines up with geography. Face recognition's classic "eigenfaces" were the principal components of face images. In finance, the first component of many stock returns behaves like the overall market. In ML pipelines, PCA compresses embeddings before a nearest-neighbour index, speeds up models on wide tabular data, and is often the first plot you make of a new high-dimensional dataset.

Check yourself

  1. What is the first principal component?

    Show answer

    B. The direction along which the centred data has the largest variance PC1 is the unit vector u that maximises the variance of the projections u . x, which is the top eigenvector of the covariance matrix. PCA never looks at labels.

  2. Eigenvalues of a 3-feature covariance matrix are 6, 3 and 1. What share of the variance do the first two components keep?

    Show answer

    B. 90% The total is 10. The first two hold 6 + 3 = 9, so 90 percent. The third explains the remaining 10 percent.

  3. You run PCA on height in centimetres and income in dollars without scaling. What happens?

    Show answer

    B. PC1 is almost entirely income, because its numbers vary most Variance depends on units. Income varies by thousands, height by tens, so income dominates. Standardize first when units differ.

  4. After PCA to 20 of 64 components the classifier loses a little accuracy. Why is that possible even though 89 percent of the variance is kept?

    Show answer

    B. The dropped low-variance directions can still carry class information PCA ranks directions by spread, not by usefulness for the labels. Some discriminative detail can live in small components.

  5. What does whitening do to the data's covariance matrix?

    Show answer

    B. Makes it the identity: uncorrelated features with unit variance Whitening rotates onto the principal components and divides each by its standard deviation, so the covariance becomes the identity, as in the code.

Recap

  • PCA finds orthogonal directions of maximum variance: the eigenvectors of the covariance matrix, ordered by eigenvalue.
  • Centre the data, and scale it when features have different units.
  • Each component's explained variance ratio is its eigenvalue over the total; the cumulative curve tells you how many to keep.
  • Projection z = W^T (x - mu) compresses; mu + W z reconstructs, and the error equals the variance dropped.
  • Whitening scales components to unit variance; PCA is linear and ignores labels, so high variance is not the same as useful.

Get new lessons by email

Get new posts on backend and AI internals. No spam, unsubscribe anytime.

Your email is only used to send new posts. Privacy