Regression
Least-Squares Line
Fit a least-squares line by computing slope = Σ(xi−mx)(yi−my) /
Σ(xi−mx)² and intercept = my − slope×mx. Two loops: the first accumulates
sx and sy for the means; the second accumulates cov_sum and var_sum. ddof
cancels (n−1 in both numerator and denominator), so unnormalized sums suffice.
Library: scipy.stats.linregress(x, y) — RESULT = (slope, intercept) rounded.
By hand
With the library
scipy.stats.linregress(x, y) returns slope, intercept, r (correlation),
pvalue, and stderr. The snapshot shows slope, intercept, and r; RESULT is
(slope, intercept).
x = [1, 2, 3, 4, 5]
y = [2, 4, 4, 4, 6]
n = len(x)
sx = 0.0
sy = 0.0
for i in range(n):
sx = sx + x[i]
sy = sy + y[i]
mx = sx / n
my = sy / n
cov_sum = 0.0
var_sum = 0.0
for i in range(n):
cov_sum = cov_sum + (x[i] - mx) * (y[i] - my)
var_sum = var_sum + (x[i] - mx) ** 2
slope = cov_sum / var_sum
intercept = my - slope * mx
print('RESULT:', (round(slope, 4), round(intercept, 4)))
from scipy import stats
from dalib.display import set_display
set_display()
x = [1, 2, 3, 4, 5]
y = [2, 4, 4, 4, 6]
fit = stats.linregress(x, y)
print('slope:', round(float(fit.slope), 4))
print('intercept:', round(float(fit.intercept), 4))
print('r:', round(float(fit.rvalue), 4))
print('RESULT:', (round(float(fit.slope), 4), round(float(fit.intercept), 4)))
slope: 0.8
intercept: 1.6
r: 0.8944
RESULT: (0.8, 1.6)
Honesty
This lesson shows the computation of the least-squares line exactly, on a tiny pinned sample. The slope and intercept are arithmetically correct and reproducible, but a line fit to a handful of points is a mechanism demo, not a predictive model — it is not a statistical finding. Reading significance into the slope, or extrapolating the line beyond the observed x-range, is not warranted at this sample size; real inference needs an adequate sample and assumption checks (linearity, independent errors of roughly constant variance).
Implementation notes
- ddof cancellation: slope = cov_sum/var_sum where both are unnormalized (Σ products, not divided by n−1). The n−1 factors cancel, so the result equals np.cov(x,y)[0,1]/np.var(x,ddof=1) exactly.
scipy.stats.linregressuses a numerically stable internal algorithm; parity holds to 4 dp here since the data are small integers.- The r value from linregress equals Pearson r from ch04 for the same data.
- Cross-reference:
covariance-by-hand(ch04) for the cov_sum accumulation;pearson-correlation(ch04) for the r value linregress also reports.