University

Introduction to Econometrics · Part 3: Regression · First year

Lesson 9: fitting the OLS line by hand

A scatter of points can be summarised by a straight line, and ordinary least squares (OLS) picks the line whose squared vertical gaps to the points add up to the smallest total. For a small data set that line can be found by hand. We do the arithmetic on five workers, then on 20 Premier League clubs, with three checks.

1. Twenty clubs and one line

Here are the 20 Premier League clubs of 2023/24, with goal difference across the page and league points up it. Nobody needs a formula to see the pattern: score more than you concede and you finish higher. The question this lesson answers is narrower. Which straight line summarises the pattern, and how do we find it without a computer?

Scatter of the 20 Premier League clubs in 2023/24, goal difference on the horizontal axis from -69 to +62 and league points on the vertical axis from 16 to 91, with the fitted line points = 52.3 + 0.623 times goal difference and R-squared 0.93. Clubs above the line include West Ham and Manchester United; below it Nottingham Forest, Brentford and Newcastle.
Figure 1. The line we will compute by hand in section 4. points = 52.30 + 0.6235 × goal difference, 20 clubs. Source: openfootball/england (CC0); deductions Everton 8, Nott'm Forest 4.

Any line we draw leaves gaps, measured straight up or down from each club's point to the line. The OLS rule is: square every gap, add the 20 squares, and choose the line that makes the total as small as possible. The gaps left by that line are called the residuals. We come back to these clubs in section 4 and compute that line by hand. First we need to see what the formula for the slope measures, and the picture is clearer with five points than with twenty.

Definition: the OLS line

We have \(n\) pairs \((x_i, y_i)\). Take any trial intercept \(b_0\) and trial slope \(b_1\). The line \(b_0 + b_1 x\) misses point \(i\) by \(y_i - b_0 - b_1 x_i\), and the sum of its squared misses is

$$ S(b_0, b_1) = \sum_{i=1}^{n}\bigl(y_i - b_0 - b_1 x_i\bigr)^2 . $$

In words: S adds up the squared vertical gaps between the points and the line \(b_0 + b_1 x\).

The ordinary least squares estimates \(\hat\beta_0\) and \(\hat\beta_1\) are the values of \(b_0\) and \(b_1\) at which \(S(b_0, b_1)\) is smallest. The OLS line is \(\hat y = \hat\beta_0 + \hat\beta_1 x\), and the gaps it leaves are its residuals.

Remarks. \(S\) is a function of \(b_0\) and \(b_1\). The \(x_i\) and \(y_i\) are fixed numbers once the sample is collected, so \(S\) changes only when we change the line. For the five workers below, \(S(10, 2) = 2.00\) and \(S(9.6, 2.2) = 1.60\). The Greek letters \(\beta_0\) and \(\beta_1\) stand for the intercept and slope of the true line in the population, which we never see (lesson 10 sets this out). A hat marks the number we compute from the sample to estimate each of them: here, the pair of trial values at which \(S\) is smallest. That pair is unique as long as the x values are not all equal. Other books write \(a\) and \(b\), or \(\alpha\) and \(\beta\); the letters are labels and nothing more.

Least squares: the line with the smallest sum of squared residuals. Ordinary: every point counts equally in that sum. The OLS explainer says why squares and not absolute gaps, with three lines through the same five points.

What students say

“Nicky is an excellent econometrics tutor. He explains complex concepts clearly and makes them much easier to understand.”
Charles GardnerGoogle review
“I was completely lost in my economics class, and then I started working Nicky and he totally saved me. He was excellent at explaining the material and extremely accommodating to meet with me many times despite us being in different time zones! Highly recommend working with Nicky!”
Claire ChouGoogle review
“Nicky is a very good and thorough teacher. He has excellent knowledge of econometrics and takes the time to work through your questions. Highly recommended!”
ChrisEconometrics · 22/08
“Really great tutor! Encouraging, knowledgeable, friendly”
JedEconometrics · 09/02
“Very good lesson, Nicky is very helpful.”
ChrisEconometrics · 19/08
“Very helpful and clear.”
ClaireEconometrics · 22/01
“I gather it was very useful, thank you!”
ClaireEconometrics · 12/01
“Fantastic!”
JedEconometrics · 11/02

2. What the slope formula measures

Five workers, with made-up numbers so that every step fits on one line. \(x\) is years of education after 16 and \(y\) is hourly pay in pounds.

Workerx (years)y (pounds)
Ana010
Ben112
Cara213
Dev316
Eli419

Start with the means: \(\bar x = 10/5 = 2\) and \(\bar y = 70/5 = 14\). Now draw a vertical line at \(x = 2\) and a horizontal line at \(y = 14\). They cross at the point of means, (2, 14), and they cut the picture into four quadrants.

Scatter of the five workers with dashed lines at the mean of x (2) and the mean of y (14), crossing at the point of means. The top-right and bottom-left quadrants are lightly shaded. Each point is labelled with its product of deviations: Ana (-2)(-4) = +8, Ben (-1)(-2) = +2, Cara (0)(-1) = 0, Dev (+1)(+2) = +2, Eli (+2)(+5) = +10. The products sum to 22 and the squared x deviations sum to 10, so the slope is 2.2.
Figure 2. The point of means splits the picture into four quadrants. In the shaded quadrants both deviations have the same sign, so their product is positive. Products: +8, +2, 0, +2, +10, total 22. Squared x deviations: 4, 1, 0, 1, 4, total 10.

Take Eli. He has two years more education than average and earns £5 more than average, so his two deviations are +2 and +5 and their product is +10. Ana is two years below average and £4 below average: two negative deviations, and their product is +8. In the top-left and bottom-right quadrants one deviation is positive and the other negative, so the product is negative; nobody sits there. Cara sits exactly on the vertical line, so her x deviation is 0 and her product is 0. Add the five products and you get 22.

Intuitively, the total of the products says which way the points lean: up to the right gives a positive total, down to the right a negative one. Points in the top-right and bottom-left quadrants push the total up, points in the other two pull it down, and the balance decides the sign of the slope. That total is the numerator of the slope. Its units are wrong, though: pounds times years, when a slope needs pounds per year. It also grows with the spread of x. Dividing by the sum of the squared x deviations, 4 + 1 + 0 + 1 + 4 = 10 (in years squared), fixes both. Squares are never negative, so the division cannot change the sign. Hence 22/10 = 2.2 pounds an hour per year of education.

$$ \hat\beta_1 = \frac{\sum_{i=1}^{n}(x_i-\bar{x})(y_i-\bar{y})}{\sum_{i=1}^{n}(x_i-\bar{x})^2} $$ $$ \hat\beta_0 = \bar{y} - \hat\beta_1\bar{x} $$

In words: slope = sum of the products of deviations, divided by the sum of squared x deviations; intercept = mean of y minus slope times mean of x.

Divide the top and the bottom by \(n\) (or by \(n - 1\)) and you have the sample covariance of x and y over the sample variance of x (lesson 3 defines both). The ratio is the same whichever we divide by, so in computing a slope the division can be left out. The intercept formula says one thing: the line passes through the point of means. Put \(\bar x\) in and you get \(\bar y\) out. The calculus that turns "smallest sum of squares" into these two formulas is set out step by step in the OLS explainer, and in matrix form on the OLS derivation page; we will not need it in this lesson.

3. The calculation, step by step

The same five workers, now as a calculation you can repeat on any small data set. Two passes through the table: one for the means, one for the deviations.

  1. Means. 2 and 14, from section 2.
  2. Deviations, products and squares. Subtract 2 from each x and 14 from each y, multiply the pair, and square the x deviation.
    Workerxyx - 2y - 14product(x - 2)2
    Ana010-2-484
    Ben112-1-221
    Cara2130-100
    Dev3161221
    Eli41925104
    Sum1070002210
    The two deviation columns must add to zero. If they do not, a mean is wrong; stop and fix it before going on.
  3. Slope. \(\hat\beta_1 = 22/10 = 2.2\) pounds an hour per year of education.
  4. Intercept. \(\hat\beta_0 = 14 - 2.2 \times 2 = 9.6\) pounds an hour. The slope comes first; the intercept needs it. Here x = 0 is a real case (a worker who left education at 16), so 9.6 is that worker's fitted pay.
  5. Fitted values and residuals. Put each x into \(\hat y = 9.6 + 2.2x\) and subtract the fitted value from the actual y.
    WorkeryFittedResidualResidual2
    Ana109.60.40.16
    Ben1211.80.20.04
    Cara1314.0-1.01.00
    Dev1616.2-0.20.04
    Eli1918.40.60.36
    Sum7070.00.01.60
    The squared residuals add to 1.60. This is \(S(9.6,\,2.2)\), the smallest value \(S\) can take for these five workers: the line 10 + 2x, for example, gives \(S(10,\,2) = 2.00\).
Scatter of the five workers with the fitted line y = 9.6 + 2.2x and blue vertical segments marking the residuals: +0.4, +0.2, -1.0, -0.2 and +0.6. The residuals add to zero and their squares add to 1.60.
Figure 3. The residuals are the vertical gaps to the line. 9.6 + 2.2x leaves residuals of +0.4, +0.2, -1.0, -0.2 and +0.6 pounds. Three above the line, two below, and the total is exactly zero.
Three checks on the arithmetic. (1) The residuals sum to zero: 0.4 + 0.2 - 1.0 - 0.2 + 0.6 = 0. (2) The line passes through the point of means: 9.6 + 2.2 × 2 = 14. (3) Each x times its residual sums to zero: 0(0.4) + 1(0.2) + 2(-1.0) + 3(-0.2) + 4(0.6) = 0.2 - 2.0 - 0.6 + 2.4 = 0. Checks (1) and (3) are the two conditions that hold at the bottom of \(S\), where its slopes in the intercept and slope directions are both zero (the first-order conditions), and (2) follows from (1). Hence all three hold for every simple least-squares line with an intercept, whatever the data, and a failed check means an arithmetic slip, not an unusual data set.

If the exam gives you sums instead of a table

A question may give you only \(\sum x\), \(\sum y\), \(\sum xy\) and \(\sum x^2\), and expect the equivalent form:

$$ \sum (x_i-\bar x)(y_i-\bar y) = \sum x_i y_i - n\bar x\bar y $$ $$ \sum (x_i-\bar x)^2 = \sum x_i^2 - n\bar x^2 $$

In words: the sum of products of deviations equals the sum of xy minus n times the product of the means; the sum of squared x deviations equals the sum of x squared minus n times the mean of x squared. (Expand the first bracket: \(\sum xy - \bar x \sum y - \bar y \sum x + n\bar x \bar y\), and since \(\sum x = n\bar x\) and \(\sum y = n\bar y\) the last three terms collapse to \(-n\bar x\bar y\).)

For the five workers, the sum of xy is 0(10) + 1(12) + 2(13) + 3(16) + 4(19) = 162 and the sum of x2 is 0 + 1 + 4 + 9 + 16 = 30. So the numerator is 162 - 5 × 2 × 14 = 22 and the denominator is 30 - 5 × 22 = 10: the same two numbers as the table, and the same slope of 2.2. The deviation table is the version to learn from, because it shows what each worker contributes. The sums version is the one to use under time pressure. On one time-series paper I marked, the question supplied a formula as a hint and many scripts re-derived it from scratch instead of using it. If the paper hands you the sums, use them.

4. The same arithmetic on 20 real points

Back to the Premier League. Goal difference is x and points is y. Two facts make this example unusually clean. The mean of goal difference is exactly zero in every season, because every goal scored is a goal conceded by somebody else; so the x deviations are the goal differences themselves. And the mean of points is 1,046/20 = 52.3.

ClubGoal diff. (x)Points (y)y - 52.3productx2
Man City629138.72,399.43,844
Arsenal628936.72,275.43,844
Liverpool458229.71,336.52,025
Aston Villa156815.7235.5225
Tottenham136613.7178.1169
Chelsea146310.7149.8196
Newcastle23607.7177.1529
Man United-1607.7-7.71
West Ham-1452-0.34.2196
Crystal Palace-149-3.33.31
Brighton-748-4.330.149
Bournemouth-1348-4.355.9169
Fulham-647-5.331.836
Wolves-1546-6.394.5225
Everton-1140-12.3135.3121
Brentford-939-13.3119.781
Nott'm Forest-1832-20.3365.4324
Luton-3326-26.3867.91,089
Burnley-3724-28.31,047.11,369
Sheffield Utd-6916-36.32,504.74,761
Sum01,0460.012,004.019,254

Official points, with the season's deductions (Everton 8, Nottingham Forest 4) applied. Because the mean goal difference is 0, the "x - mean" column is x itself and is not repeated.

Slope: 12,004/19,254 = 0.6235 points per goal of goal difference. Intercept: 52.3 - 0.6235 × 0 = 52.3, the average points total. So the line is points = 52.3 + 0.6235 × goal difference.

Software does the same arithmetic. The code below reads the 20 rows from premier-league-2023-24.csv (save it in your working folder first) and fits the line. The two numbers we found by hand, 0.6235 and 52.3, are in the first column of what it prints. The other columns are the subject of lessons 10 and 11.

Code and output:

Stata: the code

import delimited "premier-league-2023-24.csv", clear
regress points gd

Stata: what it prints

. regress points gd

      Source |       SS           df       MS      Number of obs   =        20
-------------+----------------------------------   F(1, 18)        =    233.77
       Model |  7483.95222         1  7483.95222   Prob > F        =    0.0000
    Residual |  576.247782        18  32.0137657   R-squared       =    0.9285
-------------+----------------------------------   Adj R-squared   =    0.9245
       Total |      8060.2        19  424.221053   Root MSE        =    5.6581

------------------------------------------------------------------------------
      points | Coefficient  Std. err.      t    P>|t|     [95% conf. interval]
-------------+----------------------------------------------------------------
          gd |   .6234549   .0407763    15.29   0.000      .537787    .7091227
       _cons |       52.3   1.265183    41.34   0.000     49.64195    54.95805
------------------------------------------------------------------------------

R: the code

# Premier League 2023/24 final table: points (after deductions) and goal difference
pl <- read.csv("premier-league-2023-24.csv")
fit <- lm(points ~ gd, data = pl)
summary(fit)
confint(fit)

R: what it prints

> # Premier League 2023/24 final table: points (after deductions) and goal difference
> pl <- read.csv("premier-league-2023-24.csv")
> fit <- lm(points ~ gd, data = pl)
> summary(fit)

Call:
lm(formula = points ~ gd, data = pl)

Residuals:
   Min     1Q Median     3Q    Max 
-9.078 -5.285  0.055  4.253  8.428 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) 52.30000    1.26518   41.34  < 2e-16 ***
gd           0.62345    0.04078   15.29 9.36e-12 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 5.658 on 18 degrees of freedom
Multiple R-squared:  0.9285,	Adjusted R-squared:  0.9245 
F-statistic: 233.8 on 1 and 18 DF,  p-value: 9.356e-12

> confint(fit)
                2.5 %     97.5 %
(Intercept) 49.641949 54.9580511
gd           0.537787  0.7091227

Python: the code

import pandas as pd
import statsmodels.formula.api as smf

# Premier League 2023/24 final table: points (after deductions) and goal difference
pl = pd.read_csv("premier-league-2023-24.csv")
fit = smf.ols("points ~ gd", data=pl).fit()
print(fit.summary())

Python: what it prints

                            OLS Regression Results                            
==============================================================================
Dep. Variable:                 points   R-squared:                       0.929
Model:                            OLS   Adj. R-squared:                  0.925
Method:                 Least Squares   F-statistic:                     233.8
Date:                Thu, 08 Oct 2026   Prob (F-statistic):           9.36e-12
Time:                        14:49:35   Log-Likelihood:                -61.987
No. Observations:                  20   AIC:                             128.0
Df Residuals:                      18   BIC:                             130.0
Df Model:                           1                                         
Covariance Type:            nonrobust                                         
==============================================================================
                 coef    std err          t      P>|t|      [0.025      0.975]
------------------------------------------------------------------------------
Intercept     52.3000      1.265     41.338      0.000      49.642      54.958
gd             0.6235      0.041     15.290      0.000       0.538       0.709
==============================================================================
Omnibus:                        2.895   Durbin-Watson:                   1.352
Prob(Omnibus):                  0.235   Jarque-Bera (JB):                1.209
Skew:                          -0.004   Prob(JB):                        0.546
Kurtosis:                       1.795   Cond. No.                         31.0
==============================================================================

Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
The 20 clubs of 2023/24 as grey points with dashed lines at the mean goal difference (0) and the mean points (52.3). The top-right and bottom-left quadrants are lightly shaded and hold 19 clubs. Manchester United, at goal difference -1 and 60 points, is the only club in a negative-product quadrant, with product (-1)(+7.7) = -7.7.
Figure 4. Nineteen positive products and one small negative one. Seven clubs in the top-right quadrant, twelve in the bottom-left, Manchester United alone in the top-left. Source: openfootball/england (CC0), 2023/24; deductions applied. Own calculations.

The quadrant picture explains the size of the slope as well as its sign. Sheffield United contribute the largest product, 2,504.7: 69 goals worse than average and 36.3 points below it. Manchester United are the only club in a negative quadrant: a goal difference one below average and 7.7 points above it, product -7.7. The 19 positive products add to 12,011.7 and the one negative product takes 7.7 off, which is why the slope is firmly positive.

Read the slope with its units: each extra goal of goal difference went with 0.62 more points. Aston Villa had a goal difference of +15, so the line predicts 52.3 + 0.6235 × 15 = 61.65 points; they finished on 68, a residual of +6.35. What the line leaves over, the residuals, is the interesting part of this example, and the explainer takes them up.

5. Common mistakes

  • Dividing by the wrong sum. The denominator is \(\sum(x_i - \bar x)^2\), the spread of x. Divide by \(\sum(y_i - \bar y)^2\) instead and you get the slope of x on y, a different line that minimises horizontal gaps.
  • Forgetting the correction in the sums form. \(\sum xy / \sum x^2\) is not the slope: for the five workers it gives 162/30 = 5.4, not 2.2. Subtract \(n\bar x\bar y\) on top and \(n\bar x^2\) underneath first.
  • Rise over run between two points. (19 - 10)/(4 - 0) = 2.25 uses Ana and Eli and ignores the other three. Least squares uses every point, and here it gives 2.2.
  • Computing the intercept first. The intercept is \(\bar y - \hat\beta_1 \bar x\), so it needs the slope. Compute the slope first.
  • Losing the units. A slope has units. "2.2" does not say what changed; "£2.20 an hour per year of education" does, and so does "0.62 points per goal of goal difference".
  • Mixing n and n - 1. Both cancel in the slope. Whichever you divide by, use the same one on top and bottom, or divide by neither, as the tables above do.

6. Check your understanding

Five questions, marked on the page; every option has an explanation, including the wrong ones. (Without JavaScript the explanations are shown beneath each question.)

1. From a sample: the sum of (x - x̄)(y - ȳ) is 30, the sum of (x - x̄)2 is 12 and the sum of (y - ȳ)2 is 90. What is the OLS slope of y on x?

30/90 divides by the spread of y. That is the slope of x on y, a different line. The slope of y on x divides by the spread of x.

12/30 is the formula upside down. The slope is "how y moves per unit of x", so the sum of products goes on top and the x variation underneath.

30/√(12 × 90) = 0.913 is the correlation coefficient. It is unit-free; the slope has units of y per unit of x and equals the correlation times sd(y)/sd(x): 0.913 × 2.74 = 2.5.

Correct. Slope = 30/12 = 2.5: the sum of products of deviations over the sum of squared x deviations.

Were you sure?

2. In a scatter of 30 firms, every point lies in the top-left or the bottom-right quadrant around the point of means: above-average x with below-average y, or the reverse. What does this tell you about the OLS slope of y on x?

Top-left and bottom-right both give negative products (one deviation positive, one negative), so they add up rather than cancel. Cancellation happens between a positive quadrant and a negative one.

Correct. A point in either of those quadrants has deviations of opposite sign, so its product is negative. A sum of negative products is negative, and the denominator cannot change the sign. (It is the sum that matters, not the count: one far-out point can outweigh many near the means.)

The denominator is always positive, so it sets the size of the slope and never its sign. The sign comes from the numerator, the sum of the products.

Were you sure?

3. In the 2023/24 Premier League regression, points = 52.30 + 0.6235 × goal difference, the intercept 52.30 equals the average points per club exactly. Why?

Correct. Every goal scored is a goal conceded by another club, so the mean of x is zero; intercept = ȳ - slope × x̄ = ȳ.

Only when the mean of x is zero. In general the intercept is ȳ - slope × x̄: for the five workers it is 14 - 2.2 × 2 = 9.6, not 14.

Points are not rescaled or centred; their mean is 52.3. It is goal difference, the x variable, whose mean is zero by construction.

Were you sure?

4. Five workers: pay (pounds an hour) on years of education after 16 gives \(\hat y = 9.6 + 2.2x\). How should the 2.2 be read?

A percentage reading needs the log of pay on the left-hand side. In levels the slope is in pounds, and with one regressor nothing else is held fixed.

2.2 is pounds per year, not years per pound. Two workers 2.2 years apart are, on the line, 2.2 × 2.2 = £4.84 apart in pay.

Correct. The slope has units of y per unit of x: pounds an hour per year. "On average" because the line describes the typical worker at each x, and "goes with" because the fit alone does not show that education causes the difference.

Were you sure?

5. Why do the residuals from an OLS regression with an intercept always sum to zero?

Errors are unobserved and their sample sum is almost never zero. Residuals are computed from the fitted line, and the fitting is what forces their sum to zero.

Correct. Whatever the slope, the intercept that makes the sum of squares smallest is the one that makes the residuals average zero (with calculus: differentiate with respect to the intercept and set the result to zero). The same step for the slope gives "sum of x times residual = 0", the third check in section 3.

No symmetry is needed. The five-worker residuals are 0.4, 0.2, -1.0, -0.2, 0.6: three above, two below, and they still sum to zero.

Were you sure?

7. Three questions about the arithmetic

Neither, unless you want to. The slope is a ratio of two sums, and dividing both by n, or both by n - 1, leaves the ratio unchanged. The choice only matters when you report a covariance or a variance on its own. In a slope calculation, work with the raw sums and divide once.

Compute the two means, then the numerator as the sum of xy minus n times the product of the means, and the denominator as the sum of x squared minus n times the squared mean of x. Divide. For the five workers: (162 - 5 × 2 × 14)/(30 - 5 × 4) = 22/10 = 2.2.

The sum of squared deviations of x, the variable on the right-hand side of the regression. The slope answers "how much does y change per unit of x", so the spread of x goes underneath. Dividing by the spread of y instead gives the slope of x on y, which is a different line.

8. Where next

Send me your regression: module, output and deadline

I tutor econometrics one-to-one, from a first regression through to endogeneity, panel data and time series. Bring the question you are stuck on and we will work through it in the free 30-minute consultation.

Book a free 30-minute consultation Econometrics tutor: how it works

Data and figures. Five-worker example: illustrative data. Premier League: match results from openfootball/england (CC0), 2023/24 season, with the deductions for Everton (8 points) and Nottingham Forest (4 points) applied; sums and products computed for this lesson and checked two ways (the closed-form sums agree with R and statsmodels to better than four significant figures); the 20-row file the code reads is premier-league-2023-24.csv. Figures drawn for this lesson.

Free 30-min consultationNo obligation · reply within one business day
Book now