Skip to content

K-Nearest Neighbors (KNN)

Instance-based learning - distance metrics, k selection, curse of dimensionality


Overview

KNN predicts by finding the k training points closest to the query point and aggregating their labels (majority vote for classification, mean for regression).

Algorithm Steps

  1. Store all training data (lazy learning - no training phase)
  2. Compute distance to all training points for new query
  3. Find k nearest neighbors
  4. Aggregate: majority vote (classification) or mean (regression)

How K Affects Predictions

Effect of k on KNN predictions

k ValueBehaviorTrade-off
k=1Highly flexible, captures noiseHigh variance, overfitting
k smallComplex decision boundaryMay overfit
k largeSmooth decision boundaryMay underfit
k=nAlways predicts majority classNo learning

Decision Boundaries

KNN Decision Boundaries for Different k Values

  • Small k: Jagged boundaries, sensitive to individual points
  • Large k: Smoother boundaries, more robust to noise
  • Optimal k: Found via cross-validation

Distance Metrics

Comparison of Euclidean vs Manhattan Distance

Common Metrics

MetricFormulaBest For
Euclidean (L2)d(x,y)=i=1n(xiyi)2Continuous features (default)
Manhattan (L1)d(x,y)=i=1n|xiyi|High-dimensional, robust to outliers
Cosined(x,y)=1xy|x||y|Text/documents, sparse vectors
Minkowskid(x,y)=(i=1n|xiyi|p)1/pGeneralized (p=1: Manhattan, p=2: Euclidean)

Important: Always normalize/scale features before using Euclidean distance!


Choosing K

Selection Methods

MethodDescription
Cross-validationMost reliable - test multiple k values
Rule of thumbk=n as starting point
Odd k for binaryAvoids ties in voting

Weighted KNN

Weight neighbors by inverse distance to reduce sensitivity to k choice:

wi=1di
python
# Weighted KNN in sklearn
knn = KNeighborsClassifier(n_neighbors=5, weights='distance')

Curse of Dimensionality

The Problem

In high dimensions (d>20):

  • All points become approximately equidistant
  • "Nearest" neighbor isn't meaningfully closer
  • Volume concentrates at hypercube edges

Volume Example

For a unit hypercube with inner cube of side 0.9:

DimensionsInner Volume
d=190%
d=1035%
d=100~0%

Solutions

  • Dimensionality reduction: PCA, t-SNE before KNN
  • Feature selection: Remove irrelevant features
  • Manhattan distance: More robust in high-d
  • Approximate NN: LSH, Annoy, Faiss

Complexity

OperationBrute ForceWith KD-tree
TrainingO(1)O(nlogn)
PredictionO(nd)O(dlogn) avg
SpaceO(nd)O(nd)

Speed Optimizations

MethodWhen to Use
KD-Treed<20, exact NN
Ball TreeHigher dimensions than KD-tree
LSHApproximate NN, very large datasets
Annoy/FaissProduction systems, millions of points

Strengths vs Weaknesses

StrengthsWeaknesses
Simple, no training phaseSlow prediction O(nd)
No distribution assumptionsMemory intensive
Naturally handles multi-classCurse of dimensionality
Easy to add new dataSensitive to feature scale
Adapts locallyAll features affect distance

Code Reference

python
import numpy as np
from sklearn.neighbors import KNeighborsClassifier
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import cross_val_score

# ALWAYS scale features for KNN
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

# Basic KNN
knn = KNeighborsClassifier(n_neighbors=5, metric='euclidean')
knn.fit(X_train_scaled, y_train)

# Weighted KNN (recommended)
knn_weighted = KNeighborsClassifier(
    n_neighbors=5,
    weights='distance',
    metric='euclidean'
)

# Find optimal k via cross-validation
k_range = range(1, 31)
cv_scores = [
    cross_val_score(
        KNeighborsClassifier(n_neighbors=k),
        X_train_scaled, y_train, cv=5
    ).mean()
    for k in k_range
]
best_k = k_range[np.argmax(cv_scores)]

# Fast queries with KD-tree
knn_fast = KNeighborsClassifier(
    n_neighbors=5,
    algorithm='kd_tree',  # 'ball_tree', 'auto'
    leaf_size=30
)

# Get neighbors for interpretability
distances, indices = knn.kneighbors(X_test_scaled[:1], n_neighbors=5)

Interview Questions

Q1: How do you choose k?

Use cross-validation to find optimal k. Start with k=n, use odd k for binary classification. Consider weighted KNN to reduce sensitivity to k choice.

Q2: What's the curse of dimensionality?

In high dimensions, all points become equidistant, making "nearest" meaningless. Solutions: reduce dimensions (PCA), select features, use Manhattan distance, or approximate NN methods.

Q3: KNN vs model-based approaches?

Use KNN: low dimensions (d<20), complex boundaries, online learning, interpretability needed. Use model-based: high dimensions, fast prediction required, parametric assumptions hold, limited memory.

Q4: How to speed up KNN?

  1. KD-tree/Ball-tree for low-d exact NN
  2. LSH/Annoy/Faiss for approximate NN at scale
  3. Prototype selection to reduce dataset
  4. Dimensionality reduction (PCA)

Quick Reference Card

K-NEAREST NEIGHBORS
---------------------------------------------
Algorithm: Store data, find k nearest at prediction
Classify:  Majority vote among k neighbors
Regress:   Mean of k neighbors' values

DISTANCE METRICS
---------------------------------------------
Euclidean: sqrt(sum((xi-yi)^2))  - default
Manhattan: sum(|xi-yi|)          - robust, high-d
Cosine:    1 - cos(theta)        - text, sparse

CHOOSING K
---------------------------------------------
Small k: Complex boundary, may overfit
Large k: Smooth boundary, may underfit
Method:  Cross-validation (best), sqrt(n) (rule)

COMPLEXITY
---------------------------------------------
Training:   O(1)
Prediction: O(n*d), or O(d log n) with KD-tree
Space:      O(n*d)

CURSE OF DIMENSIONALITY
---------------------------------------------
Problem: In high-d, all points equidistant
Fix:     Reduce dimensions, feature selection

USE WHEN
---------------------------------------------
+ Low-dimensional data (d < 20)
+ Complex/irregular boundaries
+ Online learning / easy updates
- High-dimensional data
- Fast prediction needed
- Limited memory