Machine learning from zero · Lesson 2.1 · 8 of 33 lessons ready · 10 min
Classification: drawing a boundary
In short
A classifier turns measurements into a category. Logistic regression gives a probability and a boundary; the lesson shows both on two penguin species.
Warm-up Two questions from earlier lessons. A minute, and it never blocks the lesson.
A biologist in Antarctica measures a penguin's bill and flippers. Which species is it? This is a different kind of question from "how much will the disease progress?". The answer is not a number on a scale but a choice between categories. Can the straight lines and downhill steps of the previous lessons handle that? They can, with one clever twist.
Choose an answer and how sure you are.
Answer to unlock the lab.
Interactive lab
This interactive lab runs in a browser with JavaScript enabled. The text around it describes what the lab shows.
Show the answer
Correct answer: 0.3
At threshold 0.3 the accuracy is 98.6% (3 mistakes), at 0.5 only 96.8% (7 mistakes), at 0.9 92.2% and at 0.1 90.4%. 0.5 is not sacred: the best threshold depends on the class proportions and on which mistake costs more.
Try this
- Look at the boundary first. Find the penguins that sit on the wrong side of it: these are the cases the model gets wrong even with its best line.
- Move the probability threshold slider towards one end and watch the boundary shift towards one species. Notice that the line moves but keeps its direction.
- Set the threshold near one extreme and count how the mistakes change: one species is now almost never missed, at the cost of the other.
- Find penguins close to the boundary and compare them with penguins far away. Which ones would you double-check by hand?
Now that you've tried it, let's see what was actually going on.
The idea in plain words
Predicting a category is called classification. In this lesson we use the Palmer Penguins dataset: 344 penguins of three species from islands near Palmer Station in Antarctica, each with bill, flipper and body measurements. To keep things flat, we take two species and two measurements, so every penguin is a point on a plane — one measurement across, the other up — with a known species.
A classifier has to split that plane into two regions: "species A here, species B there". The line between the regions is the decision boundary. Logistic regression, despite its name, is a classification model, and its boundary is a straight line.
The twist is that logistic regression does not answer just "A" or "B". It answers with a probability: "this penguin is species B with probability 0.9". Think of a weather forecast. The forecaster says "80% chance of rain", and you decide whether that is enough to take an umbrella. The model plays the forecaster; the threshold is your umbrella rule.
Why it works
First the model computes a score just like linear regression does: a weighted sum of the features plus an intercept, z = w₁x₁ + w₂x₂ + b. That score can be any number, so it is squeezed into the range from 0 to 1 by the sigmoid function:
p = 1 / (1 + e^(−z))
A large positive score gives a probability close to 1, a large negative score gives a probability close to 0, and a score of exactly zero gives 0.5. Penguins far from the boundary get confident probabilities; penguins near it get probabilities close to one half — the model is unsure, and it says so.
The weights are learned with gradient descent, as in lesson 4, but with a different loss. Instead of squared error the model uses log loss (also called cross-entropy). It barely punishes a confident correct answer and punishes a confident wrong answer very hard. This pushes the model to be sure only when the data justify it.
Finally, the threshold turns the probability into a decision: probability above the threshold → species B, below → species A. The usual default is 0.5, but nothing forces it. Moving the threshold moves the boundary. Because the probability depends on the weighted sum, every threshold corresponds to a line with the same direction, just shifted: the model's opinion about which way the species differ stays the same, only your demand for certainty changes.
Common mistake
Two errors are common. The first is treating 0.5 as a law. The threshold is a decision about costs, not part of the model; in medicine you may accept many false alarms to miss fewer cancers. The second is reading the probability as certainty. A probability of 0.97 means the model expects to be wrong in about three such cases out of a hundred — and only if the new data resemble the training data. A penguin from a population the model never saw can get a confident and wrong answer.
A boundary that gets most penguins right sounds good, but "most" hides a lot: which mistakes, how many, and how bad? In the next lesson we open the box of mistakes and learn to count them properly.
Quiz
Three questions to check yourself. Pick an answer, or open the answer under a question. Keyboard: arrow keys choose, Enter or Space confirms.
Key takeaways
- Classification predicts a category; the decision boundary separates the regions of each class.
- Logistic regression squeezes a weighted sum through the sigmoid to get a probability.
- The threshold turns a probability into a decision and is a choice about costs, not a fixed 0.5.
- Changing the threshold shifts a logistic regression boundary without rotating it.
Going further: formula, code, practice
The math
The model computes a score z = w·x + b and turns it into a probability with the sigmoid, p = 1 / (1 + e^(−z)). It is trained by minimising the log loss L = −mean( y·ln p + (1 − y)·ln(1 − p) ), whose gradient is simply mean((p − y)·x) for each weight.
- The prediction is class 1 when
p ≥ t. Because the sigmoid is increasing, that is the same asz ≥ ln(t / (1 − t)). - For
t = 0.5the right side is 0, so the boundary is the linew·x + b = 0. Fort = 0.3it is−0.85: the same direction, shifted towards class 0. wsets the direction of the boundary.tonly slides it.- A confident wrong answer costs a lot under log loss, since
−ln pgrows without limit aspgoes to 0.
In code (Python)
The lab's model: Adelie against Chinstrap by bill length and bill depth, standardised, scored on the same penguins at four thresholds:
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
df = pd.read_csv("data/raw/penguins.csv")
df = df[df["species"].isin(["Adelie", "Chinstrap"])].dropna(subset=["bill_length_mm", "bill_depth_mm"])
X, y = df[["bill_length_mm", "bill_depth_mm"]], df["species"] == "Chinstrap"
model = make_pipeline(StandardScaler(), LogisticRegression()).fit(X, y)
p = model.predict_proba(X)[:, 1] # probability of Chinstrap
for t in [0.1, 0.3, 0.5, 0.9]:
wrong = int(((p >= t) != y).sum()) # call Chinstrap when p >= t
print(f"threshold {t}: {wrong} mistakes, accuracy {1 - wrong / len(y):.1%}")
Output
threshold 0.1: 21 mistakes, accuracy 90.4%
threshold 0.3: 3 mistakes, accuracy 98.6%
threshold 0.5: 7 mistakes, accuracy 96.8%
threshold 0.9: 17 mistakes, accuracy 92.2%
The notebook linked under the output fetches the data itself. The best threshold here is 0.3, not the default 0.5.
Download the notebook (.ipynb). Open it in Jupyter or upload it to Google Colab; it fetches any missing data itself.
For practitioners
predict()always uses 0.5. To use another threshold, takepredict_probaand compare it yourself, as above, or wrap the model inFixedThresholdClassifier(a fixed threshold) orTunedThresholdClassifierCV(a threshold chosen by cross-validation), both in scikit-learn 1.5 or newer.- Choose the threshold on validation data, not on the rows you report. The 98.6% here is measured on the same penguins the model was fitted on, so it is optimistic.
- Standardise the features.
LogisticRegressionapplies L2 regularisation by default (C=1.0), and that penalty depends on the scale of each feature. - Compare accuracy with the majority-class baseline, and when the classes are unbalanced or the costs differ, look at the two kinds of mistake separately.
- A probability is only as good as the data it was fitted on. For an animal from a different population, a confident answer can still be wrong.
Was this helpful?
Thanks! This helps us improve the Atlas.
Go deeper in the Atlas
Encyclopedia entries on the ideas in this lesson: