Regression
18 min
Linear regression fits a straight line y = slope × x + intercept
through a set of points, minimizing the total squared vertical distance
between the line and every actual point — that's what "least squares"
means.
def slope_intercept(xs, ys):
n = len(xs)
x_bar = sum(xs) / n
y_bar = sum(ys) / n
numerator = sum((x - x_bar) * (y - y_bar) for x, y in zip(xs, ys))
denominator = sum((x - x_bar) ** 2 for x in xs)
slope = numerator / denominator
intercept = y_bar - slope * x_bar
return slope, intercept
The slope is the headline number in most regression stories — 'each additional unit of x is associated with slope more units of y,' holding the linear relationship steady across the whole range of the data.
The slope tells you the direction and steepness of the relationship — R² tells you how well the line actually fits. R² of 1.0 means every point sits exactly on the line; R² of 0 means the line explains none of the variation in y (you'd do just as well predicting the average every time).
import math
def r_squared(xs, ys):
x_bar = sum(xs) / len(xs)
y_bar = sum(ys) / len(ys)
numerator = sum((x - x_bar) * (y - y_bar) for x, y in zip(xs, ys))
denom_x = sum((x - x_bar) ** 2 for x in xs)
denom_y = sum((y - y_bar) ** 2 for y in ys)
correlation = numerator / math.sqrt(denom_x * denom_y)
return correlation ** 2
A high R² doesn't prove x causes y — it only measures how tightly the two move together, which is why "correlation isn't causation" comes up constantly in any discussion of regression results.
Write `slope_intercept(xs, ys)`, returning `(slope, intercept)` for the ordinary least squares line fit to `xs`/`ys`. Formula: slope = Σ((x−x̄)(y−ȳ)) / Σ((x−x̄)²), intercept = ȳ − slope × x̄.
Write `r_squared(xs, ys)`, returning R² for the OLS fit. For simple linear regression, R² equals the squared Pearson correlation between x and y.
What does R² represent in a simple linear regression?
You can fit a least-squares line by hand from the slope/intercept formulas and compute R² to judge how well it fits.