MACHINE LEARNING

Efficient Nearest Neighbour Search: KD-Tree and Ball Tree

Brute-force KNN is O(nd) per query. KD-Trees partition space along axes; Ball Trees partition into hyperspheres. Both reduce average query time to O(log n) — the right choice depends on dimensionality.

1The Nearest Neighbour Search Problem

K-Nearest Neighbours is conceptually simple: for a query point, find the k training points with smallest distance. The naive implementation scans every training point — O(nd) per query where n is dataset size and d is dimensionality. At a million points and 100 dimensions, that is 100 million distance computations per prediction. Specialised data structures reduce this to O(log n) on average.

Brute force cost

  • ✗ O(nd) per query — scans every point
  • ✗ 1M points × 100 dims = 100M ops per prediction
  • ✗ Scales poorly as dataset grows

Tree-based approaches

  • ✓ O(log n) average query time
  • ✓ Pre-compute spatial structure once
  • ✓ Skip entire subtrees via triangle inequality

2KD-Tree: Axis-Aligned Space Partitioning

A KD-Tree (k-dimensional tree) is a binary tree where each node splits the data along one axis using the median value. At depth 0 it splits on axis 0 (x), at depth 1 on axis 1 (y), cycling through all dimensions. This creates a recursive partitioning of space by axis-aligned hyperplanes. Construction is O(n log n); a single approximate nearest neighbour query is O(log n).

Search algorithm: traverse the tree like a BST to reach a leaf. Store it as the current best. Unwind upward: at each node, check if the other subtree could contain a closer point by testing whether the query circle crosses the splitting plane. If it does, explore that subtree too. This backtracking is what guarantees correctness despite the greedy descent.

Construction
Sort points by the current axis, pick the median as root, recurse on left and right halves alternating axes. Result: a balanced binary tree.
Best for
Low to moderate dimensionality (d < 20). In low dimensions, most of the tree is pruned during search — very fast in practice.
Curse of dimensionality
In high dimensions (d > 20), nearly every subtree must be explored — the tree degenerates toward brute force. Use Ball Tree instead.

3Ball Tree: Hypersphere Partitioning

A Ball Tree partitions data into nested hyperspheres (balls) rather than axis-aligned boxes. Each node stores a centroid (pivot) and a radius — the distance from the pivot to the farthest point in the node. Construction: pick two far-apart points, project all data onto their connecting vector, split at the median, recurse. Ball Trees handle high-dimensional data and data on low-dimensional manifolds much better than KD-Trees.

Triangle inequality pruning: for query q and ball with centroid c and radius r, the minimum possible distance from q to any point inside the ball is max(0, dist(q,c) - r). If this minimum already exceeds the current best distance, the entire ball is skipped. This is more effective in high dimensions where axis-aligned splits fail.

Ball Tree advantages

  • ✓ Works on low-dimensional manifolds in high-D space
  • ✓ Effective triangle inequality pruning in high dimensions
  • ✓ Handles non-axis-aligned cluster structure

Ball Tree limitations

  • ✗ Slower construction than KD-Tree
  • ✗ Sensitive to outliers (outlier stretches the ball radius)
  • ✗ Partitions may be imbalanced

4When to Use Which

Use KD-Tree
d < 20, data is axis-aligned, you want fast construction. Typical for tabular datasets with few numeric features.
Use Ball Tree
d > 20, data lies on a manifold, or KD-Tree queries are slow. Typical for image embeddings or NLP feature spaces.
Use Brute Force
Very small datasets (n < 1000) or very high d where both trees degenerate. sklearn auto-selects based on n and d.

Related

Build a 2D KD-Tree from scratch and query nearest neighbour

Recall check

0 of …

Say the answer out loud before revealing — recalling is what makes it stick. ➜ Next: BIRCH Algorithm

  1. Why is brute-force KNN O(nd) per query?

  2. How does a KD-Tree decide which subtree to prune during search?

  3. Why does the KD-Tree degrade in high dimensions?

  4. What is the key advantage of a Ball Tree over a KD-Tree?