K-Nearest Neighbours (KNN) makes predictions the same way people often do: by looking at similar examples. To decide something about a new data point, it finds the most similar points it has already seen and follows the crowd.
- Level: Beginner
- Time: about 30 minutes
- Needs: Modules 1 to 5
By the end of this module you will be able to
- Explain how KNN makes a prediction, step by step
- Calculate Euclidean and Manhattan distance
- Explain how the choice of k affects overfitting and underfitting
- Explain why KNN needs scaled features
- Use KNN for both classification and regression
- Know KNN's strengths and weaknesses
- Tune k with cross-validation using GridSearchCV in scikit-learn
6.1What is K-Nearest Neighbours?
Imagine you move to a new area and want to guess which football team your new neighbour supports. You don't know them yet, but you know the five houses closest to theirs: four support Newcastle and one supports Sunderland. A sensible guess? Newcastle.
That's KNN. To predict something about a new data point, it:
- finds the k most similar data points it already knows (its "nearest neighbours"), then
- lets them vote on the answer.
KNN in one sentence
KNN predicts the answer for a new data point by finding the k most similar examples in the training data and going with the majority.
In this module we'll help a UK streaming service. It offers a Basic and a Premium plan, and wants to predict which plan a new user will choose, based on their age and how many hours they watch per week.
KNN is a "lazy" learner
Most algorithms do their hard work during training: linear regression calculates its line, logistic regression its S-curve. KNN does almost nothing at training time. It simply memorises all the data. All the work happens later, when you ask it to predict. That's why it's called a lazy learner.
6.2How KNN works, step by step
| Step | What happens |
|---|---|
| 1. Choose k | Decide how many neighbours to ask, for example k = 5 |
| 2. Measure distances | Work out how far the new point is from every point in the training data |
| 3. Find the nearest | Sort by distance and keep the k closest |
| 4. Vote | For classification, pick the most common answer. For regression, take the average |
KNN can also give a probability, just like logistic regression: here, 3 out of 5 votes means a 60% chance of Premium.
6.3Measuring distance
"Nearest" means the smallest distance. But how do we measure distance between two data points? There are two common ways.
| Euclidean distance | Manhattan distance | |
|---|---|---|
| Idea | Straight line between two points | Sum of the steps along each direction |
| Formula (2 features) | √((x₂ − x₁)² + (y₂ − y₁)²) | |x₂ − x₁| + |y₂ − y₁| |
| You know it as | Pythagoras' theorem from school | Walking around a grid of streets |
| Default in scikit-learn? | Yes | Set metric="manhattan" |
With more than two features, the idea is exactly the same. Euclidean distance just adds more squared differences under the square root: one for every feature. The computer handles this easily, even with hundreds of features.
6.4Choosing k
The number of neighbours, k, is a hyperparameter (you met these in Module 5): you choose it before making predictions. It has a big effect on the results. Try it yourself.
Try it: click anywhere to add a new user
Small k vs large k
Try clicking near a blue point that sits among amber ones, then switch between k = 1 and k = 15. With k = 1, the prediction follows that single odd point. With k = 15, the crowd outvotes it. You can see the same effect across the whole chart:
| Small k (e.g. 1) | Large k (e.g. 50) | |
|---|---|---|
| Behaviour | Listens to just one or two neighbours | Listens to a huge crowd |
| Boundary | Jagged, follows every point | Very smooth, may miss real details |
| Risk | Overfitting: fooled by noise and odd points | Underfitting: everything drifts towards the most common class |
Tips for choosing k
Start with a value around 5. For two classes, use an odd number so a vote can never be a tie. Then do it properly: try several values with cross-validation (Module 5) and pick the one with the best average score. You'll do exactly this in Python in lesson 6.8.
6.5Why KNN needs scaled features
In Module 2 you learned that some algorithms need scaled features. KNN is the most important example, because everything depends on distance. Look at three customers:
| Customer | Age | Yearly income |
|---|---|---|
| A | 25 | £30,000 |
| B | 60 | £31,000 |
| C | 26 | £45,000 |
Who is more similar to A? Most people would say C: almost the same age. Now look at what the raw distances say:
| Distance A to B | Distance A to C | Nearest to A | |
|---|---|---|---|
| Raw values | √(35² + 1,000²) ≈ 1,001 | √(1² + 15,000²) ≈ 15,000 | B (wrong!) |
| After min-max scaling | ≈ 0.67 | ≈ 0.25 | C (correct) |
Without scaling, a £1,000 difference in income completely drowns out a 35-year age gap, simply because income numbers are bigger. After scaling (age range 18 to 70, income range £20k to £80k), both features get a fair say, and KNN finds the right neighbour.
Always scale before KNN
In the Python example later, the same KNN model scores 78% without scaling and 93% with scaling on the same data. That one step makes a huge difference.
6.6KNN for regression
KNN can predict numbers too. Instead of a vote, it takes the average of the neighbours' values.
Back to the Newcastle estate agent from Module 3. A new 95 m², 3-bedroom house comes on the market. KNN with k = 3 finds the three most similar houses already sold:
| Similar house | Size | Bedrooms | Sold for |
|---|---|---|---|
| Neighbour 1 | 90 m² | 3 | £200,000 |
| Neighbour 2 | 100 m² | 3 | £228,000 |
| Neighbour 3 | 95 m² | 3 | £210,000 |
| Prediction | Average of the three | £212,667 | |
This is exactly how estate agents value a house in real life: they look at "comparables", similar houses that sold nearby. In scikit-learn, use KNeighborsRegressor instead of KNeighborsClassifier.
Weighted KNN: closer neighbours count more
In normal KNN, every neighbour gets an equal vote, even if one is very close and another is much further away. With distance weighting, closer neighbours get a bigger say. In scikit-learn, set weights="distance". It's worth trying both options when you tune your model.
6.7Strengths and weaknesses
| Strengths | Weaknesses |
|---|---|
| Very simple to understand and explain ("these 5 similar customers chose Premium") | Slow predictions on big datasets: it must measure the distance to every training point, every time |
| No training time: new data can be added instantly | Must scale features, or results can be badly wrong |
| Flexible boundaries: can follow curvy patterns that logistic regression can't | Struggles with many features (see below) |
| Works for classification and regression | Sensitive to unbalanced classes: a very common class can outvote a rare one |
| Makes no assumptions about the shape of the data | Needs lots of memory: it stores the whole training set |
The curse of dimensionality
With lots of features (say, 500), something strange happens: all points start to look roughly the same distance from each other. If everyone is "far away", the idea of a "nearest" neighbour stops meaning much. This is called the curse of dimensionality.
An everyday example
Finding someone similar to you by age alone is easy. Finding someone with the same age, height, job, hometown, hobbies, music taste and 494 other things is almost impossible. Everyone ends up "not very similar". The fix is to keep only useful features, or reduce them with PCA (Module 12).
6.8KNN in Python
We'll use another real dataset built into scikit-learn: 178 Italian wines, each with 13 chemical measurements (such as alcohol and colour intensity), from three different grape types. Can KNN tell which grape a wine was made from?
We'll also use GridSearchCV. It automatically tries every combination of settings you give it, scores each one with cross-validation, and keeps the best. This is the proper way to choose k.
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
# 1. Load a real dataset: 178 wines, 13 chemical measurements, 3 grape types
X, y = load_wine(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.25, random_state=42, stratify=y)
# 2. KNN WITHOUT scaling
raw = KNeighborsClassifier(n_neighbors=5)
raw.fit(X_train, y_train)
print("Accuracy without scaling:", round(raw.score(X_test, y_test), 3))
# 3. KNN WITH scaling (inside a Pipeline)
knn = Pipeline([
("scale", StandardScaler()),
("knn", KNeighborsClassifier(n_neighbors=5)),
])
knn.fit(X_train, y_train)
print("Accuracy with scaling: ", round(knn.score(X_test, y_test), 3))
# 4. Find the best k with 5-fold cross-validation
grid = GridSearchCV(
knn,
param_grid={"knn__n_neighbors": [1, 3, 5, 7, 9, 11, 15, 21],
"knn__weights": ["uniform", "distance"]},
cv=5, scoring="accuracy")
grid.fit(X_train, y_train)
print("Best settings:", grid.best_params_)
print("Best cross-validation accuracy:", round(grid.best_score_, 3))
print("Final test accuracy:", round(grid.score(X_test, y_test), 3))
# 5. Predict a new wine and look at its neighbours
new_wine = X_test[:1]
print("Predicted grape type:", grid.predict(new_wine)[0])
print("Vote shares:", grid.predict_proba(new_wine).round(2)[0])
Accuracy without scaling: 0.778
Accuracy with scaling: 0.933
Best settings: {'knn__n_neighbors': 15, 'knn__weights': 'uniform'}
Best cross-validation accuracy: 0.977
Final test accuracy: 1.0
Predicted grape type: 0
Vote shares: [0.93 0.07 0. ]What the output tells us
- Scaling is essential. Accuracy jumps from 77.8% to 93.3% just by scaling. Some wine measurements (like "proline") are in the hundreds, while others are below 1, so without scaling they completely dominate the distances.
- GridSearchCV tried 16 combinations (8 values of k × 2 weighting options) and found k = 15 with equal votes worked best, with 97.7% average cross-validation accuracy.
- The final test accuracy is 100%. That's excellent, but remember the test set only has 45 wines, so one or two mistakes would change it a lot. The cross-validation score (97.7%) is the more reliable estimate.
- Vote shares show that 93% of the 15 neighbours (14 of them) were grape type 0, so the model is very confident about this wine.
Reading the GridSearchCV names
When a model is inside a Pipeline, settings are named stepname__setting with two underscores. So knn__n_neighbors means "the n_neighbors setting of the step called knn".
6.9KNN in the real world
| Use | How KNN helps |
|---|---|
| Recommendations | "Customers similar to you also bought…" finds your nearest neighbours by shopping or viewing history |
| Property valuation | Values a house from the most similar recent sales ("comparables") |
| Fraud and anomaly detection | A transaction with no close neighbours is unusual and worth checking |
| Filling missing values | KNNImputer fills a gap using the values of the most similar rows, a smarter option than the median from Module 2 |
| Image recognition | Classic example: recognising handwritten digits by comparing them to known examples |
| Healthcare | Finding past patients with the most similar symptoms and test results |
KNN is rarely the most accurate model on large, complex datasets, but it's an excellent baseline, and its "similar examples" approach is easy for anyone in a business to understand and trust.
SummaryKey takeaways
- KNN predicts by finding the k most similar training examples and letting them vote (or averaging them, for regression).
- It's a lazy learner: no real training, all the work happens at prediction time.
- Similarity is measured with distance: Euclidean (straight line) or Manhattan (grid steps).
- Small k overfits (jagged boundary); large k underfits (too smooth). Choose k with cross-validation.
- Use an odd k for two classes to avoid ties.
- Always scale your features, or large-number features will dominate the distances.
- Distance weighting gives closer neighbours a bigger say.
- KNN is slow on big data and struggles with many features (the curse of dimensionality).
Check your understanding
Your machine learning roadmap
- 01Introduction to Machine LearningWhat ML is and how it works
- 02Preparing Data for Machine LearningFeatures, encoding, scaling, train/test split
- 03Linear RegressionPredicting numbers
- 04Logistic RegressionPredicting yes or no
- 05Evaluating ModelsAccuracy, precision, recall, overfitting, cross-validation
- 06K-Nearest NeighboursYou are here
- 07Decision TreesFlowcharts that learn
- 08Random Forest and Gradient BoostingMany models working together
- 09Support Vector MachinesFinding the best boundary
- 10Naive BayesProbability-based classification
- 11Clustering with K-MeansFinding groups without labels
- 12Dimensionality Reduction with PCASimplifying big datasets
- 13Capstone ProjectBuild and present a full ML project
Next module
Decision Trees