Nearest neighbours
To label a new example, find the most similar examples you already know and let them vote. Simple, strong, and very sensitive to scale.
In 60 seconds
Nearest neighbours
To label a new example, find the most similar examples you already know and let them vote. Simple, strong, and very sensitive to scale.
import numpy as np
# Made-up fruits: (weight in grams, sweetness 1-10) and their kind
points = np.array([[120, 7], [130, 8], [115, 6], [300, 3], [320, 2], [290, 4]])
kinds = np.array(["guava", "guava", "guava", "papaya", "papaya", "papaya"])
new = np.array([140, 6])
dist = np.sqrt(((points - new) ** 2).sum(axis=1)) # straight-line distance
order = np.argsort(dist)
k = 3
print("Distances:", dist.round(1))
print("The", k, "nearest:", kinds[order[:k]])
values, counts = np.unique(kinds[order[:k]], return_counts=True)
print("Vote:", values[np.argmax(counts)])Choosing k
| k | What happens |
|---|---|
| 1 | Copies the single closest example. Very sensitive to noise and odd examples. |
| Medium (for example 5 to 15) | Smooths out noise. Often a good range. |
| Very large | Ignores local detail and drifts toward the most common label overall. |
The big trap: scale
StandardScaler in a pipeline. Without scaling, the model may quietly ignore most of your features. In this lesson's lab you will see how big the difference can be.Where k-NN fits
- Slow to predict when there are very many examples, since it compares with all of them
- Struggles when there are very many features
- Needs scaling and a sensible distance
- Very simple to explain: "these similar cases had this label"
- No training time
- Adding new examples is instant
points / [100, 1] and new / [100, 1]). Do the nearest neighbours change?Watch and read more
Lab
The same 5-nearest-neighbour model on the wine data, with and without scaling, and the gap between them.
The problem
- Run the starter. It fits k-NN with k = 5 on the raw wine features and prints the test accuracy.
- Build
scaled_model: a pipeline ofStandardScalerthenKNeighborsClassifier(n_neighbors=5). Fit it on the training rows. - Set
scaled_accto its test accuracy. - Print both accuracies. Then look at
X_train.max(axis=0): which feature has by far the largest values, and why does that hurt the unscaled model?
Practice lab
Edit the code and run it. Python runs in your browser — nothing is sent to our server.
No output. Add print(...) to see values.
You are done when
Hard questions
Try to answer before you reveal. If you can answer these, you understood the lesson.
Q1Why must the scaler be fitted on the training rows only, and how does the pipeline make sure of that?Reveal
The scaler learns each feature's average and spread. If it saw the test rows, some test information would shape the training, and the test score would be a bit too kind. A pipeline's fit only sees the data you pass it (the training rows) and then reuses those learned numbers when you call score or predict on new rows.
Q2Is scaling always the right fix? When might it hurt?Reveal
Scaling gives every feature an equal say. If some features are pure noise, giving them an equal say can hurt, because they now affect the distance as much as useful ones. Then you may need to drop noisy features, or use a model that picks features itself, such as a forest.
Questions people ask
What distance does scikit-learn use?
By default, the ordinary straight-line (Euclidean) distance. Other distances are available through the metric setting.
What if the vote is a tie?
Using an odd k helps for two groups. scikit-learn has a fixed rule for breaking ties, and you can also weight closer neighbours more with weights="distance".
Is k-NN used in real products?
The idea is everywhere: "customers similar to you also bought", and vector search in AI apps. Large systems use fast approximate search instead of comparing with every example.
Can k-NN do regression?
Yes. KNeighborsRegressor predicts the average label of the k nearest examples.
Lesson test
5 questions. Get 3 right (60%) to pass and complete this lesson.