The Singular Value Decomposition (SVD) is arguably the most important result in applied linear algebra. While eigendecomposition works only for special square matrices, SVD works for any matrix—tall, wide, square, singular, or non-singular. It provides a way to “see” the underlying structure of data by decomposing it into its most significant components.
The Geometric Idea
Every matrix represents a linear map. SVD says that any such map can be broken down into three simple steps:
A rotation in the input space ().
A scaling along the principal axes ().
A rotation in the output space ().
Mathematically:
: Columns are “right singular vectors.” They define an orthonormal basis in the input space.
: A diagonal matrix of “singular values” . These tell you the “strength” or “gain” of the matrix in each direction.
: Columns are “left singular vectors.” They define an orthonormal basis in the output space.
Data Compression: The Best Low-Rank Approximation
The real magic of SVD is the Eckart-Young Theorem. It states that if you want the best possible “summary” of a matrix using only dimensions (where is less than the rank of ), the answer is to keep only the largest singular values and their corresponding vectors.
This is how image compression and noise reduction work. By throwing away small singular values, we lose “noise” or “unimportant detail” but keep the overall structure.
Interactive Lab
import numpy as np
# Create a 'rank-2' matrix with some noise
# This matrix has 100 rows (data points) and 5 columns (features)
np.random.seed(42)
base_data = np.random.randn(100, 2) @ np.random.randn(2, 5)
noise = 0.1 * np.random.randn(100, 5)
A = base_data + noise
# Perform SVD
U, s, Vt = np.linalg.svd(A, full_matrices=False)
print("Singular Values:", s)
# Construct Rank-2 approximation
k = 2
Sk = np.diag(s[:k])
Ak = U[:, :k] @ Sk @ Vt[:k, :]
# Calculate Error
full_norm = np.linalg.norm(A, 'fro')
error_norm = np.linalg.norm(A - Ak, 'fro')
print(f"\nRelative Error of Rank-{k} approximation: {error_norm/full_norm:.4f}")
print(f"Original Rank: {np.linalg.matrix_rank(A)}")
print(f"Approximation Rank: {np.linalg.matrix_rank(Ak)}")
python
1import numpy as np
2
3# Create a 'rank-2' matrix with some noise
4# This matrix has 100 rows (data points) and 5 columns (features)
The Pseudoinverse: Solving the Solvable and Unsolvable
When a matrix is not invertible (e.g., it is not square or is singular), we can still “solve” using the Moore-Penrose Pseudoinverse .
Using SVD, the pseudoinverse is trivial to compute:
where is formed by transposing and replacing every non-zero with .
The solution is the “best” solution in two senses:
It minimizes the error (Least Squares).
If there are many such solutions, it picks the one with the smallest length .
Exercises
Knowledge Check
In an SVD decomposition A = UΣVᵀ, what do the values in Σ represent?
Answer: The scaling factors along the principal axes.
Σ is a diagonal matrix of singular values. They represent the 'gain' or stretching factor the matrix applies in the directions defined by the singular vectors.
In an SVD decomposition A = UΣVᵀ, what do the values in Σ represent?
Knowledge Check
If a matrix has singular values [100, 50, 0.01, 0.0001], which singular values should we keep for a good low-rank approximation?
Answer: Only [100, 50].
Values that are significantly smaller than the others can often be treated as noise or redundant information. Keeping only the large singular values provides a compressed version of the data.
If a matrix has singular values [100, 50, 0.01, 0.0001], which singular values should we keep for a good low-rank approximation?
Knowledge Check
What is the relationship between singular values and the eigenvalues of AᵀA?
Answer: The singular values are the square roots of the eigenvalues of AᵀA.
AᵀA is a symmetric positive semi-definite matrix. Its eigenvalues are the squares of the singular values of A.
What is the relationship between singular values and the eigenvalues of AᵀA?