Regression
R-Squared
Compute R² = 1 − SS_res/SS_tot where SS_res = Σ(yᵢ−ŷᵢ)² (residual sum of
squares) and SS_tot = Σ(yᵢ−ȳ)² (total sum of squares). One loop for the
mean, one loop accumulating both SS_res and SS_tot together. Library:
scipy.stats.linregress(x, y).rvalue**2 (R² = r² in simple linear
regression). RESULT: R² (rounded).
By hand
slope=0.8, intercept=1.6, x=[1,2,3,4,5], y=[2,4,4,4,6], mean_y=4.0. SS_res=1.6 (SSE from residuals-and-sse). SS_tot=(2−4)²+0+0+0+(6−4)²=8. R²=1−1.6/8=0.8.
slope = 0.8
intercept = 1.6
x = [1, 2, 3, 4, 5]
y = [2, 4, 4, 4, 6]
n = len(x)
total_y = 0.0
for v in y:
total_y = total_y + v
mean_y = total_y / n
ss_res = 0.0
ss_tot = 0.0
for i in range(n):
resid = y[i] - (slope * x[i] + intercept)
ss_res = ss_res + resid * resid
ss_tot = ss_tot + (y[i] - mean_y) ** 2
r2 = 1 - ss_res / ss_tot
print('RESULT:', round(r2, 4))
slope ← 0.8
1slope = 0.82intercept = 1.6values this step0.8slopeintercept ← 1.6
1slope = 0.82intercept = 1.63x = [1, 2, 3, 4, 5]values this step1.6interceptx ← [1, 2, 3, 4, 5]
2intercept = 1.63x = [1, 2, 3, 4, 5]4y = [2, 4, 4, 4, 6]values this step[1, 2, 3, 4, 5]xy ← [2, 4, 4, 4, 6]
3x = [1, 2, 3, 4, 5]4y = [2, 4, 4, 4, 6]5n = len(x)values this step[2, 4, 4, 4, 6]yn ← 5
4y = [2, 4, 4, 4, 6]5n = len(x)6total_y = 0.0values this step5ntotal_y ← 0.0
5n = len(x)6total_y = 0.07for v in y:values this step0.0total_yv ← 2, total_y ← 2.0
pass 1 of 56total_y = 0.07for v in y:8 total_y = total_y + v9mean_y = total_y / nvalues this step2v0.0 → 2.0total_yAll 5 passes — pass 1 is the card above pass vtotal_y1 2 0.0 → 2.0 2 2 → 4 2.0 → 6.0 3 — 6.0 → 10.0 4 — 10.0 → 14.0 5 4 → 6 14.0 → 20.0 for v in y:
6total_y = 0.07for v in y:8 total_y = total_y + vmean_y ← 4.0
8 total_y = total_y + v9mean_y = total_y / n10ss_res = 0.0values this step4.0mean_yss_res ← 0.0
9mean_y = total_y / n10ss_res = 0.011ss_tot = 0.0values this step0.0ss_resss_tot ← 0.0
10ss_res = 0.011ss_tot = 0.012for i in range(n):values this step0.0ss_toti ← 0, resid ← -0.40000000000000036, ss_res ← 0.16000000000000028
pass 1 of 511ss_tot = 0.012for i in range(n):13 resid = y[i] - (slope * x[i] + intercept)14 ss_res = ss_res + resid * resid15 ss_tot = ss_tot + (y[i] - mean_y) ** 216r2 = 1 - ss_res / ss_totvalues this step0i-0.40000000000000036resid0.0 → 0.16000000000000028ss_res0.0 → 4.0ss_totAll 5 passes — pass 1 is the card above pass iresidss_resss_tot1 0 -0.40000000000000036 0.0 → 0.16000000000000028 0.0 → 4.0 2 0 → 1 -0.40000000000000036 → 0.7999999999999998 0.16000000000000028 → 0.7999999999999999 — 3 1 → 2 0.7999999999999998 → 0.0 — — 4 2 → 3 0.0 → -0.8000000000000007 0.7999999999999999 → 1.440000000000001 — 5 3 → 4 -0.8000000000000007 → 0.40000000000000036 1.440000000000001 → 1.6000000000000014 4.0 → 8.0 for i in range(n):
11ss_tot = 0.012for i in range(n):13 resid = y[i] - (slope * x[i] + intercept)r2 ← 0.7999999999999998
15 ss_tot = ss_tot + (y[i] - mean_y) ** 216r2 = 1 - ss_res / ss_tot17print('RESULT:', round(r2, 4))values this step0.7999999999999998r2stdout ← RESULT: 0.8
16r2 = 1 - ss_res / ss_tot17print('RESULT:', round(r2, 4))values this stepRESULT: 0.8stdout
With the library
scipy.stats.linregress(x, y).rvalue**2 gives R² directly (r=2/√5,
r²=4/5=0.8). The snapshot also shows r for comparison with ch04.
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)
r2 = float(fit.rvalue ** 2)
print('r:', round(float(fit.rvalue), 4))
print('r_squared:', round(r2, 4))
print('RESULT:', round(r2, 4))
r: 0.8944
r_squared: 0.8
RESULT: 0.8
Honesty
This lesson shows the computation of R² exactly, on a tiny pinned sample. The value is arithmetically correct and reproducible, but it measures only how well the line fits these specific in-sample points — on so few points a high R² overstates fit and says nothing about out-of-sample or population performance. Treat it as "how the formula is computed," not as evidence the model generalizes; real evaluation needs held-out data and an adequate sample size.
Implementation notes
- R²=r² holds only for simple (one-predictor) linear regression; in multiple regression R² ≠ Pearson r².
- R²=0.8 means the line explains 80% of the variance in y.
- SS_tot = SS_res + SS_reg (regression sum of squares); R² = SS_reg/SS_tot.
- Cross-reference:
residuals-and-sse(this chapter) for SS_res;pearson-correlation(ch04) for r whose square gives R² here.