CadetX
CX Learn | Complete Machine Learning Guide
Scikit-Learn · Python
CadetX logo CadetX CX Learn
ML-101 · Module 6 Beginner about 30 minutes 10 Lessons Prereq: Modules 1 to 5

K-Nearest Neighbours (KNN)

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:

  1. finds the k most similar data points it already knows (its "nearest neighbours"), then
  2. 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

A new user, marked with a question mark, surrounded by existing users. The five nearest are circled: three Premium and two Basic, so the new user is predicted to be Premium.?k = 5 nearest neighbours● Basic plan● Premium planVote: 3 Premium vs 2 Basic
Figure 1. A new user (?) joins. KNN measures the distance to every existing user, picks the 5 closest, and counts their votes. 3 of the 5 chose Premium, so the prediction is Premium.
StepWhat happens
1. Choose kDecide how many neighbours to ask, for example k = 5
2. Measure distancesWork out how far the new point is from every point in the training data
3. Find the nearestSort by distance and keep the k closest
4. VoteFor 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.

Point A at 1,1 and point B at 4,5. The straight-line Euclidean distance is 5. The Manhattan distance, moving only along grid lines, is 3 plus 4, which is 7.012345601234563 across4 upABEuclidean (straight line)√(3² + 4²) = √25 = 5Manhattan (city blocks)3 + 4 = 7A = (1, 1) B = (4, 5)
Figure 2. Two ways to measure the distance from A to B. The Euclidean distance is the straight line "as the crow flies". The Manhattan distance moves only along the grid, like walking around city blocks.
Euclidean distanceManhattan distance
IdeaStraight line between two pointsSum of the steps along each direction
Formula (2 features)√((x₂ − x₁)² + (y₂ − y₁)²)|x₂ − x₁| + |y₂ − y₁|
You know it asPythagoras' theorem from schoolWalking around a grid of streets
Default in scikit-learn?YesSet 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

Premium: Basic:

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:

Decision regions for k equals 1 and k equals 15. With k equals 1 the boundary is jagged with small islands around single points. With k equals 15 the boundary is smooth.k = 1: jagged, overfitsk = 15: smoothFollows every single pointCaptures the general pattern
Figure 3. The coloured areas show what KNN would predict for a new user anywhere on the chart. With k = 1 the boundary is jagged, bending around single unusual points (like the amber user deep in the blue area). That's overfitting. With k = 15 the boundary is smooth and follows the general pattern.
Small k (e.g. 1)Large k (e.g. 50)
BehaviourListens to just one or two neighboursListens to a huge crowd
BoundaryJagged, follows every pointVery smooth, may miss real details
RiskOverfitting: fooled by noise and odd pointsUnderfitting: 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:

CustomerAgeYearly income
A25£30,000
B60£31,000
C26£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 BDistance A to CNearest to A
Raw values√(35² + 1,000²) ≈ 1,001√(1² + 15,000²) ≈ 15,000B (wrong!)
After min-max scaling≈ 0.67≈ 0.25C (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 houseSizeBedroomsSold for
Neighbour 190 m²3£200,000
Neighbour 2100 m²3£228,000
Neighbour 395 m²3£210,000
PredictionAverage 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

StrengthsWeaknesses
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 instantlyMust scale features, or results can be badly wrong
Flexible boundaries: can follow curvy patterns that logistic regression can'tStruggles with many features (see below)
Works for classification and regressionSensitive to unbalanced classes: a very common class can outvote a rare one
Makes no assumptions about the shape of the dataNeeds 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.

wine_knn.py
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])
Output
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

UseHow KNN helps
Recommendations"Customers similar to you also bought…" finds your nearest neighbours by shopping or viewing history
Property valuationValues a house from the most similar recent sales ("comparables")
Fraud and anomaly detectionA transaction with no close neighbours is unusual and worth checking
Filling missing valuesKNNImputer fills a gap using the values of the most similar rows, a smarter option than the median from Module 2
Image recognitionClassic example: recognising handwritten digits by comparing them to known examples
HealthcareFinding 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

  1. 01
    Introduction to Machine LearningWhat ML is and how it works
  2. 02
    Preparing Data for Machine LearningFeatures, encoding, scaling, train/test split
  3. 03
    Linear RegressionPredicting numbers
  4. 04
    Logistic RegressionPredicting yes or no
  5. 05
    Evaluating ModelsAccuracy, precision, recall, overfitting, cross-validation
  6. 06
    K-Nearest NeighboursYou are here
  7. 07
    Decision TreesFlowcharts that learn
  8. 08
    Random Forest and Gradient BoostingMany models working together
  9. 09
    Support Vector MachinesFinding the best boundary
  10. 10
    Naive BayesProbability-based classification
  11. 11
    Clustering with K-MeansFinding groups without labels
  12. 12
    Dimensionality Reduction with PCASimplifying big datasets
  13. 13
    Capstone ProjectBuild and present a full ML project