Keep the straight boundary. Let every feature vote. Hand back a probability.
The default linear classifier — and the model you'll actually ship.
Two classes, some overlap. A straight line can mostly separate them — but it has to tilt, because both features carry signal.
Linear score, then squash it to a probability:
z=w⊤x+bp=σ(z)=1+e−z1Train by minimizing cross-entropy — the loss the sigmoid was built for:
L=−N1i∑[yilogpi+(1−yi)log(1−pi)]The gradient collapses to the error times the features:
∂w∂L=N1i∑(pi−yi)xiClean (p - y). That cancellation is why you don't use squared error here.
Each frame is one real gradient step. The orange line is where p = 0.5; red rings are current mistakes; the loss drops underneath.
Zero weights → no line → a crude cut → rotate and slide into the gap. 96% on the toy set.
Flat at the ends (confident), steep in the middle (uncertain), crossing 0.5 at z = 0.
Pima diabetes, 537 train / 231 test. Our gradient descent lands on sklearn's answer; both beat the one-feature threshold.
Scratch 0.7662 · sklearn 0.7662 · week-1 stump 0.7316. Heaviest weights: glucose, BMI, pregnancies — in that order.
(p - y). Don't use squared error.