Skip to content
Kudos AI

The Bayes Classifier and Nearest Neighbours

The rule that minimises test error, the floor it leaves behind, and the nonparametric method that imitates it by counting neighbours - with the number of neighbours turning out to be the flexibility dial in disguise.

IntermediateModule 125 min · 100 XP
Two Gaussian densities crossing at the Bayes boundary with the overlap shaded as the error floor, the boundary sliding as the priors change, and a KNN decision boundary going from jagged to flat as k rises past its best value.

Logistic regression gave one way to draw a boundary. Before comparing it with others, it is worth knowing what the best possible boundary looks like - because there is one, it is unbeatable, and every method in this path is a different attempt to guess at it.

The classifier that cannot be beaten

Suppose you knew, for every point xx, the true conditional probability of each class, P(Y=j∣X=x)P(Y = j \mid X = x). The Bayes classifier assigns xx to whichever class has the largest one.

That rule minimises the error rate, and the argument is almost too short to count as a proof. At each individual xx the probability of being wrong is 1−max⁡jP(Y=j∣X=x)1 - \max_j P(Y = j \mid X = x), and no other rule can make that smaller at that point. A rule that is optimal at every point is optimal on average. The resulting error,

1−E[max⁡jP(Y=j∣X)],1 - E\left[\max_j P(Y = j \mid X)\right],

is the Bayes error rate: the classification analogue of irreducible error. It is not zero, because the classes genuinely overlap in the population.

Notice what the rule requires. It needs P(Y∣X)P(Y \mid X) - precisely the quantity every real method is trying to estimate. The Bayes classifier is therefore a benchmark you can only evaluate in a simulation where you built the data yourself. That is not a reason to ignore it; it is the reason simulations are worth running.

Working it out on the line

Take two classes on the real line. Class 1 is N(−1.25,1)N(-1.25, 1), class 2 is N(1.25,1)N(1.25, 1), and they are equally likely. Where is the boundary?

The posteriors are equal where π1f1(x)=π2f2(x)\pi_1 f_1(x) = \pi_2 f_2(x). With equal priors and equal variances the densities are mirror images, so the boundary is the midpoint, x=0x = 0. Everything left of zero is called class 1.

The error rate follows immediately. A class 2 observation is misclassified when it falls below zero, which happens with probability Φ(−1.25)=0.105650\Phi(-1.25) = 0.105650, and by symmetry the same holds for class 1. So the Bayes error rate is

0.105650.0.105650 .

About one prediction in ten is wrong, and no method, however sophisticated, will do better on this problem. Integrating the mixture numerically over four million points on the line returns the same value to six decimal places.

Interactive: the boundary nothing can beat

The shaded overlap is the error floor.

class 0class 1x*
Bayes error (the floor)
0.105650
Boundary x*
0.000000
Cost of using the midpoint
0.000000

With equal priors the boundary sits at the midpoint and the floor is the overlap of the two curves. Nothing can get under it: the classes genuinely occupy the same ground. Now drag the prior. Widen σ and the floor rises, because the floor is overlap and nothing else.

What the priors do

Now make class 1 more common, with π1=0.7\pi_1 = 0.7. The boundary solves π1f1(x)=π2f2(x)\pi_1 f_1(x) = \pi_2 f_2(x), and taking logs gives

x=σ2log⁡(π1/π2)+(μ22−μ12)/2μ2−μ1=+0.338919.x = \frac{\sigma^2 \log(\pi_1/\pi_2) + (\mu_2^2 - \mu_1^2)/2}{\mu_2 - \mu_1} = +0.338919 .

The boundary moved toward the rarer class, enlarging class 1's region. That is the right direction, and it is worth pausing on because the opposite is a natural guess: since class 1 is more common, shouldn't its region shrink to avoid swamping class 2? No - a point near zero is now more likely to have come from class 1 simply because there are more class 1 points to come from, and the optimal rule follows the posterior, not the density.

The payoff is measurable. At the shifted boundary the error rate is 0.0935650.093565; keeping the boundary at zero and ignoring the prior gives 0.1056500.105650, so the mistake costs 0.0120840.012084. At π1=0.9\pi_1 = 0.9 the boundary reaches +0.878890+0.878890 and the error falls to 0.0504960.050496, while the boundary at zero still gives 0.1056500.105650 - by then, ignoring the prior more than doubles the error.

Checked against a grid of 240,001 candidate thresholds, the derived boundary really is the best available. It is a small thing to verify and it catches sign errors, which are easy to make here and invisible afterwards.

Imitating the Bayes classifier by counting

Real data does not come with P(Y∣X)P(Y \mid X). k-nearest-neighbours estimates it in the most direct way imaginable: look at the kk training points closest to x0x_0, and use the proportions among them.

P(Y=j∣X=x0)=1k∑i∈N0I(yi=j)P(Y = j \mid X = x_0) = \frac{1}{k} \sum_{i \in \mathcal{N}_0} I(y_i = j)

Then apply the Bayes rule to that estimate. Nothing is fitted in advance - the training set is the model, which makes training instantaneous and prediction expensive.

k is the flexibility dial

Take a two-dimensional problem whose Bayes error rate, computed by integration, is 0.0927080.092708. Fit on 200 training points, score on 20,000 test points:

kk135915254575125199
test error0.13820.11550.10300.09760.09720.09770.09770.10360.12310.5049

Read the two ends first. At k=1k = 1 every training point is its own nearest neighbour, so the training error is exactly zero - and the test error, 0.1382000.138200, is the worst in the table apart from the degenerate k=199k = 199. That single pair of numbers is the clearest demonstration you will see that training error is not an estimate of test error.

At k=199k = 199 out of 200 training points, nearly the whole sample votes on every prediction. The classifier has stopped depending on xx at all and simply returns the majority class, so its error, 0.5048500.504850, is essentially the class prior. Maximum bias, minimum variance, no information.

Between them the curve is U-shaped, with a shallow floor from k=9k = 9 to k=45k = 45 and a best value of 0.0971500.097150 at k=15k = 15 - within half a percentage point of the Bayes floor, from a method that assumed nothing about the shape of the boundary. There is no formula for the best kk; it is chosen by cross-validation, and the flatness of the floor means it usually only has to be roughly right.

What it costs

The method imposes no shape on the boundary, so it can trace curves and disconnected regions no linear model can express. In exchange it has no way to ignore an irrelevant feature: every dimension enters the distance, so accuracy degrades as uninformative features are added. In high dimensions the "nearest" neighbours are not close to x0x_0 in any useful sense, which is one face of the curse of dimensionality.

And because the distance is Euclidean, a feature measured in large units dominates it. Standardising is not a refinement here; it is a precondition for the method meaning anything at all.

Before the quiz

The Bayes classifier picks the most probable class at every point and cannot be beaten; what it leaves behind is the Bayes error rate, 0.1056500.105650 for the one-dimensional example. Priors move the boundary toward the rarer class, and ignoring them costs measurably. k-nearest-neighbours imitates the rule by counting neighbours, with kk as the flexibility dial: k=1k = 1 memorises, k≈nk \approx n returns the majority class, and the useful values are in between.

References & further reading

  • Gareth James, Daniela Witten, Trevor Hastie, Robert Tibshirani, An Introduction to Statistical Learning, with Applications in R, Springer (Springer Texts in Statistics 103), 2013source ↗
  • Stuart Russell, Peter Norvig, Artificial Intelligence: A Modern Approach, Pearson (3rd edition), 2010· Kudos AI reference library

Copyrighted works are cited for reference only and are not hosted here; please consult the publisher for access.

Unlock the full path

This first lesson is free. Enrol to take the mastery quiz, earn XP, and unlock every module, with more interactive, runnable examples throughout.