MediumLinear Algebra

Linear Regression Closed Form

Linear Algebra · Classic ML

Medium

Problem

Linear regression finds the weight vector that minimizes the sum of squared errors between predictions and targets. The closed-form solution (the normal equation) computes the optimal weights directly using matrix algebra, without iterative optimization.

Given a feature matrix X and a target vector y, compute the weight vector w using the normal equation.

Formula

w = (X^T X)^{-1} X^T y

Where X is the n \times d feature matrix (n samples, d features), y is the n-dimensional target vector, and w is the d-dimensional weight vector.

Return the weight vector as a list of floats with one value per feature column.

Theory

Linear regression finds the best straight line (or hyperplane) through data points. Given input features X and target values y, we want to find weights w such that:

Xw \approx y

The "best" weights minimize the sum of squared errors between predictions and actual values.


Setting Up the Optimization

We want to minimize the squared error:

L(w) = ||Xw - y||^2 = (Xw - y)^T(Xw - y)

This is a quadratic function in w, shaped like a bowl. There is a unique minimum (when X^T X is invertible), and we can find it exactly by setting the gradient to zero.


Deriving the Normal Equation

Step 1: Expand the loss

L(w) = (Xw - y)^T(Xw - y)

= w^T X^T X w - 2w^T X^T y + y^T y

Step 2: Take the gradient with respect to w

\nabla_w L = 2 X^T X w - 2 X^T y

Step 3: Set the gradient to zero

2 X^T X w - 2 X^T y = 0

X^T X w = X^T y

Step 4: Solve for w

w = (X^T X)^{-1} X^T y

This is the normal equation, the closed-form solution to linear regression.


Understanding Each Component

X^T X (the Gram matrix):

(X^T X)^{-1}:

X^T y:


A Numerical Example

Data: 3 samples, 2 features

X = \begin{bmatrix} 1 & 1 \\ 1 & 2 \\ 1 & 3 \end{bmatrix}, \quad y = \begin{bmatrix} 1 \\ 2 \\ 2 \end{bmatrix}

The first column is all ones (the intercept term).

Step 1: Compute X^T X

X^T X = \begin{bmatrix} 1 & 1 & 1 \\ 1 & 2 & 3 \end{bmatrix} \begin{bmatrix} 1 & 1 \\ 1 & 2 \\ 1 & 3 \end{bmatrix} = \begin{bmatrix} 3 & 6 \\ 6 & 14 \end{bmatrix}

Step 2: Compute X^T y

X^T y = \begin{bmatrix} 1 & 1 & 1 \\ 1 & 2 & 3 \end{bmatrix} \begin{bmatrix} 1 \\ 2 \\ 2 \end{bmatrix} = \begin{bmatrix} 5 \\ 11 \end{bmatrix}

Step 3: Compute (X^T X)^{-1}

For a 2 \times 2 matrix:

\det(X^T X) = 3 \cdot 14 - 6 \cdot 6 = 42 - 36 = 6

(X^T X)^{-1} = \frac{1}{6} \begin{bmatrix} 14 & -6 \\ -6 & 3 \end{bmatrix} = \begin{bmatrix} 7/3 & -1 \\ -1 & 1/2 \end{bmatrix}

Step 4: Compute w

w = (X^T X)^{-1} X^T y = \begin{bmatrix} 7/3 & -1 \\ -1 & 1/2 \end{bmatrix} \begin{bmatrix} 5 \\ 11 \end{bmatrix} = \begin{bmatrix} 35/3 - 11 \\ -5 + 11/2 \end{bmatrix} = \begin{bmatrix} 2/3 \\ 1/2 \end{bmatrix}

The regression line is: \hat{y} = \frac{2}{3} + \frac{1}{2}x


When Does This Work?

Invertibility requirement:

(X^T X)^{-1} exists when X^T X is invertible, which requires:

Perfect multicollinearity:

If two features are perfectly correlated (e.g., one is a scaled version of the other), X^T X is singular. The system has infinitely many solutions.


Numerical Stability Concerns

Condition number:

Even when X^T X is technically invertible, it may be ill-conditioned. A large condition number means:

Better approaches:

In practice, avoid computing (X^T X)^{-1} directly. Instead:


Adding Regularization

To handle multicollinearity or prevent overfitting, add a regularization term:

Ridge regression (L2):

w = (X^T X + \lambda I)^{-1} X^T y

The added \lambda I makes the matrix invertible and shrinks weights toward zero.

This still has a closed form! Unlike Lasso (L1 regularization), which requires iterative optimization.


Computational Complexity

For small d (few features), this is fast. For large d, iterative methods like gradient descent may be preferred.


Connection to Projection

Geometrically, Xw is the projection of y onto the column space of X. The normal equation finds the point in that subspace closest to y.

The residual y - Xw is orthogonal to all columns of X:

X^T(y - Xw) = X^T y - X^T X w = 0

This is exactly the normal equation rearranged!

Examples

Example 1

Input
X = [[1], [2], [3]], y = [2, 4, 6]
Output
[2.0]
Explanation
The single weight 2 exactly maps each feature value to its target.

Example 2

Input
X = [[1, 1], [1, 2], [1, 3]], y = [3, 5, 7]
Output
[1.0, 2.0]

Hints

  1. Convert X and y to float64 NumPy arrays.
  2. Apply matrix multiplication in the same order as the normal equation.

Requirements

Constraints

Starter Code

import numpy as np

def linear_regression_closed_form(X: list, y: list) -> list:
    """
    Returns the optimal weight vector as a list.
    """
    # Write code here
    pass

Test Cases

CaseMatches
1Dpublic
Biaspublic