Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Ordinary Least Squares

We’ve now spent a number of lectures exploring how to build effective models – we introduced the SLR and constant models, selected cost functions to suit our modeling task, and applied transformations to improve the linear fit.

Throughout all of this, we considered models of one feature (y^i=θ0+θ1xi\hat{y}_i = \theta_0 + \theta_1 x_i) or zero features (y^i=θ0\hat{y}_i = \theta_0). As data scientists, we usually have access to datasets containing many features. To make the best models we can, it will be beneficial to consider all of the variables available to us as inputs to a model, rather than just one. In today’s lecture, we’ll introduce multiple linear regression as a framework to incorporate multiple features into a model. We will also learn how to accelerate the modeling process – specifically, we’ll see how linear algebra offers us a powerful set of tools for understanding model performance.

OLS Problem Formulation

Multiple Linear Regression

Multiple linear regression is an extension of simple linear regression that adds additional features to the model. The multiple linear regression model takes the form:

y^=θ0 + θ1x1 + θ2x2 + ... + θpxp\hat{y} = \theta_0\:+\:\theta_1x_{1}\:+\:\theta_2 x_{2}\:+\:...\:+\:\theta_p x_{p}

Our predicted value of yy, y^\hat{y}, is a linear combination of the single observations (features), xix_i, and the parameters, θi\theta_i.

x⃗=[x1⋮xp]→[θ0θ1⋮θp]→y^\vec{x} = \begin{bmatrix} x_1 \\ \vdots \\ x_p \end{bmatrix} \quad\rightarrow\quad \begin{bmatrix} \theta_0 \\ \theta_1 \\ \vdots \\ \theta_p \end{bmatrix} \quad\rightarrow\quad \hat{y}

As an example, you could predict cats’ ages y^\hat{y} as a linear model of two features: length x1x_1 and weight x2x_2. This would give us the equation

y^=θ0+θ1x1+θ2x2\hat{y} = \theta_0 + \theta_1x_1 + \theta_2x_2

where θ0\theta_0 is the intercept, θ1\theta_1 is the parameter for length, and θ2\theta_2 is the parameter for weight.

We can explore this idea further by looking at a dataset containing aggregate per-player data from the 2018-19 NBA season, downloaded from Kaggle.

Loading...

Let’s say we are interested in predicting the number of points (PTS) an athlete will score in a basketball game this season.

Suppose we want to fit a linear model by using some characteristics, or features of a player. Specifically, we’ll focus on field goals, assists, and 3-point attempts.

  • FG, the average number of (2-point) field goals per game

  • AST, the average number of assists per game

  • 3PA, the average number of 3-point field goals attempted per game

Loading...

Because we are now dealing with many parameter values, we’ve collected them all into a parameter vector with dimensions (p+1)×1(p+1) \times 1 to keep things tidy. Remember that pp represents the number of features we have (in this case, 3).

θ=[θ0θ1⋮θp]\theta = \begin{bmatrix} \theta_{0} \\ \theta_{1} \\ \vdots \\ \theta_{p} \end{bmatrix}

We are working with two vectors here: a row vector representing the observed data, and a column vector containing the model parameters. The multiple linear regression model is equivalent to the dot (scalar) product of the observation vector and parameter vector.

[1, x1, x2, x3, ..., xp]θ=[1, x1, x2, x3, ..., xp][θ0θ1⋮θp]=θ0 + θ1x1 + θ2x2 + ... + θpxp\begin{aligned} [1,\:x_{1},\:x_{2},\:x_{3},\:...,\:x_{p}] \theta \quad&=\quad [1,\:x_{1},\:x_{2},\:x_{3},\:...,\:x_{p}] \begin{bmatrix} \theta_{0} \\ \theta_{1} \\ \vdots \\ \theta_{p} \end{bmatrix} \\ \\ &=\quad \theta_0\:+\:\theta_1x_{1}\:+\:\theta_2 x_{2}\:+\:...\:+\:\theta_p x_{p} \end{aligned}

Notice that we have inserted 1 as the first value in the observation vector. When the dot product is computed, this 1 will be multiplied with θ0\theta_0 to give the intercept of the regression model. We call this 1 entry the intercept or bias term.

Given that we have three features here, we can express this model as:

y^=θ0 + θ1x1 + θ2x2 + θ3x3\hat{y} = \theta_0\:+\:\theta_1x_{1}\:+\:\theta_2 x_{2}\:+\:\theta_3 x_{3}

Our features are represented by x1x_1 (FG), x2x_2 (AST), and x3x_3 (3PA) with each having corresponding parameters, θ1\theta_1, θ2\theta_2, and θ3\theta_3.

In statistics, this model + loss is called Ordinary Least Squares (OLS). The solution to OLS is the minimizing loss for parameters θ^\hat{\theta}, also called the least squares estimate.

From One Feature To Many Features

In an earlier chapter, we worked with the Simple Linear Regression (SLR) model y^=θ0+θ1x\hat{y} = \theta_0 + \theta_1x, along the actual observations yy. We can represent the dataset that corresponds to this model as follows:

 x ⁣ ⁣ ⁣yx1y1x2y2⋮⋮xnyn→FGPTS1.8  5.30.4  1.71.1  3.26.0  13.93.4  8.9⋮⋮\begin{array}{c} \begin{array}{cc} \,x & \quad \!\!\!y \end{array} \\ \boxed{ \begin{array}{c|c} x_1 & y_1 \\ \hline x_2 & y_2 \\ \hline \vdots & \vdots \\ \hline x_n & y_n \end{array} } \end{array} \quad\rightarrow\quad \begin{array}{c} \begin{array}{cc} \mathbf{FG} & \mathbf{PTS} \end{array} \\ \boxed{ \begin{array}{c|c} 1.8\,\, & \enspace5.3 \\ \hline 0.4\,\, & \enspace1.7 \\ \hline 1.1\,\, & \enspace3.2 \\ \hline 6.0\,\, & 13.9 \\ \hline 3.4\,\, & \enspace8.9 \\ \hline \vdots & \vdots \\ \end{array} } \end{array}

We have also worked with the Constant Model y^=θ\hat{y} = \theta, along with the actual observations yy. We can represent the dataset that corresponds to this model even more simply, as there is no feature data to consider:

yy1y2⋮yn→PTS  5.3  1.7  3.2 ⁣13.9  8.9⋮\begin{array}{c} y \\ \boxed{ \begin{array}{c} y_1 \\ \hline y_2 \\ \hline \vdots \\ \hline y_n \end{array} } \end{array} \quad\rightarrow\quad \begin{array}{c} \mathbf{PTS} \\ \boxed{ \begin{array}{c} \,\,5.3 \\ \hline \,\,1.7 \\ \hline \,\,3.2 \\ \hline \!13.9 \\ \hline \,\,8.9 \\ \hline \vdots \\ \end{array} } \end{array}

Accordingly, we can use a similar representation for our new Multiple Regression Model:

x:,1 ⁣ ⁣ ⁣x:,2  x:,p  yx11x12⋯x1py1x21x22⋯x2py2⋮⋮⋱⋮⋮xn1xn2⋯xnpyn→  FGAST ⁣ ⁣3PA ⁣ ⁣PTS1.8  0.6   4.1 5.30.4  0.8   1.5 1.71.1  1.9   2.2 3.26.0  1.6   0.0 13.93.4  2.2   0.2 8.9⋮⋮⋮⋮\begin{array}{c} \begin{array}{ccccc} x_{:,1} & \enspace\!\!\! x_{:,2} & \quad & \,\, x_{:,p} & \,\, y \end{array} \\ \boxed{ \begin{array}{c|c|c|c|c} x_{11} & x_{12} & \cdots & x_{1p} & y_1 \\ \hline x_{21} & x_{22} & \cdots & x_{2p} & y_2 \\ \hline \vdots & \vdots & \ddots & \vdots & \vdots \\ \hline x_{n1} & x_{n2} & \cdots & x_{np} & y_n \end{array} } \end{array} \quad\rightarrow\quad \begin{array}{c} \begin{array}{cccc} \,\,\mathbf{FG} & \mathbf{AST} & \!\!\mathbf{3PA} & \!\!\mathbf{PTS} \end{array} \\ \boxed{ \begin{array}{c|c|c|c} 1.8\,\, & \enspace0.6 \,\, & \,4.1 \, & \enspace5.3 \\ \hline 0.4\,\, & \enspace0.8 \,\, & \,1.5 \, & \enspace1.7 \\ \hline 1.1\,\, & \enspace1.9 \,\, & \,2.2 \, & \enspace3.2 \\ \hline 6.0\,\, & \enspace1.6 \,\, & \,0.0 \, & 13.9 \\ \hline 3.4\,\, & \enspace2.2 \,\, & \,0.2 \, & \enspace8.9 \\ \hline \vdots & \vdots & \vdots & \vdots \\ \end{array} } \end{array}

From here, we can pull out just the first row, in order to get the first observation {x11,x12,⋯ ,x1p,y1}\{x_{11}, x_{12}, \cdots, x_{1p}, y_1\}. Similarly, we can pull out just the second column {x12,x22,⋯ ,xn2}\{x_{12}, x_{22}, \cdots, x_{n2}\}, in order to get the second feature.

Recall that this is our model for Multiple Linear Regression:

y^=θ0 + θ1x1 + θ2x2 + ... + θpxp\hat{y} = \theta_0\:+\:\theta_1x_{1}\:+\:\theta_2 x_{2}\:+\:...\:+\:\theta_p x_{p}

We can then write all of our predictions y^i\hat{y}_i like this:

{y^1=θ0+θ1x11+θ2x12+⋯+θpx1py^2=θ0+θ1x21+θ2x22+⋯+θpx2p⋮y^n=θ0+θ1xn1+θ2xn2+⋯+θpxnp\begin{cases} \hat{y}_1 = \theta_0 + \theta_1 x_{11} + \theta_2 x_{12} + \cdots + \theta_p x_{1p} \\ \hat{y}_2 = \theta_0 + \theta_1 x_{21} + \theta_2 x_{22} + \cdots + \theta_p x_{2p} \\ \vdots \\ \hat{y}_n = \theta_0 + \theta_1 x_{n1} + \theta_2 x_{n2} + \cdots + \theta_p x_{np} \end{cases}

Linear Algebra Approach

We now know how to generate a single prediction from multiple observed features. Data scientists usually work at scale – that is, they want to build models that can produce many predictions, all at once. The vector notation we introduced above gives us a hint on how we can expedite multiple linear regression. We want to use the tools of linear algebra.

Let’s think about how we can apply what we did above. To accommodate for the fact that we’re considering several feature variables, we’ll adjust our notation slightly. Each observation can now be thought of as a row vector with an entry for each of pp features.

Explanation for notation: x_i_j is the ith observation with the jth feature.

To make a prediction from the first observation in the data, we take the dot product of the parameter vector and first observation vector. To make a prediction from the second observation, we would repeat this process to find the dot product of the parameter vector and the second observation vector. If we wanted to find the model predictions for each observation in the dataset, we’d repeat this process for all nn observations in the data.

{y^1=x1Tθ,wherex1T=[1x11x12⋯x1p] is datapoint/observation 1y^2=x2Tθ,wherex2T=[1x21x22⋯x2p] is datapoint/observation 2⋮y^n=xnTθ,wherexnT=[1xn1xn2⋯xnp] is datapoint/observation n\begin{cases} \hat{y}_1 = x_1^T\theta \enspace \text{,} \quad \text{where} \enspace x_1^T = \begin{bmatrix} 1 & x_{11} & x_{12} & \cdots & x_{1p} \end{bmatrix} \text{ is datapoint/observation 1}\\ \hat{y}_2 = x_2^T\theta \enspace \text{,} \quad \text{where} \enspace x_2^T = \begin{bmatrix} 1 & x_{21} & x_{22} & \cdots & x_{2p} \end{bmatrix} \text{ is datapoint/observation 2}\\ \vdots \\ \hat{y}_n = x_n^T\theta \enspace \text{,} \quad \text{where} \enspace x_n^T = \begin{bmatrix} 1 & x_{n1} & x_{n2} & \cdots & x_{np} \end{bmatrix} \text{ is datapoint/observation n}\\ \end{cases}

Expanding our transpose vectors, we get the following:

y^1=[1, x11, x12, x13, ..., x1p]θy^2=[1, x21, x22, x23, ..., x2p]θ⋮y^n=[1, xn1, xn2, xn3, ..., xnp]θ\hat{y}_1 = [1,\:x_{11},\:x_{12},\:x_{13},\:...,\:x_{1p}] \theta \\ \hat{y}_2 = [1,\:x_{21},\:x_{22},\:x_{23},\:...,\:x_{2p}] \theta \\ \vdots \\ \hat{y}_n = [1,\:x_{n1},\:x_{n2},\:x_{n3},\:...,\:x_{np}] \theta

We can then vectorize our predictions y^\hat{y} and our parameters θ\theta. We will keep the nn row vectors, each with dimension p+1p + 1.

[y^1y^2⋮y^n]=[1x11x12…x1p][1x21x22…x2p]⋮[1xn1xn2…xnp]θ\begin{bmatrix} \hat{y}_1 \\ \\ \hat{y}_2 \\ \\ \vdots \\ \\ \hat{y}_n \end{bmatrix} {\Huge =} \enspace \begin{matrix} \begin{bmatrix} 1 & x_{11} & x_{12} & \dots & x_{1p} \end{bmatrix} \\ \\ \begin{bmatrix} 1 & x_{21} & x_{22} & \dots & x_{2p} \end{bmatrix} \\ \\ \vdots \\ \\ \begin{bmatrix} 1 & x_{n1} & x_{n2} & \dots & x_{np} \end{bmatrix} \end{matrix} \enspace {\Huge \theta}

We can collect all of our xiTx_i^T row vectors into a single matrix.

[y^1y^2⋮y^n]=[1x11x12⋯x1p1x21x22⋯x2p⋮⋮⋱⋮1xn1xn2⋯xnp]θ\begin{bmatrix} \hat{y}_1 \\ \\ \hat{y}_2 \\ \\ \vdots \\ \\ \hat{y}_n \end{bmatrix} {\Huge =} \enspace \begin{bmatrix} 1 & x_{11} & x_{12} & \cdots & x_{1p} \\ \\ 1 & x_{21} & x_{22} & \cdots & x_{2p} \\ \vdots & \vdots & \ddots & \vdots \\ \\ 1 & x_{n1} & x_{n2} & \cdots & x_{np} \end{bmatrix} \enspace {\Huge \theta}

Briefly expanding our parameter vector θ\theta, we can see that our predictions take the following form:

[y^1y^2⋮y^n]=[1x11x12⋯x1p1x21x22⋯x2p⋮⋮⋱⋮1xn1xn2⋯xnp][θ0θ1θ2⋮θp]\begin{bmatrix} \hat{y}_1 \\ \\ \hat{y}_2 \\ \\ \vdots \\ \\ \hat{y}_n \end{bmatrix} {\Huge =} \enspace \begin{bmatrix} 1 & x_{11} & x_{12} & \cdots & x_{1p} \\ \\ 1 & x_{21} & x_{22} & \cdots & x_{2p} \\ \\ \vdots & \vdots & \ddots & \vdots \\ \\ 1 & x_{n1} & x_{n2} & \cdots & x_{np} \end{bmatrix} \enspace \begin{bmatrix} \theta_0 \\ \\ \theta_1 \\ \\ \theta_2 \\ \\ \vdots \\ \\ \theta_p \end{bmatrix}

Let’s collapse our parameter vector back into θ\theta and call our matrix of observations X\mathbb{X}.

[y^1y^2⋮y^n]=Xθ\begin{bmatrix} \hat{y}_1 \\ \\ \hat{y}_2 \\ \\ \vdots \\ \\ \hat{y}_n \end{bmatrix} {\Huge =} \enspace {\Huge \mathbb{X}} \enspace {\Huge \theta}

Finally, we can call our prediction vector Y^\hat{\mathbb{Y}}. We can now represent our Multiple Linear Regression model for many observations fully in terms of matrices.

Y^=Xθ{\Huge \hat{\mathbb{Y}}} {\Huge =} \enspace {\Huge \mathbb{X}} \enspace {\Huge \theta}

The matrix X\mathbb{X} is known as the design matrix. It contains all observed data for each of our pp features, where each row corresponds to one observation, and each column corresponds to a feature. It often (but not always) contains an additional column of all ones to represent the intercept or bias column.

Our true output can also be represented as a vector, which we will call Rp+1\mathbb{R}^{p + 1}. As an example, our true output in the basketball example was the actual recorded PTS (5.1, 1.7, etc.). This is distinct from the predictions our model would make for PTSPTS based on our features (FG, AST, 3PA)

To review what is happening in the design matrix: each row represents a single observation. For example, a student in Data 100. Each column represents a feature. For example, the ages of students in Data 100. This convention allows us to easily transfer our previous work in DataFrames over to this new linear algebra perspective.

Illustration of how to view a DataFrame within the linear algebra framework.

To summarize where we have ended up, our model now takes the form Y^=Xθ\mathbb{\hat{Y}} = \mathbb{X} \theta. Y^\mathbb{\hat{Y}} is the prediction vector with nn elements (Y^∈Rn\mathbb{\hat{Y}} \in \mathbb{R}^{n}); it contains the prediction made by the model for each of the nn input observations. X\mathbb{X} is the design matrix with dimensions X∈Rn×(p+1)\mathbb{X} \in \mathbb{R}^{n \times (p + 1)}, and θ\theta is the parameter vector with dimensions θ∈R(p+1)\theta \in \mathbb{R}^{(p + 1)}. Our true output Y\mathbb{Y} contains nn elements (Y∈Rn\mathbb{Y} \in \mathbb{R}^{n}).

Mean Squared Error

We now have a new approach to understanding models in terms of vectors and matrices. To accompany this new convention, we should update our understanding of risk functions and model fitting.

Recall our definition of MSE:

R(θ)=1n∑i=1n(yi−y^i)2R(\theta) = \frac{1}{n} \sum_{i=1}^n (y_i - \hat{y}_i)^2

At its heart, the MSE is a measure of distance – it gives an indication of how “far away” the predictions are from the true values, on average.

We can express the MSE as a squared L2 norm if we rewrite it in terms of the prediction vector, Y^\hat{\mathbb{Y}}, and true target vector, Y\mathbb{Y}:

R(θ)=1n∑i=1n(yi−y^i)2=1n(∣∣Y−Y^∣∣2)2R(\theta) = \frac{1}{n} \sum_{i=1}^n (y_i - \hat{y}_i)^2 = \frac{1}{n} (||\mathbb{Y} - \hat{\mathbb{Y}}||_2)^2

Here, the superscript 2 outside of the parentheses means that we are squaring the norm. If we plug in our linear model Y^=Xθ\hat{\mathbb{Y}} = \mathbb{X} \theta, we find the MSE cost function in vector notation:

R(θ)=1n(∣∣Y−Xθ∣∣2)2R(\theta) = \frac{1}{n} (||\mathbb{Y} - \mathbb{X} \theta||_2)^2

Under the linear algebra perspective, our new task is to fit the optimal parameter vector θ\theta such that the cost function is minimized. Equivalently, we wish to minimize the norm

∣∣Y−Xθ∣∣2=∣∣Y−Y^∣∣2.||\mathbb{Y} - \mathbb{X} \theta||_2 = ||\mathbb{Y} - \hat{\mathbb{Y}}||_2.

We can restate this goal in three ways:

  • Minimize the mean squared error for the linear model Y^=Xθ\mathbb{\hat{Y}} = \mathbb{X} \theta

  • Minimize the distance between the vector of true values, Y\mathbb{Y}, and the vector of predicted values, Y^\mathbb{\hat{Y}}

  • Minimize the length of the residual vector, defined as:

    e=Y−Y^=[y1−y^1y2−y^2⋮yn−y^n]e = \mathbb{Y} - \mathbb{\hat{Y}} = \begin{bmatrix} y_1 - \hat{y}_1 \\ y_2 - \hat{y}_2 \\ \vdots \\ y_n - \hat{y}_n \end{bmatrix}

A Note on Terminology for Multiple Linear Regression

There are several equivalent terms in the context of regression. The ones we use most often for this course are bolded.

  • xx can be called a

    • Feature(s)

    • Covariate(s)

    • Independent variable(s)

    • Explanatory variable(s)

    • Predictor(s)

    • Input(s)

    • Regressor(s)

  • yy can be called an

    • Output

    • Outcome

    • Response

    • Dependent variable

  • y^\hat{y} can be called a

    • Prediction

    • Predicted response

    • Estimated value

  • θ\theta can be called a

    • Weight(s)

    • Parameter(s)

    • Coefficient(s)

  • θ^\hat{\theta} can be called a

    • Estimator(s)

    • Optimal parameter(s)

  • A datapoint (x,y)(x, y) is also called an observation.

Geometric Derivation

Rethinking Matrix-Vector Multiplication

There are 2 ways we can think about matrix-vector multiplication

  1. So far, we’ve thought of our model as horizontally stacked predictions per datapoint:

The prediction column vector Y_hat equals the product of X, made up of vertically stacked row vectors representing observations, and theta.
  1. Notice that we can express our predictions Y^\mathbb{\hat{Y}} in the following way:

[y^1y^2⋮y^n]=[θ0+θ1x11+θ2x12+⋯+θpx1pθ0+θ1x21+θ2x22+⋯+θpx2p⋮θ0+θ1xn1+θ2xn2+⋯+θpxnp]\begin{bmatrix} \hat{y}_1 \\ \\ \hat{y}_2 \\ \\ \vdots \\ \\ \hat{y}_n \end{bmatrix} {\Huge =} \enspace \begin{bmatrix} \theta_0 + \theta_1 x_{11} + \theta_2 x_{12} + \cdots + \theta_p x_{1p} \\ \\ \theta_0 + \theta_1 x_{21} + \theta_2 x_{22} + \cdots + \theta_p x_{2p} \\ \\ \vdots \\ \\ \theta_0 + \theta_1 x_{n1} + \theta_2 x_{n2} + \cdots + \theta_p x_{np} \end{bmatrix}

Notice that the jjth element (zero-indexed) of every sum in the vector on the right side contains θj\theta_j. So, the zeroth element of every sum contains θ0\theta_0, the second element of every sum (again, zero-indexed) contains θ2\theta_2, etc. It would be nice to group these elements with shared θ\theta values together!

Because adding vectors of the same length produces a new vector of element-wise sums, we can split this already-summed vector into the sum of vectors:

[y^1y^2⋮y^n]=[θ0θ0⋮θ0]+[θ1x11θ1x21⋮θ2xn1]+[θ2x12θ2x22⋮θ2xn2]+⋯+[θpx1pθpx2p⋮θpxnp]\begin{bmatrix} \hat{y}_1 \\ \\ \hat{y}_2 \\ \\ \vdots \\ \\ \hat{y}_n \end{bmatrix} {\Large =} \enspace \begin{bmatrix} \theta_0 \\ \\ \theta_0 \\ \\ \vdots \\ \\ \theta_0 \end{bmatrix} {\Large +} \enspace \begin{bmatrix} \theta_1 x_{11} \\ \\ \theta_1 x_{21} \\ \\ \vdots \\ \\ \theta_2 x_{n1} \end{bmatrix} {\Large +} \enspace \begin{bmatrix} \theta_2 x_{12} \\ \\ \theta_2 x_{22} \\ \\ \vdots \\ \\ \theta_2 x_{n2} \end{bmatrix} {\Large +} \enspace {\Large \cdots} \enspace {\Large +} \enspace \begin{bmatrix} \theta_p x_{1p} \\ \\ \theta_p x_{2p} \\ \\ \vdots \\ \\ \theta_p x_{np} \end{bmatrix}

Note that any jjth summed column vector contains exclusively elements of the form θjxij\theta_j x_{ij} (except for the first one, which contains only elements of the form θ0=θ0×1\theta_0 = \theta_0 \times 1). Thus, you can factor out θj\theta_j from every jj-th summed column vector:

[y^1y^2⋮y^n]=θ0[11⋮1]+θ1[x11x21⋮xn1]+θ2[x12x22⋮xn2]+⋯+θp[x1px2p⋮xnp]\begin{bmatrix} \hat{y}_1 \\ \\ \hat{y}_2 \\ \\ \vdots \\ \\ \hat{y}_n \end{bmatrix} {\Large =} \enspace {\Large \theta_0} \begin{bmatrix} 1 \\ \\ 1 \\ \\ \vdots \\ \\ 1 \end{bmatrix} {\Large +} \enspace {\Large \theta_1} \begin{bmatrix} x_{11} \\ \\ x_{21} \\ \\ \vdots \\ \\ x_{n1} \end{bmatrix} {\Large +} \enspace {\Large \theta_2} \begin{bmatrix} x_{12} \\ \\ x_{22} \\ \\ \vdots \\ \\ x_{n2} \end{bmatrix} {\Large +} \enspace {\Large \cdots} \enspace {\Large +} \enspace {\Large \theta_p} \begin{bmatrix} x_{1p} \\ \\ x_{2p} \\ \\ \vdots \\ \\ x_{np} \end{bmatrix}
  1. It is sometimes very helpful to think of matrix-vector multiplication as performed by columns. We can also think of Y\mathbb{Y} as a linear combination of feature vectors, scaled by parameters.

The prediction column vector Y_hat is the product of X and theta. This can be rewritten as the columns of X multiplied by the parameters within theta.

Up until now, we’ve mostly thought of our model as a scalar product between horizontally stacked observations and the parameter vector. We can also think of Y^\hat{\mathbb{Y}} as a linear combination of feature vectors, scaled by the parameters. We use the notation X:,i\mathbb{X}_{:, i} to denote the iith column of the design matrix.

The prediction column vector Y_hat is the product of X and theta.
Y^=θ0[11⋮1]+θ1[x11x21⋮xn1]+…+θp[x1px2p⋮xnp]=θ0X:, 1+θ1X:, 2+…+θpX:, p+1\hat{\mathbb{Y}} = \theta_0 \begin{bmatrix} 1 \\ 1 \\ \vdots \\ 1 \end{bmatrix} + \theta_1 \begin{bmatrix} x_{11} \\ x_{21} \\ \vdots \\ x_{n1} \end{bmatrix} + \ldots + \theta_p \begin{bmatrix} x_{1p} \\ x_{2p} \\ \vdots \\ x_{np} \end{bmatrix} = \theta_0 \mathbb{X}_{:,\:1} + \theta_1 \mathbb{X}_{:,\:2} + \ldots + \theta_p \mathbb{X}_{:,\:p+1}

This new approach is useful because it allows us to take advantage of the properties of linear combinations.

Because the prediction vector, Y^=Xθ\hat{\mathbb{Y}} = \mathbb{X} \theta, is a linear combination of the columns of X\mathbb{X}, we know that the predictions are contained in the span of X\mathbb{X}. That is, we know that Y^∈Span(X)\mathbb{\hat{Y}} \in \text{Span}(\mathbb{X}).

Column Space And The Normal Equation

The diagram below is a simplified view of Span(X)\text{Span}(\mathbb{X}), assuming that each column of X\mathbb{X} has length nn. Notice that the columns of X\mathbb{X} define a subspace of Rn\mathbb{R}^n, where each point in the subspace can be reached by a linear combination of X\mathbb{X}'s columns. The prediction vector Y^\mathbb{\hat{Y}} lies somewhere in this subspace.

Illustration of the span of X

Examining this diagram, we find a problem. The vector of true values, Y\mathbb{Y}, could theoretically lie anywhere in Rn\mathbb{R}^n space – its exact location depends on the data we collect out in the real world. However, our multiple linear regression model can only make predictions in the subspace of Rn\mathbb{R}^n spanned by X\mathbb{X}. Remember the model fitting goal we established in the previous section: we want to generate predictions such that the distance between the vector of true values, Y\mathbb{Y}, and the vector of predicted values, Y^\mathbb{\hat{Y}}, is minimized. This means that we want Y^\mathbb{\hat{Y}} to be the vector in Span(X)\text{Span}(\mathbb{X}) that is closest to Y\mathbb{Y}.

Another way of rephrasing this goal is to say that we wish to minimize the length of the residual vector ee, as measured by its L2L_2 norm.

The residual is now drawn on the previous graph.

The vector in Span(X)\text{Span}(\mathbb{X}) that is closest to Y\mathbb{Y} is always the orthogonal projection of Y\mathbb{Y} onto Span(X).\text{Span}(\mathbb{X}). Thus, we should choose the parameter vector θ\theta that makes the residual vector orthogonal to any vector in Span(X)\text{Span}(\mathbb{X}). You can visualize this as the vector created by dropping a perpendicular line from Y\mathbb{Y} onto the span of X\mathbb{X}.

Remember our goal is to find θ^\hat{\theta} such that we minimize the objective function R(θ)R(\theta). Equivalently, this is the θ^\hat{\theta} such that the residual vector e=Y−Xθ^e = \mathbb{Y} - \mathbb{X} \hat{\theta} is orthogonal to Span(X)\text{Span}(\mathbb{X}).

Looking at the definition of orthogonality of Y−Xθ^\mathbb{Y} - \mathbb{X}\hat{\theta} to span(X)span(\mathbb{X}), we can write:

XT(Y−Xθ^)=0⃗\mathbb{X}^T (\mathbb{Y} - \mathbb{X}\hat{\theta}) = \vec{0}

Let’s then rearrange the terms:

XTY−XTXθ^=0⃗\mathbb{X}^T \mathbb{Y} - \mathbb{X}^T \mathbb{X} \hat{\theta} = \vec{0}

And finally, we end up with the normal equation:

XTXθ^=XTY\mathbb{X}^T \mathbb{X} \hat{\theta} = \mathbb{X}^T \mathbb{Y}

Any vector θ\theta that minimizes MSE on a dataset must satisfy this equation.

If XTX\mathbb{X}^T \mathbb{X} is invertible, we can conclude:

θ^=(XTX)−1XTY\hat{\theta} = (\mathbb{X}^T \mathbb{X})^{-1} \mathbb{X}^T \mathbb{Y}

This is called the least squares estimate of θ\theta: it is the value of θ\theta that minimizes the squared loss.

Note that the least squares estimate was derived under the assumption that XTX\mathbb{X}^T \mathbb{X} is invertible. This condition holds true when XTX\mathbb{X}^T \mathbb{X} is full column rank, which, in turn, happens when X\mathbb{X} is full column rank. We will get to the proof for why X\mathbb{X} needs to be full column rank in the OLS Properties section.

OLS Properties

Residuals

When using the optimal parameter vector, our residuals e=Y−Y^e = \mathbb{Y} - \hat{\mathbb{Y}} are orthogonal to span(X)span(\mathbb{X}).

XTe=0\mathbb{X}^Te = 0

The Bias/Intercept Term

For all linear models with an intercept term, the sum of residuals is zero.

∑inei=0\sum_i^n e_i = 0

Existence of a Unique Solution

To summarize:

ModelEstimateUnique?
Constant Model + MSEy^=θ0\hat{y} = \theta_0θ^0=mean(y)=yˉ\hat{\theta}_0 = mean(y) = \bar{y}Yes. Any set of values has a unique mean.
Constant Model + MAEy^=θ0\hat{y} = \theta_0θ^0=median(y)\hat{\theta}_0 = median(y)Yes, if odd. No, if even. Return the average of the middle 2 values.
Simple Linear Regression + MSEy^=θ0+θ1x\hat{y} = \theta_0 + \theta_1xθ^0=yˉ−θ^1xˉ\hat{\theta}_0 = \bar{y} - \hat{\theta}_1\bar{x} θ^1=rσyσx\hat{\theta}_1 = r\frac{\sigma_y}{\sigma_x}Yes. Any set of non-constant values has a unique mean, SD, and correlation coefficient.
OLS (Linear Model + MSE)Y^=Xθ\mathbb{\hat{Y}} = \mathbb{X}\mathbb{\theta}θ^=(XTX)−1XTY\hat{\theta} = (\mathbb{X}^T\mathbb{X})^{-1}\mathbb{X}^T\mathbb{Y}Yes, if X\mathbb{X} is full column rank (all columns are linearly independent, # of datapoints >>> # of features).

Uniqueness of the OLS Solution

In most settings, the number of observations (n) is much greater than the number of features (p).

Conceptual illustration of the normal equation with matrices.

In practice, instead of directly inverting matrices, we can use more efficient numerical solvers to directly solve a system of linear equations using the normal equation shown below. Note that at least one solution always exists because intuitively, we can always draw a line of best fit for a given set of data, but there may be multiple lines that are “equally good”. (Formal proof is beyond this course.)

Conceptual illustration of the normal equation with matrices.

The Least Squares estimate θ^\hat{\theta} is unique if and only if X\mathbb{X} is full column rank.

Therefore, if X\mathbb{X} is not full column rank, we will not have unique estimates. This can happen for two major reasons.

  1. If our design matrix X\mathbb{X} is “wide”:

    • If n < p, then we have way more features (columns) than observations (rows).

    • Then rank(X)=min(n,p+1)<p+1rank(\mathbb{X}) = min(n, p+1) < p+1, so θ^\hat{\theta} is not unique.

    • Intuition

      • With one data point (n=1n=1), there are ∞\infty SLR models (p=1p = 1) that minimize MSE. Try drawing a picture!

    • More intuition

      • Given two non-overlapping vectors (p=1p = 1) in 2D space (n=2n = 2) there is exactly one linear combination that can reach each point in 2D space.

      • If you have three of these vectors (p=2p = 2), there are ∞\infty possible combinations.

    • Typically we have nn >> pp, so this is less of an issue.

  2. If our design matrix X\mathbb{X} has features that are linear combinations of other features:

    • By definition, rank of X\mathbb{X} is number of linearly independent columns in X\mathbb{X}.

    • Example: If “Width”, “Height”, and “Perimeter” are all columns,

      • Perimeter = 2 * Width + 2 * Height →\rightarrow X\mathbb{X} is not full rank.

    • Important with one-hot encoding (to discuss later).

Evaluating Model Performance

Our geometric view of multiple linear regression has taken us far! We have identified the optimal set of parameter values to minimize MSE in a model of multiple features. Now, we want to understand how well our fitted model performs.

RMSE

One measure of model performance is the Root Mean Squared Error, or RMSE. The RMSE is simply the square root of MSE. Taking the square root converts the value back into the original, non-squared units of yiy_i, which is useful for understanding the model’s performance. A low RMSE indicates more “accurate” predictions – that there is a lower average loss across the dataset.

RMSE=1n∑i=1n(yi−y^i)2\text{RMSE} = \sqrt{\frac{1}{n} \sum_{i=1}^n (y_i - \hat{y}_i)^2}

Multiple R2R^2

For SLR, we used the correlation coefficient to capture the association between the target variable and a single feature variable. In a multiple linear model setting, we will need a performance metric that can account for multiple features at once. Multiple R2R^2, also called the coefficient of determination, is the proportion of variance of our fitted values (predictions) y^i\hat{y}_i to our true values yiy_i. It ranges from 0 to 1 and is effectively the proportion of variance in the observations that the model explains.

R2=variance of y^ivariance of yi=σy^2σy2R^2 = \frac{\text{variance of } \hat{y}_i}{\text{variance of } y_i} = \frac{\sigma^2_{\hat{y}}}{\sigma^2_y}

Note that for OLS with an intercept term, for example y^=θ0+θ1x1+θ2x2+⋯+θpxp\hat{y} = \theta_0 + \theta_1x_1 + \theta_2x_2 + \cdots + \theta_px_p, R2R^2 is equal to the square of the correlation between yy and y^\hat{y}. On the other hand for SLR, R2R^2 is equal to r2r^2, the correlation between xx and yy. The proof of these last two properties is out of scope for this course.

As we add more features, our fitted values tend to become closer and closer to our actual values. Thus, R2R^2 increases.

Returning to our basketball example:

  • The SLR model (AST only) explains 45.7% of the variance in the true yy.

  • The AST & 3PA model explains 60.9% of the variance in the true yy.

Adding more features doesn’t always mean our model is better, though! We’ll see why later in the course.

Demo: Predicting Penguin Bill Depth

Can we predict bill depth from flipper length and body mass? We can now apply what we have learned about Multiple Linear Regression models and Ordinary Least Squares to do just that. We will conclude by introducing the scikit-learn library for simple machine learning tasks, and using it to recreate the same prediction of bill depth.

Consider the penguins dataset.

Loading...

Suppose we could measure flippers and weight easily, but not bill dimensions. How can we predict bill depth from flipper length and/or body mass?

Profile illustration of a penguin. The vertical depth of the penguin's bill, measured at its base, is labeled as bill depth.

For demo purposes, we’ll drop all columns except the variables whose relationships we’re interested in modeling.

Loading...

Suppose we want to create a linear regression model that predicts a penguin’s bill depth yy using both their flipper length x1x_1 and body mass x2x_2, plus an intercept term.

y^=θ0+θ1x1+θ2x2\Large \hat{y} = \theta_0 + \theta_1 x_1 + \theta_2 x_2

Another way to write this:

bill_depth_mm^=θ0+θ1∗flipper_length_mm+θ2∗body_mass_g\widehat{\texttt{bill\_depth\_mm}} = \theta_0 + \theta_1 * \texttt{flipper\_length\_mm} + \theta_2 * \texttt{body\_mass\_g}

Using The Solution To The Normal Equation

We saw in last lecture that we can model the above multiple linear regression equation using matrix multiplication:

Y^=Xθ\large \hat{\mathbb{Y}} = \mathbb{X} \theta

The optimal θ^\hat{\theta} that minimizes MSE also solves the normal equation:

(XTX)θ^=XTY\left( \mathbb{X}^T \mathbb{X} \right) \hat{\theta} = \mathbb{X}^T \mathbb{Y}

If X\mathbb{X} is full column rank, then there is a unique solution to θ^\hat{\theta}:

θ^=(XTX)−1XTY\large \hat{\theta} = \left( \mathbb{X}^T \mathbb{X} \right)^{-1} \mathbb{X}^T \mathbb{Y}

Note: This derivation is one of the most challenging in the course, especially for those of you who are learning linear algebra during the same semester. Be kind to yourself!

Let’s try this in code. We have to add a bias column to the design matrix if we want to include an intercept in the model:

Loading...
Loading...

Recall the solution to the normal equation if X\mathbb{X} is full column rank:

θ^=(XTX)−1XTY\hat{\theta} = \left( \mathbb{X}^T \mathbb{X} \right)^{-1} \mathbb{X}^T \mathbb{Y}
array([1.10029953e+01, 9.82848689e-03, 1.47749591e-03])

So, our fitted model is as follows:

bill_depth_mm^=11+0.0098∗flipper_length_mm+0.0015∗body_mass_g\widehat{\texttt{bill\_depth\_mm}} = 11 + 0.0098 * \texttt{flipper\_length\_mm} + 0.0015 * \texttt{body\_mass\_g}

Note: The code above is inefficient. We won’t go into this in Data 100, but it’s better to use np.linalg.solve rather than computing the explicit matrix inverse:

array([1.10029953e+01, 9.82848689e-03, 1.47749591e-03])

Make Predictions

We’ll save the predictions in a column so we can compare them against predictions from sklearn in the next section.

Loading...

Machine Learning Frameworks

We have introduced the Multiple Linear Regression model Y^=Xθ\hat{\mathbb{Y}} = \mathbb{X}\theta. We have expressed the Mean Squared Error loss function in vector notation:

R(θ)=1n(∣∣Y−Xθ∣∣2)2R(\theta) = \frac{1}{n} (||\mathbb{Y} - \mathbb{X} \theta||_2)^2

We then used geometry to minimize average loss by fitting our model with optimal parameter values θ^\hat{\theta}. We touched upon the use of matrix calculus to fit the model (out of scope for this course), and we used calculus to find the optimal parameter values for SLR in the previous chapters.

In research and industry, it is common to use libraries for creating and training models. In Data 100, we will use scikit-learn, commonly called sklearn.

Home page for the scikit-learn website. Three sections are featured: Classification, Regression, and Clustering.

The sklearn Workflow

At a high level, there are three steps to creating an sklearn model:

  1. Initialize a new model instance.

  • Make a “copy” of the model template

my_model = lm.LinearRegression()
  1. Fit the model to the training data.

  • Save the optimal model parameters

my_model.fit(X, y)
  1. Use fitted models to make predictions.

my_model.predict(X_new)

To extract the fitted model’s parameters, use my_model.coef_ (to extract parameters for all features without the bias θ1,θ2,⋯ ,θp\theta_1, \theta_2, \cdots, \theta_p) and my_model.intercept_ (to extract the parameter for the bias θ0\theta_0).

Let’s try this out.

Using sklearn to fit our Multiple Linear Regression Model

Do we obtain the same fitted OLS parameters provided by the normal equation using sklearn? We can use the sklearn workflow we just described to find out.

An alternate approach to optimize our model is to use the sklearn.linear_model.LinearRegression class.(Documentation)

  1. Create an sklearn object.

    First we create a model. At this point the model has not been fit so it has no parameters.

Loading...
  1. fit the object to data.

Then we “fit” the model, which means computing the parameters that minimize the loss function.

The first argument of the .fit method should be a matrix, or DataFrame, with dimension n×pn \times p containing your feature data (the dimension is not n×p+1n \times p + 1 because LinearRegression objects add an intercept by default). The second argument should be a vector, or Series, of dimension nn containing the observations we’re trying to predict.

Note: The LinearRegression class is hard-coded to use the MSE as its loss function.

Loading...
  1. Analyze fit or call predict.

Now that our model is trained, we can ask it questions.

The code below asks the model to estimate the bill depth (in mm) for three different penguins with different flipper lengths and body masses.

array([18.36187501, 17.96809096, 17.22998758])

Here are the predictions for all of the penguins in our dataset:

array([18.32256106, 18.44557829, 17.72141192, 17.99725413, 18.26326785, 18.13787407, 19.82684359, 17.5197668 , 18.49472072, 19.45001768, 18.28800021, 18.0169111 , 19.58793878, 17.72411076, 19.11520455, 17.73663808, 18.09110819, 18.47506375, 18.65737419, 18.38660737, 18.45540678, 18.04671885, 17.56890923, 17.34760713, 18.60823175, 17.55432765, 18.51469999, 17.72648731, 18.57367091, 17.83222412, 19.06098673, 18.70651662, 18.01723339, 17.6576879 , 19.68179284, 17.445892 , 18.68178426, 17.41133115, 19.4303607 , 17.25375308, 19.66688896, 17.85220338, 17.96776867, 19.01184429, 18.00232952, 19.20398322, 17.96776867, 18.95255108, 17.12566046, 18.34697113, 18.07620431, 18.5143777 , 16.99281474, 18.45033139, 17.47537746, 19.42053222, 18.14025062, 18.87392319, 17.0223002 , 18.7261736 , 17.86916151, 18.90848404, 17.37677031, 19.52389247, 18.18939306, 18.63264183, 18.17448918, 19.07081521, 18.33714265, 19.19890783, 18.34697113, 18.57367091, 18.0860328 , 18.82953385, 17.58856621, 19.87360948, 18.45540678, 19.10537606, 17.82984757, 18.15483221, 18.48489224, 18.03181498, 18.69668814, 18.18939306, 18.2334601 , 19.37106749, 17.84475144, 19.40595063, 17.71665882, 19.40055296, 18.33714265, 19.35648591, 17.03720408, 18.94779798, 18.39373702, 19.97934628, 17.3449083 , 19.1497654 , 17.22156878, 18.05654734, 18.49947382, 18.63264183, 17.47300091, 19.99425016, 18.60045753, 19.67671745, 17.62788015, 19.2555022 , 18.64247031, 18.95017453, 17.13548895, 18.53641122, 17.81019059, 17.77325319, 17.49503444, 18.12027136, 17.83016985, 18.71364627, 17.33745636, 18.8688478 , 17.71903537, 19.27278263, 17.38659879, 18.97696116, 17.78308168, 18.11044287, 18.07112893, 19.57065836, 17.90134581, 18.63264183, 17.57128578, 18.84173889, 17.84475144, 19.17925086, 17.92337933, 17.97522061, 17.35711333, 18.37408004, 17.32255248, 18.21412542, 19.1497654 , 17.94573515, 18.0169111 , 18.4405029 , 18.30765719, 18.88850477])

Let’s save the scikit-learn model predictions as a column in our DataFrame:

Loading...

Looking at the predictions above, we see that they are exactly the same as what we calculated with our analytic formula!

Analyze parameters.

We can ask the model for its intercept and slope with .intercept_ and .coef_, respectively.

np.float64(11.002995277447068)
array([0.00982849, 0.0014775 ])

So, our fitted model is as follows:

bill_depth_mm^=11+0.0098∗flipper_length_mm+0.0015∗body_mass_g\widehat{\texttt{bill\_depth\_mm}} = 11 + 0.0098 * \texttt{flipper\_length\_mm} + 0.0015 * \texttt{body\_mass\_g}

The parameters are the same as with our analytic formula.

array([1.10029953e+01, 9.82848689e-03, 1.47749591e-03])

They look the same!

Fitting General Models

The solution we found for the normal equation can only help us fit our model, or find our optimal parameters θ^\hat{\theta} when we use Multiple Linear Regression as our model and Mean Squared Error as our loss function. How do these software packages, like scikit-learn, fit general models?

We made some big assumptions with the calculus-based and geometric techniques for minimizing loss:

  • Calculus:

    • We can’t always algebraically solve for the zero points of the derivative.

  • Geometric:

    • We don’t always use a linear model with MSE loss.

To design more complex models with different loss functions, we need a new optimization technique: gradient descent.

In the next chapter, we will use this iterative algorithm to numerically compute the parameters θ^\hat{\theta} that minimize the loss.

[Bonus] Time Complexity of the Normal Equation

It can be easy to assume that a closed-form solution is always the fastest approach, but evaluating the normal equation on large datasets can be extremely computationally taxing and can take a lot of resources to calculate. Here we’ll explore why this is true.

We know that the solution to the normal equation is θ^=(XTX)−1XTY\hat{\theta} = (\mathbb{X}^T\mathbb{X})^{-1}\mathbb{X}^T\mathbb{Y}. Let’s break this down and determine the computational complexity for this solution.

Illustration of the normal equation with matrices.

Let nn be the number of samples (rows) and dd be the number of features (columns).

  • Computing (X⊤X)(\mathbb{X}^{\top}\mathbb{X}) takes O(nd2)O(nd^2) time, and it’s inverse takes another O(d3)O(d^3) time to calculate; overall, (X⊤X)−1(\mathbb{X}^{\top}\mathbb{X})^{-1} takes O(nd2)+O(d3)O(nd^2) + O(d^3) time.

  • X⊤Y\mathbb{X}^{\top}\mathbb{Y} takes O(nd)O(nd) time.

  • Multiplying (X⊤X)−1(\mathbb{X}^{\top}\mathbb{X})^{-1} and X⊤Y\mathbb{X}^{\top}\mathbb{Y} takes O(d2)O(d^2) time.

In total, calculating the solution to the normal equation takes O(nd2)+O(d3)+O(nd)+O(d2)O(nd^2) + O(d^3) + O(nd) + O(d^2) time. We can see that O(nd2)+O(d3)O(nd^2) + O(d^3) dominates the complexity — this can be problematic for high-dimensional models and very large datasets.