Principal Component Analysis

Imagine a dataset with 10,000 gene-expression measurements per patient. Only a few hundred patients are available, though. Most of that variation is redundant. Genes co-express in pathways. The "true" degrees of freedom are far fewer than 10,000. Principal Component Analysis (PCA) finds the small set of directions in feature space. These directions capture as much of this variation as possible. This lets you compress, visualize, and denoise high-dimensional data without a label in sight. PCA is the oldest and most widely deployed method in unsupervised learning. It is embedded quietly inside preprocessing pipelines, compression codecs, finance risk models, and computer vision systems. It answers a deceptively simple question. If you are allowed only kk numbers to summarize each data point, which kk linear combinations of the original features preserve the most information? Information here is measured by variance. The answer turns out to be exactly computable. There is no iterative optimization, no local minima, no hyperparameter search. It works via an eigendecomposition of the covariance matrix. The big picture is that data with correlated features lives, approximately, on a lower-dimensional linear subspace. This subspace is embedded in the ambient space. PCA discovers this subspace by rotating the coordinate system. The rotation aligns it with the axes of maximal spread. These are the principal axes of the data's covariance ellipsoid. PCA then truncates to the top few axes. This single geometric idea supports dimensionality reduction and noise filtering. It also enables visualization of high-dimensional data in 2D or 3D. Additionally, it supports feature decorrelation before other algorithms, and compression. This article develops PCA from its variance-maximization objective. It derives the eigenvector solution rigorously. It gives working pseudocode and traces a full numerical example. It also situates PCA relative to its generalization, the Singular Value Decomposition. Finally, it connects PCA to its nonlinear successors in Manifold Learning and Nonlinear Dimensionality Reduction.

Key takeaways
  • PCA finds orthogonal directions (principal components) that successively maximize the variance of projected data.
  • The solution is the eigenvectors of the empirical covariance matrix, ordered by eigenvalue (explained variance).
  • Projecting onto the top kk eigenvectors gives the best rank-kk linear approximation in squared-error sense.
  • Complexity is O(np2+p3)O(np^2 + p^3) for nn points in pp dimensions; the p3p^3 eigendecomposition dominates when pp is large.
  • PCA requires centering (and often scaling) data first; it is sensitive to feature scale and outliers.
  • It is equivalent to the Singular Value Decomposition of the centered data matrix, which is the numerically preferred way to compute it.
The core insight

PCA rotates coordinates to the eigenvectors of the covariance matrix, ranking directions by variance so that keeping the top kk gives the best possible rank-kk linear summary of the data.

The idea

Let X∈Rn×pX \in \mathbb{R}^{n \times p} be a data matrix of nn observations in pp dimensions, with rows xi⊤x_i^\top. Assume the data is centered, meaning the column means have been subtracted so xˉ=1n∑ixi=0\bar{x} = \frac{1}{n}\sum_i x_i = 0. The empirical covariance matrix is

S=1n−1X⊤X∈Rp×p.S = \frac{1}{n-1} X^\top X \in \mathbb{R}^{p \times p}.

SS is symmetric and positive semi-definite. PCA seeks a unit vector w1∈Rpw_1 \in \mathbb{R}^p, ∥w1∥=1\|w_1\|=1, such that projecting each data point onto w1w_1 — computing the scalar score zi=xi⊤w1z_i = x_i^\top w_1 — maximizes the variance of the resulting scores {zi}\{z_i\}. This is the first principal component direction. Subsequent components w2,w3,…w_2, w_3, \ldots are chosen the same way, subject to being orthogonal to all previous directions, so that each new component captures the maximal remaining variance. The key terminology: wkw_k is the kk-th principal component (also called a loading vector or eigenvector); the projected value zi=xi⊤wkz_i = x_i^\top w_k is the score; the variance captured, λk\lambda_k, is the eigenvalue associated with wkw_k; and λk/∑jλj\lambda_k / \sum_j \lambda_j is the fraction of explained variance. Collecting the top kk components as columns of a matrix Wk∈Rp×kW_k \in \mathbb{R}^{p \times k}, the transformation Z=XWkZ = X W_k maps each observation to a kk-dimensional code, and XWkWk⊤X W_k W_k^\top reconstructs an approximation back in the original pp-dimensional space. Crucially, PCA is a linear, unsupervised, variance-based method — related to but distinct from methods built on Distance Metrics and Similarity Measures like multidimensional scaling, and it makes no use of labels, unlike supervised dimensionality reduction such as linear discriminant analysis. It assumes that variance is a good proxy for "information" and that the interesting structure is linear; when that assumption fails, nonlinear techniques discussed under Manifold Learning and Nonlinear Dimensionality Reduction become necessary.

How it works

Step 1 — Center (and optionally standardize) the data. Subtract the mean of each feature so the cloud of points is centered at the origin. If features are on very different scales (e.g., income in dollars vs. age in years), divide each feature by its standard deviation as well; this variant is PCA on the correlation matrix rather than the covariance matrix.

Step 2 — Compute the covariance matrix. S=1n−1X⊤XS = \frac{1}{n-1}X^\top X, a p×pp \times p symmetric matrix whose (j,k)(j,k) entry is the sample covariance between feature jj and feature kk.

Step 3 — Eigendecompose SS. Since SS is symmetric positive semi-definite, the spectral theorem guarantees a full set of real, non-negative eigenvalues λ1≥λ2≥⋯≥λp≥0\lambda_1 \ge \lambda_2 \ge \cdots \ge \lambda_p \ge 0 with a corresponding orthonormal set of eigenvectors w1,…,wpw_1, \ldots, w_p. These eigenvectors are exactly the principal component directions, and the eigenvalue λk\lambda_k equals the variance of the data when projected onto wkw_k.

Step 4 — Truncate. Keep the top kk eigenvectors (largest eigenvalues) forming WkW_k, chosen either as a fixed number or by requiring cumulative explained variance ∑i≤kλi/∑iλi\sum_{i\le k}\lambda_i / \sum_i \lambda_i to exceed a threshold (e.g., 95%).

Step 5 — Project / reconstruct. Compute scores Z=XWkZ = X W_k for compression or visualization, and reconstruct X^=ZWk⊤\hat{X} = Z W_k^\top as a denoised low-rank approximation. Why does maximizing variance under orthogonality yield eigenvectors of SS? Consider the first component: maximize Var(Xw)=w⊤Sw\mathrm{Var}(Xw) = w^\top S w subject to ∥w∥=1\|w\|=1. Using a Lagrange multiplier λ\lambda,

L(w,λ)=w⊤Sw−λ(w⊤w−1),\mathcal{L}(w, \lambda) = w^\top S w - \lambda(w^\top w - 1),

and setting the gradient to zero gives

∇wL=2Sw−2λw=0⟹Sw=λw.\nabla_w \mathcal{L} = 2Sw - 2\lambda w = 0 \quad\Longrightarrow\quad Sw = \lambda w.

So any stationary point ww must be an eigenvector of SS, and the variance achieved there is w⊤Sw=w⊤(λw)=λw^\top S w = w^\top(\lambda w) = \lambda. To maximize variance, pick the eigenvector with the largest eigenvalue. For the second component, maximize w⊤Sww^\top S w subject to ∥w∥=1\|w\|=1 and w⊥w1w \perp w_1; the same Lagrangian argument (with an added orthogonality multiplier) shows the optimum is the eigenvector with the next-largest eigenvalue, and inductively for all kk. This is precisely why the eigenvectors of SS, sorted by eigenvalue, solve the sequential variance-maximization problem exactly — no iterative search is needed in principle, though in practice numerical eigensolvers are themselves iterative. ``` ALGORITHM PCA(X, k) Input: X, an n × p data matrix (n samples, p features) k, target number of components (k <= p) Output: W_k (p × k matrix of principal directions) Z (n × k matrix of projected scores) explained_variance_ratio (length-k vector) // Step 1: center the data (mean-subtraction is mandatory) mu <- column_mean(X) // length-p vector Xc <- X - broadcast(mu) // n × p, mean-zero columns // (optional) standardize if feature scales differ wildly if standardize: sigma <- column_std(Xc) Xc <- Xc / broadcast(sigma) // Step 2: covariance matrix S <- (1 / (n - 1)) transpose(Xc) @ Xc // p × p, symmetric PSD // Step 3: eigendecomposition S = V diag(lambda) * V^T (lambda, V) <- eigendecompose(S) // lambda: length-p, V: p × p sort (lambda, V) by lambda descending // lambda_1 >= lambda_2 >= ... // Step 4: truncate to top k eigenvectors W_k <- V[:, 1..k] // p × k // Step 5: project Z <- Xc @ W_k // n × k total_var <- sum(lambda) explained_variance_ratio <- lambda[1..k] / total_var return W_k, Z, explained_variance_ratio

ALGORITHM RECONSTRUCT(Z, W_k, mu) // approximate original data from k-dimensional codes Xhat <- Z @ transpose(W_k) + broadcast(mu) return Xhat ```

Figure
The covariance ellipsoid: PCA rotates axes to align with directions of maximal spread
Original coordinates (x1, x2) x1 x2 w1 (λ1, top var.) w2 (λ2) rotate to eigenbasis Principal component axes PC1 PC2 PC1 (red) is the direction of largest variance; PC2 (green) is orthogonal, capturing what remains.

Complexity & correctness

Time complexity. Forming the covariance matrix S=X⊤X/(n−1)S = X^\top X / (n-1) costs O(np2)O(np^2) (a p×np \times n times n×pn \times p matrix product). Eigendecomposing the resulting p×pp \times p symmetric matrix costs O(p3)O(p^3) using standard dense methods (e.g., the symmetric QR algorithm after tridiagonalization). Total time is

O(np2+p3).O(np^2 + p^3).

When n≫pn \gg p (many samples, few features), the np2np^2 term dominates and PCA scales linearly in nn. When pp is very large (e.g., p∼104p \sim 10^4 features, nn moderate), the p3p^3 eigendecomposition becomes the bottleneck, and it is standard to instead perform the Singular Value Decomposition of the centered data matrix directly, X=UΣV⊤X = U\Sigma V^\top, which costs O(min⁡(np2,n2p))O(\min(np^2, n^2p)) and avoids explicitly forming SS (better numerically conditioned, since squaring XX to get SS squares its condition number). The right singular vectors VV equal the PCA loadings WW, and singular values relate to eigenvalues via λi=σi2/(n−1)\lambda_i = \sigma_i^2/(n-1). If only the top k≪pk \ll p components are needed, randomized or Lanczos-based iterative methods compute them in roughly O(npk)O(npk) time, avoiding the full p3p^3 or np2np^2 cost entirely.

Space complexity. Storing XX costs O(np)O(np); storing SS costs O(p2)O(p^2); the output WkW_k and ZZ cost O(pk)O(pk) and O(nk)O(nk). Total space is O(np+p2)O(np + p^2), dominated by the covariance matrix when pp is large relative to nn.

Correctness (why top-kk eigenvectors are optimal, not just a heuristic). Two equivalent formal justifications exist: Variance-maximization view. As derived above, the sequential constrained-optimization argument shows each successive principal direction is exactly the eigenvector of the covariance matrix with the next-largest eigenvalue — this is not approximate, it follows directly from setting the Lagrangian gradient to zero and using the spectral theorem's guarantee of an orthonormal eigenbasis for any real symmetric matrix. Best low-rank approximation view (Eckart–Young). PCA is equivalent to finding the rank-kk subspace minimizing reconstruction error:

min⁡W:W⊤W=Ik  ∑i=1n∥xi−WW⊤xi∥2.\min_{W: W^\top W = I_k} \; \sum_{i=1}^n \|x_i - WW^\top x_i\|^2.

Expanding this objective and using ∥xi∥2=∥WW⊤xi∥2+∥xi−WW⊤xi∥2\|x_i\|^2 = \|WW^\top x_i\|^2 + \|x_i - WW^\top x_i\|^2 (Pythagoras, since WW⊤xiWW^\top x_i is an orthogonal projection), minimizing reconstruction error is equivalent to maximizing ∑i∥W⊤xi∥2=trace(W⊤SW)(n−1)\sum_i \|W^\top x_i\|^2 = \mathrm{trace}(W^\top S W)(n-1), the total projected variance. So variance-maximization and squared-error-minimization are the same objective viewed from two sides — this is why PCA is simultaneously "the projection that preserves the most variance" and "the best possible linear compression under squared error," a fact formalized generally by the Eckart–Young theorem for the Singular Value Decomposition.

Honest tradeoffs.

  • PCA only captures linear structure; data on a curved manifold (e.g., a Swiss roll) will not be well summarized by a few linear directions, motivating Manifold Learning and Nonlinear Dimensionality Reduction.
  • PCA is sensitive to the scale of features — a feature measured in millimeters will dominate variance over one measured in kilometers unless standardized.
  • PCA is sensitive to outliers, since variance (a squared quantity) is heavily influenced by extreme points; robust variants (e.g., PCA on ranks, or robust covariance estimators) exist for contaminated data.
  • Interpretability of components can be poor: each principal component is a linear combination of all original features, unlike sparse or interpretable feature-selection methods.

Worked example

Consider n=5n=5 two-dimensional points measuring (hours studied, exam score deviation from mean), already roughly linearly related:

Pointx1x_1 (hours)x2x_2 (score)
A12
B34
C55
D78
E99

Step 1 — center. Column means: xˉ1=5\bar{x}_1 = 5, xˉ2=5.6\bar{x}_2 = 5.6.

Pointx1−xˉ1x_1 - \bar x_1x2−xˉ2x_2 - \bar x_2
A-4-3.6
B-2-1.6
C0-0.6
D22.4
E43.4

Step 2 — covariance matrix. Compute entries with n−1=4n-1 = 4:

S11=(−4)2+(−2)2+02+22+424=404=10S_{11} = \frac{(-4)^2+(-2)^2+0^2+2^2+4^2}{4} = \frac{40}{4} = 10
S22=(−3.6)2+(−1.6)2+(−0.6)2+2.42+3.424=12.96+2.56+0.36+5.76+11.564=33.24=8.3S_{22} = \frac{(-3.6)^2+(-1.6)^2+(-0.6)^2+2.4^2+3.4^2}{4} = \frac{12.96+2.56+0.36+5.76+11.56}{4} = \frac{33.2}{4} = 8.3
S12=(−4)(−3.6)+(−2)(−1.6)+0(−0.6)+2(2.4)+4(3.4)4=14.4+3.2+0+4.8+13.64=364=9S_{12} = \frac{(-4)(-3.6)+(-2)(-1.6)+0(-0.6)+2(2.4)+4(3.4)}{4} = \frac{14.4+3.2+0+4.8+13.6}{4} = \frac{36}{4}=9

So

S=(10998.3).S = \begin{pmatrix} 10 & 9 \\ 9 & 8.3 \end{pmatrix}.

Step 3 — eigendecomposition. Solve det⁡(S−λI)=0\det(S - \lambda I) = 0:

(10−λ)(8.3−λ)−81=0(10-\lambda)(8.3-\lambda) - 81 = 0
λ2−18.3λ+83−81=0  ⟹  λ2−18.3λ+2=0.\lambda^2 - 18.3\lambda + 83 - 81 = 0 \;\Longrightarrow\; \lambda^2 - 18.3\lambda + 2 = 0.

Quadratic formula: λ=18.3±18.32−82=18.3±334.89−82=18.3±326.892=18.3±18.082\lambda = \dfrac{18.3 \pm \sqrt{18.3^2 - 8}}{2} = \dfrac{18.3 \pm \sqrt{334.89 - 8}}{2} = \dfrac{18.3 \pm \sqrt{326.89}}{2} = \dfrac{18.3 \pm 18.08}{2}.

λ1≈18.19,λ2≈0.11.\lambda_1 \approx 18.19, \qquad \lambda_2 \approx 0.11.

Total variance =λ1+λ2=18.3= \lambda_1 + \lambda_2 = 18.3 (matches trace of S=10+8.3S = 10 + 8.3, confirming the computation). Component 1 explains 18.19/18.3≈99.4%18.19/18.3 \approx 99.4\% of the variance — expected, since the data lies almost exactly on a line. For λ1≈18.19\lambda_1 \approx 18.19: solve (S−λ1I)w=0(S - \lambda_1 I)w = 0:

(10−18.19)w1+9w2=0  ⇒  −8.19w1+9w2=0  ⇒  w2=0.910 w1.(10 - 18.19)w_1 + 9 w_2 = 0 \;\Rightarrow\; -8.19 w_1 + 9 w_2 = 0 \;\Rightarrow\; w_2 = 0.910\,w_1.

Normalizing (1,0.910)(1, 0.910) to unit length (12+0.9102=1.348\sqrt{1^2+0.910^2}=1.348):

w1≈(0.742, 0.675).w_1 \approx (0.742,\ 0.675).

The second eigenvector is orthogonal: w2≈(−0.675, 0.742)w_2 \approx (-0.675,\ 0.742).

Step 4/5 — project. Score for point A, centered (−4,−3.6)(-4,-3.6):

zA=(−4)(0.742)+(−3.6)(0.675)=−2.968−2.430=−5.398.z_A = (-4)(0.742) + (-3.6)(0.675) = -2.968 - 2.430 = -5.398.
Pointcentered (x1,x2)(x_1,x_2)score on PC1
A(-4, -3.6)-5.40
B(-2, -1.6)-2.57
C(0, -0.6)-0.41
D(2, 2.4)3.10
E(4, 3.4)5.27

A single number per point (the PC1 score) now nearly reproduces the full 2D dataset, since PC1 captures 99.4% of the variance — exactly the compression PCA promises when features are strongly correlated.

Common pitfalls & traps

PitfallWhy it happensFix
Forgetting to center the dataUncentered PCA conflates the mean with variance direction, giving a first "component" that mostly points toward the centroidAlways subtract column means before computing covariance
Ignoring feature scaleA feature in different units dominates variance triviallyStandardize (z-score) features when units differ, i.e., use the correlation matrix
Treating PCA as feature selectionComponents are linear combinations of all features, not a subsetUse sparse PCA or explicit feature-selection methods if interpretability of individual features matters
Choosing kk arbitrarilyToo small kk discards signal; too large keeps noiseUse a scree plot / cumulative explained-variance threshold (e.g., 90–95%)
Assuming PCA finds "the" true underlying factorsPCA components are defined only up to sign and, for tied eigenvalues, rotation within the tied subspace; they need not align with causal or semantically meaningful axesInterpret components with domain knowledge, not blind trust in axis meaning
Applying PCA blindly to nonlinear dataCurved manifolds are not well approximated by a linear subspaceConsider kernel PCA or methods under Manifold Learning and Nonlinear Dimensionality Reduction
Computing SS then eigendecomposing on very high-dimensional dataForming X⊤XX^\top X squares the condition number and costs O(p3)O(p^3) unnecessarilyUse the Singular Value Decomposition of XX directly, or randomized/truncated SVD for top-kk only

Pioneers & history

Origins · 1 minKarl Pearson and how this was discovered
KP
Karl Pearson
1857–1936 · founder of mathematical statistics, University College London

Pearson introduced the geometric idea behind PCA in 1901, framing it as finding "lines and planes of closest fit" to a system of points — the same reconstruction-error minimization later formalized rigorously via the Eckart–Young theorem.

History
- 1901 — Karl Pearson formulates the problem of the best-fitting line/plane to a point cloud, the geometric precursor to PCA.
- 1933 — Harold Hotelling independently develops PCA in its modern statistical form, coining "principal components" and deriving them via eigenvectors of the covariance matrix.
- 1936 — Eckart and Young prove the optimal low-rank matrix approximation theorem, giving PCA its rigorous optimality justification via the SVD.
- 1987 — PCA popularized in computer vision and pattern recognition as computing power made eigendecomposition of large covariance matrices practical.
- 1991 — Turk and Pentland introduce "Eigenfaces," applying PCA to face recognition, a landmark application demonstrating PCA's power on real high-dimensional image data.

Where this matters

PCA underlies preprocessing in nearly every machine learning pipeline that touches high-dimensional numeric data. In computer vision, Eigenfaces and related PCA-based methods compressed face images for recognition before deep learning dominated the field. In genomics, PCA reduces gene-expression or SNP data with tens of thousands of dimensions to a handful of components used for visualization and population-structure detection. In finance, PCA on asset return covariance matrices extracts common risk factors (level, slope, and curvature of yield curves are classic PCA-derived factors). In signal processing and sensor networks, PCA denoises data by discarding low-variance components assumed to be noise. Recommendation systems and NLP pipelines use PCA (or its close relative, Singular Value Decomposition, applied directly as in latent semantic analysis) to compress sparse high-dimensional representations before feeding them to downstream models. Almost every exploratory-data-analysis workflow begins with a PCA scatterplot to visually inspect clusters in two or three dimensions before deploying more expensive supervised or clustering methods.

Ask the tutor: How does PCA change if I compute it via the SVD of the data matrix instead of eigendecomposing the covariance matrix directly, and why is that usually the better choice numerically?

Is PCA the same as the Singular Value Decomposition?

They are closely related but not identical. PCA is the statistical problem of finding variance-maximizing directions; SVD is the linear-algebra tool commonly used to solve it. Applying SVD to the centered data matrix X=UΣV⊤X = U\Sigma V^\top gives the PCA loadings directly as the columns of VV, and the eigenvalues of the covariance matrix relate to singular values via λi=σi2/(n−1)\lambda_i = \sigma_i^2/(n-1). Computing PCA via SVD directly on XX, rather than explicitly forming X⊤XX^\top X and eigendecomposing it, is numerically preferred because it avoids squaring the condition number of the data. See Singular Value Decomposition for the general matrix factorization this relies on.

How do I choose the number of components k?

Common approaches include: plotting cumulative explained variance and picking the smallest kk that exceeds a threshold like 90–95%; inspecting a "scree plot" of eigenvalues for an "elbow" where marginal variance gain drops sharply; and, when PCA is a preprocessing step for a supervised model, choosing kk by cross-validated downstream performance rather than variance alone. There is no universally correct kk — it depends on whether you prioritize compression, visualization (often k=2,3k=2,3), or preserving signal for a later model.

Does PCA assume the data is Gaussian?

No distributional assumption is required for PCA to be well-defined — it is purely a statement about second moments (variances and covariances) of the data, valid for any distribution. However, PCA's optimality as a summary of all the information in the data is strongest when the data truly is close to Gaussian, since a Gaussian distribution is fully characterized by its mean and covariance. For strongly non-Gaussian data (e.g., heavy-tailed or multimodal clusters), variance may not capture the most meaningful structure, and other unsupervised methods may be more appropriate.

Can PCA handle nonlinear structure, like data lying on a curved surface?

Not directly — PCA only finds linear subspaces, so data on a curved manifold (a classic example is the "Swiss roll") will be poorly summarized by a few principal components even though its intrinsic dimensionality is low. Kernel PCA extends the idea by implicitly mapping data into a higher-dimensional feature space via a kernel function before finding linear components there, capturing some nonlinear structure. For genuinely nonlinear manifolds, dedicated techniques described under Manifold Learning and Nonlinear Dimensionality Reduction, such as Isomap or t-SNE, are typically more effective.

What happens if two eigenvalues of the covariance matrix are equal?

When λi=λi+1\lambda_i = \lambda_{i+1}, the corresponding eigenvectors are not uniquely determined — any orthonormal basis of the two-dimensional eigenspace they span is an equally valid choice of principal components, since all directions in that subspace yield the same projected variance. This is a genuine, not pathological, indeterminacy: it reflects true rotational symmetry in the data's covariance structure along those axes. Numerically, eigensolvers will still return some valid orthonormal basis, but it may vary slightly between runs or implementations, so components in a near-tied eigenvalue regime should not be over-interpreted individually.

Why do principal components come out with an arbitrary sign?

If ww is a unit eigenvector of SS with eigenvalue λ\lambda, then −w-w is also a unit eigenvector with the same eigenvalue, since S(−w)=−Sw=−λw=λ(−w)S(-w) = -Sw = -\lambda w = \lambda(-w). Both directions capture identical variance, so the eigendecomposition is only defined up to sign. This means the sign of any PCA component (and hence whether its scores are positive or negative for a given cluster) is an artifact of the numerical solver and carries no meaning — always check sign conventions before interpreting "high" versus "low" scores across different runs or software libraries.

Is PCA useful as a preprocessing step even if I plan to use a nonlinear model later?

Yes, commonly for two reasons: reducing dimensionality can mitigate the curse of dimensionality and overfitting when the number of features is comparable to or exceeds the number of samples, and decorrelating features can improve numerical stability and convergence speed for many downstream algorithms. However, if the discriminative signal for a supervised task lies in a low-variance direction (which PCA would discard), unsupervised variance-based reduction can hurt performance — in such cases, supervised dimensionality reduction or careful cross-validated selection of kk is safer than applying PCA blindly.

Before this

Where this leads