Linear Algebra in Action with NumPy

Learn how to represent and manipulate vectors and matrices with NumPy, compute dot products and norms, perform matrix multiplication, and apply decompositions like eigendecomposition and SVD that underpin core ML algorithms.

Loading video…

What you'll be able to do

  • Create and manipulate vectors and matrices using NumPy arrays
  • Compute dot products, norms, and cosine similarity to measure vector relationships
  • Perform matrix multiplication, transposition, and inversion correctly
  • Apply broadcasting to write efficient, vectorized linear algebra code
  • Use eigendecomposition and SVD to understand dimensionality reduction techniques like PCA
  • Connect linear algebra operations to real ML tasks such as linear regression

Why Linear Algebra Matters for ML

Nearly every machine learning model is built on linear algebra. Data is stored as vectors and matrices, model parameters are vectors, and training involves matrix operations. NumPy gives us fast, vectorized tools to do this math efficiently in Python.

Vectors and Matrices

A vector is a 1-D array of numbers; a matrix is a 2-D array. In NumPy both are ndarray objects.

import numpy as np
v = np.array([1, 2, 3])          # shape (3,)
M = np.array([[1, 2], [3, 4]])    # shape (2, 2)
print(v.shape, M.shape)

The .shape attribute is your best friend—most bugs are shape mismatches.

Dot Products and Norms

The dot product sums element-wise products and measures alignment between vectors:

a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
print(np.dot(a, b))   # 32
print(a @ b)          # 32 (preferred operator)

The norm (length/magnitude) of a vector:

np.linalg.norm(a)     # sqrt(1+4+9) = 3.742

Cosine similarity measures the angle between vectors (used in recommendations and NLP):

cos = (a @ b) / (np.linalg.norm(a) * np.linalg.norm(b))

Matrix Multiplication

Matrix multiplication combines rows and columns. For A @ B, the inner dimensions must match: (m, n) @ (n, p) -> (m, p).

A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
print(A @ B)          # matrix product
print(A * B)          # element-wise (NOT the same!)
print(A.T)            # transpose

This is exactly how a neural network layer computes outputs = inputs @ weights + bias.

Broadcasting

Broadcasting lets NumPy operate on arrays of different shapes without explicit loops, by stretching smaller arrays.

X = np.array([[1, 2, 3], [4, 5, 6]])
mean = X.mean(axis=0)        # shape (3,)
X_centered = X - mean        # broadcasts row-wise

This is the foundation of feature normalization.

Solving Linear Systems

Linear regression’s closed-form solution uses matrix inversion. Prefer np.linalg.solve over computing the inverse directly for stability.

# Solve Ax = b
A = np.array([[3, 1], [1, 2]])
b = np.array([9, 8])
x = np.linalg.solve(A, b)    # [2., 3.]

Matrix Decompositions

Decompositions break a matrix into useful factors.

Eigendecomposition finds vectors that only get scaled (not rotated) by a matrix. It powers PCA on covariance matrices.

values, vectors = np.linalg.eig(A)

Singular Value Decomposition (SVD) factors any matrix A = U S Vᵀ. It underpins PCA, recommender systems, and data compression.

Xc = X - X.mean(axis=0)          # PCA requires centered data
U, S, Vt = np.linalg.svd(Xc, full_matrices=False)
# columns of Vt.T are principal directions; S**2/(n-1) are the explained variances

The largest singular values capture the most variance—keeping only the top ones gives dimensionality reduction. Note: the variance interpretation only holds after mean-centering (sklearn’s PCA centers the data internally for exactly this reason).

Putting It Together: Linear Regression

# Least squares with an intercept (no need to form XᵀX explicitly)
Xb = np.hstack([np.ones((X.shape[0], 1)), X])   # add intercept
w, *_ = np.linalg.lstsq(Xb, y, rcond=None)       # QR/SVD-based; more stable than solving Xt@X

Forming XᵀX squares the condition number; lstsq (QR/SVD) is numerically preferable. This trains a linear regression model—pure linear algebra.

Key Takeaways

  • Always check shapes; use @ for matrix multiply, * for element-wise.
  • Use np.linalg.solve instead of explicit inverses.
  • SVD and eigendecomposition are the math behind PCA and many ML methods.

Check your understanding

6 questions — answer to see instant feedback.

Q1. Which operator performs matrix multiplication in NumPy?
The @ operator performs matrix multiplication, while * does element-wise multiplication.
Q2. What does np.linalg.norm(v) compute for a vector v?
The norm computes the magnitude or length of a vector, e.g., the Euclidean norm sqrt(sum of squares).
Q3. For A @ B with A of shape (m, n), what shape must B have?
The inner dimensions must match: A is (m, n), so B must be (n, p), giving a result of shape (m, p).
Q4. Why prefer np.linalg.solve(A, b) over computing np.linalg.inv(A) @ b?
Solving the system directly is more numerically stable and faster than explicitly forming the inverse.
Q5. Which decomposition factors any matrix into U S Vᵀ and underpins PCA and recommender systems?
Answer:SVD (Singular Value Decomposition)
SVD factors any matrix A into U, S, and Vᵀ; its top singular values capture the most variance, enabling dimensionality reduction.
Q6. In one short phrase, what does broadcasting let you do in NumPy?
Answer:Operate on arrays of different shapes without explicit loops
Broadcasting automatically stretches smaller arrays to compatible shapes, enabling efficient vectorized operations like subtracting a mean vector from every row.
Ask the AI tutor about this lessonStuck or curious? Ask a question and get a grounded answer.

The tutor answers from this lesson's material and can make mistakes — verify anything important.