Linear Regression
Gradient Step (One Weight)
Perform ONE gradient-descent step for a 1D model y_pred=w·x (no bias). Gradient of MSE w.r.t. w: grad = (2/n)Σ((w·xᵢ−yᵢ)·xᵢ). Update: w_new = w − lr·grad. Library: NumPy vectorized gradient confirms the loop. RESULT: (gradient, w_new) rounded.
By hand
x=[1,2,4], y=[2,4,8]. w=1.0, lr=0.1. Errors: −1,−2,−4. Σ(err·x)=−1−4−16=−21. grad=(2/3)(−21)=−14.0. w_new=1.0−0.1·(−14.0)=2.4.
x = [1, 2, 4]
y = [2, 4, 8]
w = 1.0
lr = 0.1
n = len(x)
grad = 0.0
for i in range(n):
err = w * x[i] - y[i]
grad = grad + err * x[i]
grad = (2 / n) * grad
w_new = w - lr * grad
print('RESULT:', (round(grad, 4), round(w_new, 4)))
x ← [1, 2, 4]
1x = [1, 2, 4]2y = [2, 4, 8]values this step[1, 2, 4]xy ← [2, 4, 8]
1x = [1, 2, 4]2y = [2, 4, 8]3w = 1.0values this step[2, 4, 8]yw ← 1.0
2y = [2, 4, 8]3w = 1.04lr = 0.1values this step1.0wlr ← 0.1
3w = 1.04lr = 0.15n = len(x)values this step0.1lrn ← 3
4lr = 0.15n = len(x)6grad = 0.0values this step3ngrad ← 0.0
5n = len(x)6grad = 0.07for i in range(n):values this step0.0gradi ← 0
6grad = 0.07for i in range(n):8 err = w * x[i] - y[i]values this step0ierr ← -1.0
7for i in range(n):8 err = w * x[i] - y[i]9 grad = grad + err * x[i]values this step-1.0errgrad ← -1.0
8 err = w * x[i] - y[i]9 grad = grad + err * x[i]10grad = (2 / n) * gradvalues this step0.0 → -1.0gradi ← 1
6grad = 0.07for i in range(n):8 err = w * x[i] - y[i]values this step0 → 1ierr ← -2.0
7for i in range(n):8 err = w * x[i] - y[i]9 grad = grad + err * x[i]values this step-1.0 → -2.0errgrad ← -5.0
8 err = w * x[i] - y[i]9 grad = grad + err * x[i]10grad = (2 / n) * gradvalues this step-1.0 → -5.0gradi ← 2
6grad = 0.07for i in range(n):8 err = w * x[i] - y[i]values this step1 → 2ierr ← -4.0
7for i in range(n):8 err = w * x[i] - y[i]9 grad = grad + err * x[i]values this step-2.0 → -4.0errgrad ← -21.0
8 err = w * x[i] - y[i]9 grad = grad + err * x[i]10grad = (2 / n) * gradvalues this step-5.0 → -21.0gradfor i in range(n):
6grad = 0.07for i in range(n):8 err = w * x[i] - y[i]grad ← -14.0
9 grad = grad + err * x[i]10grad = (2 / n) * grad11w_new = w - lr * gradvalues this step-21.0 → -14.0gradw_new ← 2.4000000000000004
10grad = (2 / n) * grad11w_new = w - lr * grad12print('RESULT:', (round(grad, 4), round(w_new, 4)))values this step2.4000000000000004w_newstdout ← RESULT: (-14.0, 2.4)
11w_new = w - lr * grad12print('RESULT:', (round(grad, 4), round(w_new, 4)))values this stepRESULT: (-14.0, 2.4)stdout
With NumPy
np.sum((w*x - y) * x) computes Σ((w·xᵢ−yᵢ)·xᵢ) vectorized.
import numpy as np
from dalib.display import set_display
set_display()
x = np.array([1, 2, 4])
y = np.array([2, 4, 8])
w = 1.0
lr = 0.1
n = len(x)
grad = round(float((2 / n) * np.sum((w * x - y) * x)), 4)
w_new = round(w - lr * grad, 4)
print('gradient:', grad)
print('RESULT:', (grad, w_new))
gradient: -14.0
RESULT: (-14.0, 2.4)
Honesty
This lesson shows a single gradient step computed exactly, on a tiny pinned sample. The updated weight is arithmetically correct and reproducible, but one step on a handful of points illustrates the update rule, not a trained model — the resulting weight is not a fitted estimate and warrants no inference. Real fitting needs many steps (or a closed-form solve), an adequate sample, and a held-out check before any prediction is trustworthy.
Implementation notes
- ONE step only — full gradient descent iterates this update until convergence.
Closed-form
normal-equation-1d(this chapter) reaches the exact optimum in one computation; gradient descent approximates it iteratively. - The gradient is negative (MSE decreases as w increases from 1.0 toward the optimum); subtracting a negative gradient raises w.
- The true optimum for this data is w*=2.0 (Σxᵢyᵢ/Σxᵢ²=42/21=2.0). One step with lr=0.1 overshoots to 2.4 — illustrating how learning rate choice affects convergence.
- No bias term: y_pred=w·x. Adding an intercept b requires a second update: b_new = b − lr·(2/n)Σ(w·xᵢ+b−yᵢ).
- The gradient formula (2/n)Σ((w·xᵢ−yᵢ)·xᵢ) is the derivative of MSE = (1/n)Σ(w·xᵢ−yᵢ)² with respect to w by the chain rule.