Easier to read with cream paper, a tint, more contrast or larger text? Choose your colours and text, once, for every page.

Free lesson

Fitting a line to data (linear regression)

After this lesson: I can fit a line to data and say how good it is.

55 min lesson3 commandsJupyterLab data science lab: pandas, Matplotlib and scikit-learn in the browser

How many bikes for a warm day?

The forecast says 20 degrees tomorrow. The shop has to decide tonight how many bikes to bring out of the store.

A year of days shows warm days are busier. A straight line through those days turns "busier" into a number you can plan with, and says how far to trust it.

By the end of this lesson

Note

I can fit a line to data and say how good it is.

Key words

WordWhat it means
Linear regressiona straight-line rule from one value to another
Slopehow much the answer changes when the input goes up by 1
Interceptthe answer when the input is 0
Residualthe true value minus the predicted one
Least squareschoosing the line with the smallest total of squared residuals
R squaredthe share of the change the line explains, from 0 to 1
Test setrows kept back to check a model

The cells students fill in are left blank in this preview.

A line is a slope and an intercept

A straight line is hires = intercept + slope * temperature. The slope says how many more hires each extra degree brings. The intercept is the line's guess at 0 degrees.

scikit-learn's LinearRegression finds both from the data. line.py fits hires against temperature alone, on all 365 days.

Fit hires against temperature

Command
docker exec jupyter python3 steps/line.py

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Least squares picks the line

Every day sits a little above or below the line. That gap is the residual. Square each residual, so a gap below counts as much as one above. Then add them up.

Least squares is the line with the smallest total. Two short sums give it: the slope from how x and y move together, then the intercept from the means.

Worked example: three days and their residuals

TemperatureHiresLine says 130 + 13 xResidualSquared
5200195525
10250260-10100
15330325525
Total0150

The cells students fill in are left blank in this preview.

The two sums by hand

Code: python
# Least squares by hand, for three days.
temps = [5, 10, 15]
hires = [200, 250, 330]
mean_x = sum(temps) / len(temps)
mean_y = sum(hires) / len(hires)
top = 0
bottom = 0
for n in range(len(temps)):
    top = top + (temps[n] - mean_x) * (hires[n] - mean_y)
    bottom = bottom + (temps[n] - mean_x) ** 2
slope = top / bottom
intercept = mean_y - slope * mean_x
print("slope:", slope, "intercept:", intercept)
# Change 330 to 300 and run again.
# Does the slope go up or down?

Type this in your notebook: the year

Code: python
import pandas as pd

hires = pd.read_csv("hires.csv")
x = hires["temp_c"]
y = hires["hires"]
slope = ((x - x.mean()) * (y - y.mean())).sum() / ((x - x.mean()) ** 2).sum()
intercept = y.mean() - slope * x.mean()
# Compare with what line.py printed.
round(slope, 1), round(intercept, 1)

Judge a line on unseen days

A line always fits the days it learnt from quite well. The real question is how it does on new days.

So split the data. Fit on about three quarters, the training set, and keep the rest back as a test set. Then measure R squared and the mean error on the test set alone.

Fit on some days, test on others

Command
docker exec jupyter python3 steps/split.py

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

A common mistake

Warning

Many people think a high R squared on the data a model learnt from shows it will predict well. A model is always flattered by data it has seen. Judge it on a test set it never saw, and quote that figure.

More inputs can explain more

Temperature alone explains about 60 per cent of the change from day to day. Rain matters too.

model.py fits one line with two inputs, temperature and rain. Each input gets its own slope. A negative slope means that input pulls the answer down.

Fit with temperature and rain

Command
docker exec jupyter python3 steps/model.py

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Going further

In your notebook, add a third input to the line: a weekend column of 1 and 0, made with hires["weekday"].isin(["Sat", "Sun"]).astype(int).

Fit it on a training set and score it on a test set, as split.py does. Does the test R squared rise? Say in a sentence what the weekend slope means for the shop.

About this lab and its source: JupyterLab data science lab: pandas, Matplotlib and scikit-learn in the browser

Teaching a class? Set this module for your students with a teacher guide, marked assignments and a lab for every student.