Answer

PCA, eigenvectors and eigenvalues explained in plain language

Inspired by a question on Cross Validated ·

pcanormalization

The short answer

PCA rotates your data onto new axes (principal components): the first captures the most spread, the second the most of what is left at right angles to the first, and so on. The eigenvectors of the correlation or covariance matrix give the directions of these axes, and each eigenvalue is the variance along its axis. If a few eigenvalues are large, a few components summarize many variables.

The idea without the algebra

Picture a cloud of points: every person in a study measured on two variables, such as height and weight. The cloud is not round. It is stretched along a diagonal, because tall people tend to be heavier. If you could only describe each person with one number, the most informative single number would be their position along that long diagonal, roughly 'overall size'. Their position across the diagonal, 'heavier or lighter than expected for their height', is the second, smaller piece of information.

PCA does exactly this, for any number of variables. It finds the direction in which the cloud is longest and calls it the first principal component. Then it finds the longest direction at right angles to the first, and so on, until there are as many components as variables. Nothing is lost at that point: it is the same cloud seen from a better angle. The gain comes when you notice that the last few directions are thin, so you can drop them and keep most of the information in far fewer numbers.

Where eigenvectors and eigenvalues come in

The shape of the cloud is summarized by its covariance matrix, or by its correlation matrix if the variables are standardized first. A matrix acts on directions: push a direction through it and it usually comes out pointing somewhere else. An eigenvector is a special direction that comes out pointing the same way, only stretched. The eigenvalue is how much it gets stretched.

For a covariance or correlation matrix, those special directions are the axes of the cloud, and the stretch factor equals the variance of the data along that axis. So:

With standardized variables each variable contributes a variance of 1, so the eigenvalues add up to the number of variables. An eigenvalue above 1 means the component carries more variance than any single original variable.

See it in R and Python

This simulation creates six test scores for 300 people. Three depend on a verbal ability and three on a numeric ability, and the two abilities are correlated. PCA is done twice in R: by hand with eigen() on the correlation matrix, and with base R's prcomp(). The Python tab does the same with NumPy.

R

set.seed(2691)
n <- 300
# Two related hidden abilities drive six test scores
verbal  <- rnorm(n)
numeric <- 0.5 * verbal + rnorm(n, sd = 0.87)
X <- data.frame(
  vocab   = verbal  + rnorm(n, sd = 0.5),
  reading = verbal  + rnorm(n, sd = 0.5),
  writing = verbal  + rnorm(n, sd = 0.6),
  algebra = numeric + rnorm(n, sd = 0.5),
  geometry= numeric + rnorm(n, sd = 0.5),
  stats   = numeric + rnorm(n, sd = 0.6)
)

# PCA by hand: eigen-decomposition of the correlation matrix
e <- eigen(cor(X))
round(e$values, 3)                       # eigenvalues = variance of each component
round(e$values / sum(e$values), 3)       # proportion of variance explained
round(cumsum(e$values) / ncol(X), 3)     # cumulative proportion

# The same thing with prcomp (standardized variables)
p <- prcomp(X, scale. = TRUE)
round(p$sdev^2, 3)                       # identical eigenvalues
round(p$rotation[, 1:2], 3)              # eigenvectors = loadings (signs are arbitrary)

# Scores: each person's position along the new axes
scores <- scale(X) %*% e$vectors
round(apply(scores, 2, var), 3)          # variances equal the eigenvalues
round(cor(scores[, 1], scores[, 2]), 3)  # components are uncorrelated

Python

import numpy as np

rng = np.random.default_rng(2691)
n = 300
# Two related hidden abilities drive six test scores
verbal = rng.normal(0, 1, n)
numeric = 0.5 * verbal + rng.normal(0, 0.87, n)
X = np.column_stack([
    verbal + rng.normal(0, 0.5, n),    # vocab
    verbal + rng.normal(0, 0.5, n),    # reading
    verbal + rng.normal(0, 0.6, n),    # writing
    numeric + rng.normal(0, 0.5, n),   # algebra
    numeric + rng.normal(0, 0.5, n),   # geometry
    numeric + rng.normal(0, 0.6, n),   # stats
])

# PCA by hand: eigen-decomposition of the correlation matrix
values, vectors = np.linalg.eigh(np.corrcoef(X, rowvar=False))
order = np.argsort(values)[::-1]              # eigh sorts ascending; flip to largest first
values, vectors = values[order], vectors[:, order]
print(np.round(values, 3))                    # eigenvalues = variance of each component
print(np.round(values / values.sum(), 3))     # proportion of variance explained
print(np.round(np.cumsum(values) / X.shape[1], 3))
print(np.round(vectors[:, :2], 3))            # eigenvectors = loadings (signs are arbitrary)

# Scores: each person's position along the new axes
Z = (X - X.mean(axis=0)) / X.std(axis=0, ddof=1)
scores = Z @ vectors
print(np.round(scores.var(axis=0, ddof=1), 3))   # variances equal the eigenvalues
print(round(np.corrcoef(scores[:, 0], scores[:, 1])[0, 1], 3))  # uncorrelated

The figures below come from one seeded run of the R code. Python uses a different random number generator, so its figures differ slightly, but the pattern is the same (its eigenvectors may also come out with the opposite sign, which changes nothing).

Practical points

How to report a principal component analysis in APA style (7th edition)

In the method section, say which variables were entered, whether PCA used the correlation or covariance matrix, whether any rotation was applied, and how you decided how many components to keep. Using the example above:

"A principal component analysis of the six standardized test scores (N = 300) yielded two components with eigenvalues greater than 1. The first component (eigenvalue = 3.52) explained 58.7% of the variance and had similar positive weights on all tests; the second (eigenvalue = 1.56) explained a further 25.9% and contrasted verbal with numeric tests. Together the two components explained 84.6% of the variance."

Put the full set of weights or loadings in a table, with one row per variable, one column per retained component, and rows at the bottom for the eigenvalue and percentage of variance. State in a table note whether the values are eigenvector weights or loadings.

Related tools and guides

More answered questions

Working with your own data?

General answers only go so far. Send us your situation and we'll reply by email within two business days.

Ask your question

Written by AskStats with AI assistance. This is general information, not advice for your specific data or study. When the results matter, check your approach with a qualified statistician.