Logistic regression for classification
Turn a linear score into a probability with the sigmoid and train it by gradient descent on log loss.
On this page
Linear regression and gradient descent.
- Turn a linear score into a probability with the sigmoid and train it by gradient descent on log loss.
- Predict the sample output and explain the state changes.
- Complete the practice task and check the boundary cases.
The concept
Despite its name, logistic regression is a classification method. It computes a linear score z = w·x + b and passes it through the sigmoid function σ(z) = 1 / (1 + e⁻ᶻ), which maps any number to a value between 0 and 1 that is read as the probability of the positive class. A prediction is positive when that probability is at least 0.5, which happens exactly when z >= 0.
The model is trained by minimizing the log loss (binary cross-entropy), which punishes confident wrong predictions heavily. Its gradient has the same pleasant shape as in linear regression: ∂L/∂w = average of (σ(z) − y)·x. The decision boundary, where the probability is 0.5, is at x = −b / w for one feature.
The data below are separable: every example with x <= 3 is class 0 and every example with x >= 4 is class 1. The trained model classifies all six correctly and places the boundary near 3.47, in the gap between 3 and 4. The exact position within the gap depends on how long training runs. For separable data, the unregularized weights would grow forever as training continues, so practical implementations add a regularization penalty or stop early.
Code example
import math
xs = [1, 2, 3, 4, 5, 6]
labels = [0, 0, 0, 1, 1, 1]
def sigmoid(z):
return 1 / (1 + math.exp(-z))
w = b = 0.0
for _ in range(3000):
grad_w = sum((sigmoid(w * x + b) - y) * x for x, y in zip(xs, labels)) / len(xs)
grad_b = sum((sigmoid(w * x + b) - y) for x, y in zip(xs, labels)) / len(xs)
w -= 0.5 * grad_w
b -= 0.5 * grad_b
predictions = [1 if sigmoid(w * x + b) >= 0.5 else 0 for x in xs]
print(predictions == labels)
print(round(sigmoid(w * 2 + b), 3), round(sigmoid(w * 3.5 + b), 3), round(sigmoid(w * 5 + b), 3))
print(round(-b / w, 2))True 0.001 0.537 0.999 3.47
Follow the code
Open the walkthrough to inspect the example one step at a time.
Show guided walkthrough
import math xs = [1, 2, 3, 4, 5, 6]labels = [0, 0, 0, 1, 1, 1] def sigmoid(z): return 1 / (1 + math.exp(-z)) w = b = 0.0for _ in range(3000): grad_w = sum((sigmoid(w * x + b) - y) * x for x, y in zip(xs, labels)) / len(xs) grad_b = sum((sigmoid(w * x + b) - y) for x, y in zip(xs, labels)) / len(xs) w -= 0.5 * grad_w b -= 0.5 * grad_b predictions = [1 if sigmoid(w * x + b) >= 0.5 else 0 for x in xs]print(predictions == labels)print(round(sigmoid(w * 2 + b), 3), round(sigmoid(w * 3.5 + b), 3), round(sigmoid(w * 5 + b), 3))print(round(-b / w, 2))Follow the example
Start to inspect the source, values, and output. These prepared steps explain the published sample; grouped loop steps describe multiple iterations.
View the complete dry-run table
| Step / line | What happens | State after step | Output so far |
|---|---|---|---|
| The sigmoid squashes any score into (0, 1), so the output can be read as a probability. | — | — | |
| The log-loss gradient: prediction minus label, weighted by the input. | — | — | |
| After training, all six examples are classified correctly. | — | True | |
| Probability of class 1: near 0 at x = 2, about one half in the gap at 3.5, near 1 at x = 5. | — | True 0.001 0.537 0.999 | |
| The decision boundary is where w·x + b = 0, at x ≈ 3.47. | — | True 0.001 0.537 0.999 3.47 |
Behind the scenes
How Python processes this code
Python runs this source through its interpreter. It creates objects for values and resolves names as each statement runs.
Cost and common mistakes
Each training step costs O(n) for n examples (O(n·d) with d features), the same as linear regression.
- Logistic regression produces a probability, not a certainty. Use a threshold appropriate to the costs of errors, not always 0.5.
- On perfectly separable data the weights keep growing, making the probabilities extreme. Use regularization.
- The model is linear in its inputs, so a single logistic regression cannot separate classes that need a curved boundary without feature engineering.
Try it yourself
Roughly what probability does the model give for x = 3.47?
Reveal answer and reasoning
About 0.5, because that is the decision boundary where w·x + b = 0 and σ(0) = 0.5.