k-Nearest Neighbors
Learning by remembering — and the ancestor of vector search
kNN has no training step and no parameters, which makes it the clearest model of what "similar inputs have similar outputs" means — and the clearest demonstration of why raw high-dimensional data breaks that assumption. It is also, almost literally, the retrieval step of a RAG system (9.1 Why RAG, and the canonical pipeline, 9.3 Vector search and indexes): find the nearest stored vectors to a query. Understand kNN and you understand what vector databases do and why they need approximate indexes.
You'll be able to
- Implement kNN classification and regression, including distance weighting, from scratch
- Choose a distance metric and explain why feature scaling is mandatory
- Explain how k trades bias against variance and select it with cross-validation
- Derive three quantitative consequences of the curse of dimensionality and state why learned embeddings escape it
- Describe the cost of brute-force search and how KD-trees and approximate indexes (HNSW) change it
- Connect kNN to retrieval, few-shot classification on embeddings and anomaly detection
Key ideas
- kNN stores the data and predicts by majority vote (or mean) over the k nearest points; the model is the data plus a distance.
- Features must be scaled with training statistics before computing distances, or the largest-scale feature decides everything.
- Small k → low bias, high variance (jagged boundary); large k → smooth, tends to the majority class; pick k by cross-validation, odd for binary.
Show 5 more key ideas
- Curse of dimensionality: a 1% neighbourhood spans 95% of each axis at d = 100; relative distance spread shrinks like 1/√d; almost all volume is near the boundary.
- kNN works on learned embeddings because real data have low intrinsic dimension; representation learning makes the locality assumption true.
- Brute force is O(nd) per query; KD/ball trees help for d ≲ 20; HNSW and other approximate indexes power vector search at scale.
- kNN is the retrieval step of RAG, the engine of few-shot classification on embeddings, KNN imputation and distance-based anomaly detection.
- Lazy (instant train, slow predict) is the mirror image of parametric models (slow train, instant predict).
Suggested path through this lesson
The algorithm
kNN is lazy learning: training is storing the data. To predict for a query , compute its distance to every stored point, take the closest — the neighbourhood — and aggregate their labels:
The distance-weighted version gives nearer neighbours more say, with weights (or ), and predicts the weighted vote or weighted mean. Class probabilities are the vote fractions, which makes kNN a crude density estimator: it is asking "around here, which label is more common?" The model is the data plus a notion of "around here" — the distance.
Distances and scaling
| metric | formula | use when |
|---|---|---|
| Euclidean () | continuous features of comparable scale; the default | |
| Manhattan () | many small differences should not be dominated by one large one | |
| Minkowski () | the family containing both | |
| cosine distance | direction matters, length does not: text vectors, embeddings (1.1 Vectors, dot products and norms, 9.2 Embeddings deep dive) | |
| Hamming | number of differing coordinates | binary / categorical codes |
Scaling is not optional. Suppose patients are described by age (20–80 years) and income (20,000–200,000). Euclidean distance between and is : the thirty-year age gap contributes essentially nothing, and the "nearest" neighbours are chosen by income alone. Standardize each feature (zero mean, unit variance) or min–max scale it using training-set statistics before computing any distance. For one-hot categorical features, consider Hamming or Gower distance; for embeddings, normalize to unit length so Euclidean and cosine rankings coincide (1.1 Vectors, dot products and norms).
Choosing k
is the capacity knob of 3.1 What is learning? ERM, generalization and the ML workflow in reverse. With the training error is zero (every point is its own nearest neighbour), the decision boundary follows every noisy point, and the model has high variance. As grows the boundary smooths, outliers are outvoted, and eventually — at — every prediction is the majority class: high bias. The sweet spot depends on the data and is found by cross-validation (3.5 Evaluating models: metrics, validation and the bias–variance trade-off); is a common starting point, odd avoids ties in binary problems, and distance weighting makes the choice less sensitive. The interactive demo shows this directly: place two classes of points, slide and watch the painted decision regions go from jagged islands to smooth blobs.
Worked example
Training points : , , , , . Query . Squared Euclidean distances: , , , , .
- : nearest is (distance ) → red.
- : (1), then and tied at → votes red, red, blue → red, with probability .
- : three red, two blue → red, probability .
- Distance-weighted, : weights → red vs blue → red with higher confidence than the plain vote.
Move the query to and recompute: is now nearest, and flips to blue while still says red — the small- boundary is the one that moves.
The curse of dimensionality
kNN assumes neighbours are local — close in every feature. In high dimensions three facts conspire against that assumption.
1. Neighbourhoods are not local. Take points uniform in the unit cube . To capture a fraction of the points in a sub-cube around a query, its edge must be . For : , , . In 100 dimensions, a "neighbourhood" containing 1% of the data spans 95% of the range of every feature. Nearest neighbours are not near.
2. Distances concentrate. If coordinates are i.i.d. with variance , then is a sum of i.i.d. terms: its mean grows like and its standard deviation like , so the relative spread of distances shrinks like . The ratio from a query to the dataset tends to zero: everyone is roughly equally far away, and "nearest" becomes a statement about noise (1.1 Vectors, dot products and norms made the same point with cosines).
3. Everything is on the edge. The fraction of the unit cube's volume within of its boundary is ; for this is at and at . Almost every point is near the boundary, so predictions extrapolate rather than interpolate.
Yet kNN on 768-dimensional sentence embeddings works superbly (9.2 Embeddings deep dive). The resolution is that real data lie near a low-dimensional manifold — images of digits, sentences about cooking — and a good embedding maps that manifold to a space where Euclidean distance tracks semantic similarity. The curse applies to the ambient dimension of raw pixels or one-hot words, not to the intrinsic dimension of meaningful representations. This is the deepest reason representation learning (4.10 Autoencoders, embeddings and representation learning, 5.8 Self-supervised and contrastive learning) matters: it makes kNN's assumption true.
Cost, trees and approximate search
A brute-force query costs — compute distances in dimensions — which is the whole pairwise-distance trick of 2.2 NumPy and vectorized thinking in one row. For in the millions and thousands of queries per second that is too slow. KD-trees and ball trees partition space recursively and answer exact queries in roughly when ; above that the partitions stop pruning anything (distance concentration again) and they degrade to brute force. The modern answer is approximate nearest neighbour (ANN) search: locality-sensitive hashing, inverted-file indexes with product quantization, and graph-based HNSW, which navigates a hierarchy of small-world graphs greedily and finds the true nearest neighbour 95–99% of the time, 100–1000× faster than brute force. This is exactly what a vector database does (9.3 Vector search and indexes); scikit-learn's KNeighborsClassifier(algorithm="auto") picks a tree or brute force for you, and FAISS/HNSW libraries take over at scale.
Beyond classification
kNN regression (KNeighborsRegressor) averages neighbours' targets; KNNImputer fills missing values from similar rows (3.13 Feature engineering, data quality and data-centric ML); the distance to the -th neighbour is an anomaly score; user–user collaborative filtering recommends what your nearest users liked; and few-shot classification on top of a pretrained encoder is kNN in embedding space — label ten examples, embed everything, vote. Against logistic regression (3.3 Logistic regression and softmax classification), kNN wins when the boundary is complex and data are dense, loses when data are scarce, high-dimensional and raw, and is always slower at prediction time — the opposite trade-off of a parametric model, which is slow to train and instant to query.
Where this shows up later
- Distance on embeddings is retrieval: vector search, ANN indexes and RAG — 9.2 Embeddings deep dive, 9.3 Vector search and indexes, 9.5 Retrieval quality: hybrid search, reranking, query transforms and metrics.
- k-means uses the same distances to assign points to centroids — 3.11 Clustering: k-means, GMMs/EM, DBSCAN and hierarchical; KNNImputer and anomaly scores appear in 3.13 Feature engineering, data quality and data-centric ML.
- The curse of dimensionality motivates dimensionality reduction — 3.12 Dimensionality reduction: PCA, t-SNE and UMAP — and representation learning — 4.10 Autoencoders, embeddings and representation learning, 5.8 Self-supervised and contrastive learning.
- kNN's bias–variance behaviour in is the clean case for the decomposition in 3.5 Evaluating models: metrics, validation and the bias–variance trade-off.
Common pitfalls (5)
- Computing Euclidean distance on unscaled features, so one feature's units silently decide the neighbours.
- Using k = 1 because training accuracy is 100%; it is the highest-variance choice possible.
- Applying kNN to raw high-dimensional data (pixels, one-hot words) and concluding kNN 'doesn't work'.
- Fitting the scaler on all data before the split, leaking test statistics into the distance computation.
- Forgetting prediction cost: a brute-force kNN over millions of rows may be too slow to serve.
Recap: all 8 key points
- kNN stores the data and predicts by majority vote (or mean) over the k nearest points; the model is the data plus a distance.
- Features must be scaled with training statistics before computing distances, or the largest-scale feature decides everything.
- Small k → low bias, high variance (jagged boundary); large k → smooth, tends to the majority class; pick k by cross-validation, odd for binary.
- Curse of dimensionality: a 1% neighbourhood spans 95% of each axis at d = 100; relative distance spread shrinks like 1/√d; almost all volume is near the boundary.
- kNN works on learned embeddings because real data have low intrinsic dimension; representation learning makes the locality assumption true.
- Brute force is O(nd) per query; KD/ball trees help for d ≲ 20; HNSW and other approximate indexes power vector search at scale.
- kNN is the retrieval step of RAG, the engine of few-shot classification on embeddings, KNN imputation and distance-based anomaly detection.
- Lazy (instant train, slow predict) is the mirror image of parametric models (slow train, instant predict).
Watch
The algorithm in five minutes; watch before the worked example.
Read
Try it live
Interactive demo
runs in your browserExercises
- kNN from scratch
Implement
knn_predict(Xtrain, ytrain, Xquery, k, weighted=False)using the pairwise-distance trick from 2.2 NumPy and vectorized thinking. Verify on the worked example (query (3,2): red for k=1, 3, 5) and againstKNeighborsClassifieron the iris dataset. Expected: identical predictions. - The scaling disaster
Create a dataset with one informative feature in [0, 1] and one random feature in [0, 1000]. Fit kNN with and without
StandardScaler. Expected: accuracy near chance without scaling, high with it. - Curse of dimensionality, measured
For sample 2,000 uniform points and one query; compute and the fraction of points within 0.05 of the cube boundary. Expected: the ratio collapses toward 0 and the boundary fraction rises toward 1, matching .
- kNN on embeddings
Use
sentence-transformers(or any embedding API) to embed 200 short texts from two topics. Run 5-NN with cosine distance on 20 labelled examples per topic and classify the rest. Expected: high accuracy from 40 labels — few-shot classification is kNN in embedding space.
Quiz
Flashcards
These cards are now in your spaced-repetition queue. Review all due cards →