← Part of Lysen · lysen.org
Lysen ML
← All algorithms Supervised · classification

K-nearest neighbours

The problem it solves: something new arrives and you have to put a label on it. KNN puts the label on by looking around. It measures how far the new thing is from every example you already have, keeps the k closest, and gives the new thing whatever label most of those k are carrying. That is the whole algorithm. There is no line to fit, no weights to learn, and no training step at all.

What to read first: nothing. This is the one chapter on the site that needs no earlier one. If you have read logistic regression you will recognise the ideas in module 3 and 4, and where that happens there is a link back rather than a repeat.

Used for recommendationhandwriting and image matchingfraud and anomaly triagefilling in missing valuesa first honest baseline
Learning typeSupervised
Primary taskClassification
Also doesRegression
MechanismDistance based · no training

Running example for the whole chapter: a packing line that sorts fruit into crates. A belt carries apples, oranges and lemons past two sensors, so every fruit arrives as two numbers: width in centimetres and weight in grams. Seventy-four fruits have already been sorted by hand, and those are the examples the machine gets to look at. Everything that rolls past after that has to be labelled from those seventy-four alone.

01

Intuition: you have been doing this all along

1a Circle the group you can already see

Below are the seventy-four fruits the line has already sorted, plotted by width and weight. The labels are hidden, so all you have is the shape of the cloud.

Drag a loop around the fruits you think belong to one type. Do it by eye. You will be right.

Drag anywhere on the plot to draw. Let go and the loop closes itself.

…fruits inside your loop …most common type inside …share that type holds
Draw a loop and the fruits inside it will tell you what they actually were.

Nobody told you where the groups were. You found them by noticing that things near each other tend to be the same thing, which is the only assumption this entire algorithm makes.

Now notice what you did not do. You did not work out an equation for the boundary, and you could not write down the loop you drew as a formula if somebody asked. You looked at what was nearby and went with the local majority.

KNN never draws that loop. It does something lazier and, it turns out, more flexible: it waits until a new fruit shows up and only then asks who is standing closest.

1b Drop a fruit on the belt

Same plot, labels revealed. Click anywhere to put a new fruit on the belt, then drag it around. The lines show its distance to the k nearest sorted fruits, and those k are the only ones with a vote.

apple orange lemon the fruit you dropped
Click on the plot to drop a fruit, then drag it into a crowd and watch the verdict change.

Put your fruit deep inside one crowd and every k gives the same answer. Put it on the seam between apples and oranges and the answer starts flipping as you change k, which is module 3's whole problem in one gesture.

That is the algorithm. Measure, rank, take the top k, count the labels, go with the majority. Everything left in this chapter is about the three quiet decisions hiding in that sentence: what measure means, what k should be, and whether the numbers being measured are on speaking terms with each other.

CuriousIf there is no training step, what is the model?

The data. That is not a joke or a simplification: the seventy-four sorted fruits are the model. Fitting a KNN classifier means storing them, which is why the fit is instant and why the library call that does it looks suspiciously like it forgot to do anything.

The name for this is a lazy learner. Linear and logistic regression are eager: they do the work once, boil a whole dataset down to a couple of numbers, and then throw the dataset away. KNN defers all of the work to prediction time and throws nothing away. Every chapter on this site has a moment where the cost has to be paid, and this is the only algorithm that pays it at the end rather than the beginning. Module 4e is about the bill.

02

The algorithm: every step of the loop

There is no loop over epochs here, because there is nothing to improve. The loop is over the data you already have, and it runs once per question you ask.

1store every sorted fruit, exactly as it came // this is the whole of "training"
2for each new fruit:
3 measure the distance to every stored fruit // §2a
4 sort those distances and keep the nearest k // §2b
5 count the labels among those k, and take the majority // §2c

Three lines of work, and each one hides a decision that changes the answer. We will take them in order.

2a Line 3: measure against every single one

To know which fruits are closest, there is no shortcut past measuring all of them. Nothing has been summarised, so nothing can be skipped. Seventy-four stored fruits means seventy-four distances, every time, for every new fruit forever.

Drag the pale fruit anywhere. Every line you can see is one distance the machine has to work out before it can answer.

…distances measured …nearest of them all …farthest of them all

The ranking that comes out

…

Only the order of that list survives into the next step. The distances themselves get thrown away the moment the sort finishes, which is a small fact with large consequences, and §2c is where they land.

2b Line 4: deciding what "near" is allowed to mean

So far "distance" has quietly meant the straight line between two dots, because that is what a plot makes you think of. It is one choice out of many, and each one draws a different shape around the new fruit.

The shape below is every point that sits at exactly the same distance from the new fruit. Under a straight line that shape is a circle. Under other measures it is not.

apple orange lemon the new fruit everything the same distance away

Both axes are in standard deviations, so the picture is square and the shapes are honest. §2c is about why that is not cheating.

d = √( Δwidth² + Δweight² )
…what the k nearest vote for …neighbours swapped out
…

On two tidy features the four measures mostly agree, and the swap counter mostly reads zero. That is the honest result, and it is worth seeing before the table below tempts you into thinking the choice is always dramatic. It becomes dramatic when the features are counts, categories, or many.

Which measure, and when

Distance is a slot in the algorithm, not a fact about the world. Anything that turns two examples into one number and behaves sensibly can go in the slot. These are the ones you will actually meet.

MeasureWhat it adds upReach for it whenThe catch
EuclideanL2 · the straight line The square root of the summed squared gaps. Features are continuous, comparable and few. The default, and a fine one. Squaring lets one badly wrong feature dominate the total, and it fades fastest as columns pile up (§4a).
ManhattanL1 · city blocks The summed gaps, no squaring. Features are separately meaningful, or there are a lot of them. Steadier than Euclidean when one feature is odd. Depends on which way the axes point, so rotating the data changes the answer.
ChebyshevL∞ · the worst gap Only the single largest gap. The rest are ignored. Being far off on any one feature should disqualify a neighbour on its own. Tolerance checks, grids, board games. Throws away every feature but one, so it wastes most of what you measured.
Minkowskithe family they all live in The summed gaps each raised to p, then the p-th root. You want to tune the measure rather than pick one. p=1 is Manhattan, p=2 is Euclidean, large p approaches Chebyshev. One more knob to cross-validate, and it usually earns less than fixing your features would.
Cosinethe angle, not the length The angle between two rows read as arrows from the origin. Length is an artefact. Text, word counts, ratings, embeddings: a long document and a short one on the same subject should count as near. Deliberately blind to magnitude, so it cannot tell a big thing from a small thing of the same shape.
Hamminghow many differ The number of positions where two rows disagree. Everything is categorical or binary. Yes and no columns, genetic sequences, error-correcting codes. Every disagreement counts the same, so a wrong country weighs exactly as much as a wrong day of the week.
Jaccardoverlap of sets What two sets share, divided by everything they cover between them. Rows are sets of tags, ingredients, purchases or visited pages, and lengths differ. A shared absence counts for nothing, which is right for baskets and wrong for questionnaires.
Mahalanobisdistance that knows the spread The gap measured in units of how the data actually varies, with correlated features counted once. Features are correlated and on different scales, and you would rather the measure handled that than do it by hand. Needs enough rows to estimate the covariance, and it is fragile when you do not have them.
Gowermixed columns A per-column score, numeric or categorical, averaged into one number. The table has ages, prices, postcodes and yes-or-no columns side by side. Real tables usually do. The averaging is a weighting decision, made for you, and rarely questioned.
Edit distanceand dynamic time warping How many changes turn one sequence into the other, allowing for stretch. Rows are not points at all: they are words, gestures, sensor traces, or two recordings of the same movement at different speeds. Slow, and quadratic in the length of the sequences, so a full scan gets expensive fast.

Two rules cover almost every real case. If the columns are numbers that mean the same kind of thing, start with Euclidean and only move if you have a reason. If length is noise rather than information, use cosine. Everything else on that table is a specific answer to a specific shape of data.

CuriousDoes it have to be a distance at all?

No. The algorithm only ever asks the measure to rank things, so anything that gives a consistent ordering will run. It does not even have to be a distance in the mathematical sense, which requires that nothing is nearer to something else than it is to itself, and that going via a third point is never a shortcut.

Two families get used constantly and neither is a distance:

  • Similarity, the mirror image. Cosine similarity and Jaccard both answer "how alike", where bigger means closer. You sort descending instead of ascending and nothing else changes. Most libraries take the measure as an argument for exactly this reason.
  • A measure the data chooses for itself. Rather than picking a formula, you can learn one, by fitting the weighting that pulls examples of the same class together and pushes the others apart. That is metric learning, and it is what an embedding model is doing when it puts two photographs of the same person near each other. Face recognition on your phone is very close to KNN run on a learned measure.

There is a real limit though. Break the triangle rule and you lose the tricks that make prediction fast (§4e), because those rely on being able to say "everything in this branch is at least so far away" without checking. A strange measure means a full scan every time, with no way out.

2c Line 5: the vote, and the ranking it counts on

The vote itself is the least interesting line in the algorithm. Count the labels among the k nearest, take whichever appears most, done.

What makes it interesting is what it is counting. The vote never sees a distance. It sees a list in order, and takes the top k. So anything that changes the order changes the answer, and the order is decided entirely by which units you happened to measure in.

Here is the problem in our own data. Width is measured in centimetres and spans about six of them. Weight is measured in grams and spans about two hundred. Ask for the straight-line distance between two fruits and the grams swamp the centimetres before you have finished typing the formula.

apple orange lemon everything counted as near
…weight counts this much more than width …accuracy on 40 unseen fruits

The five nearest, in order

…

In raw units the neighbourhood is a flat band. Anything within a few grams counts as near no matter how much wider or narrower it is, so width is not being under-weighted, it is being ignored. And width is the one thing that separates an apple from an orange here, because an orange carries a thick peel and is wider than an apple of the same weight.

The fix is one line and it is the most valuable line in this chapter: put every feature on the same footing before measuring anything. Subtract the mean of the column, divide by its spread, and now one step is one step whichever column you took it in.

for each feature: z = (value − mean of that column) ÷ spread of that column // then measure distances on z

Standardising is not a neutral act, though, and pretending otherwise is how people get surprised later. It is a claim that every feature deserves the same say. Sometimes it does not, and then you weight on purpose: the third setting above lets you decide that width is worth twice what weight is, or that weight should count for nothing. Turn one of them down to zero and watch the neighbourhood collapse into a stripe again.

Two habits keep this honest. Work out the mean and the spread on your training data only, and reuse those exact numbers on everything that arrives afterwards, or the new fruit gets judged by a ruler it helped to build. And when you report a result, convert back: a neighbour is 0.4 standard deviations away only to the algorithm. To the person reading the report it is half a centimetre and nine grams, and that is the version they can argue with.

CuriousWhat happens in a tie?

Ties are common and libraries are quiet about them. Set k to 4 in the interactive in §1b, drop a fruit on the seam between apples and oranges, and you can get two votes each. Something has to break it.

  • Make k odd. The advice everyone gives. It works for exactly two classes and does nothing at all for three, where three neighbours can be an apple, an orange and a lemon.
  • Let the nearest one decide. Among the tied classes, pick the one owning the single closest neighbour. Cheap and defensible.
  • Add up the distances. Sum the distance of each tied class's neighbours and take the smaller total, so four votes clustered tightly beat four spread thin. This is distance weighting arriving through the back door.
  • Weight every vote by nearness from the start, so a neighbour half as far counts twice. Exact ties then stop happening almost entirely, and this is usually the right answer. It has a second benefit worth more than tie-breaking: it makes a large k much safer, because distant neighbours stop being able to shout (§3).
  • Shrink k by one and ask again until the tie breaks. Tidy, and it quietly turns your chosen k into a suggestion.

Worth knowing what your library does when you have not said. Scikit-learn's classifier resolves a tie by taking the class that comes first in sorted order, which for labels named "apple" and "orange" means apples win the alphabet. That rule is not wrong so much as arbitrary, and it will never mention itself in the output.

CuriousWhat if the answer is a number rather than a label?

Then you average instead of counting, and everything else stays exactly where it is. Find the k nearest, take the mean of their answers, and that is KNN regression. Use the median instead of the mean and one wild neighbour stops mattering.

It is genuinely useful for the thing regression struggles with: a relationship that is not a line and does not want to become one. Predicting the rent of a flat from its position on a map is the standard example. There is no formula from latitude and longitude to rent, but the four nearest flats know.

The catch it inherits is worth stating, because it is the one people trip over. A KNN regressor can never predict a value outside the range it has seen, since an average of stored answers is bounded by those answers. Ask linear regression about a house twice the size of anything in its data and it will confidently extrapolate, and be wrong. Ask KNN and it will hand you back the average of the biggest houses it knows, and be wrong in the opposite direction, but it will at least be wrong inside the realm of things that have actually happened.

03

Evaluation: k is the only dial, and it lies to you

Every other model on this site has a loss you can watch fall. KNN has nothing of the kind, because it never fits anything, so there is no curve to stare at and no moment where it settles. The single number you get to choose is k, and choosing it badly is the main way this algorithm goes wrong.

3a Watch the boundary breathe

The coloured background is the machine's answer for every possible fruit: drop one anywhere in the pale coral region and it goes in the apple crate. The solid dots are the seventy-four sorted fruits it learned from. The hollow rings are forty fruits it has never seen, held back to mark its homework.

The regions at k =5

Accuracy against k

…accuracy on the fruits it stored …accuracy on the 40 it has never seen …stored score minus unseen
…
apple orange lemon held-out fruit accuracy on the stored fruits accuracy on the unseen forty

Three things are worth doing to that slider before you read on.

  • Push it to k = 1. Accuracy on the stored fruits jumps to a perfect 100 percent, and it will do that on any dataset you ever feed it, because the nearest fruit to a stored fruit is itself, at a distance of zero. The model has memorised the answer sheet. Meanwhile accuracy on the unseen forty drops below every other small setting: every k from 3 into the forties beats it. This is the cleanest demonstration on the site of why a score on the data a model has memorised is not a score at all.
  • Walk it up slowly. The islands dissolve, the boundary straightens, and the two accuracies converge. Somewhere in the low single figures the held-out score peaks. That is the trade every model makes, and here it is a single integer.
  • Push it to the far end. With k at seventy-three, almost every fruit on the line is voting on every question, so the answer stops depending on the question. The whole plot turns one colour and accuracy drops to 35 percent, which is not a coincidence: it is exactly the share of apples in the test set. The model has become "always say apple" with extra steps.

So small k follows the noise and large k ignores the signal. Reading that as bias and variance is the right instinct, and it is the same dial as lambda in linear regression and depth in a decision tree, wearing different clothes.

3b How you actually pick k

Not by eye, and not from that curve. The forty held-out fruits above are drawn so you can see the shape of the problem, but the moment you choose k by looking at them you have started fitting to them, and their score stops meaning anything.

The real procedure is cross-validation: split the training fruits into five parts, and for each candidate k, fit on four parts and score on the fifth, rotating until every part has taken a turn as the scorer. Average the five, take the k with the best average, and only then let the held-out forty pass judgment, once.

Three rules of thumb that survive contact with real data:

  • Odd k for two classes, to stop the most common tie. It does nothing for three classes or more, as the tie aside in §2c explains.
  • Weight the votes by nearness rather than counting them equally, and large k stops being dangerous, because a neighbour on the far side of the plot can no longer shout as loudly as one next door.
  • The square root of the number of stored examples is where people start. For seventy-four fruits that suggests about nine. It is a starting point for the search, not a result.

Accuracy is also the wrong score to be reading here, and this chapter has been quietly abusing it. It is fine on this data because the three crates are almost equally full. Change that and it stops being fine, which is the subject of a page shared by every classifier on the site.

The rest of the scoring lives on the shared evaluation and comparison page: the confusion matrix, precision, recall, F1 and what to do when one class is rare. Logistic regression and decision trees point at the same page rather than each explaining it again. Go there →
04

Failure modes, and how to counter each

KNN fails in ways that are unusually easy to demonstrate, because there is no fitting process to hide behind. When it goes wrong, it is the data that is wrong, and you can see it.

4a Too many columns, and "near" stops meaning anything

This is the one that kills the algorithm in production, and it is deeply unintuitive: adding more information makes it worse. Not slower. Worse.

Suppose the packing line also records the belt speed, the hour of the day, the lane number, the humidity in the shed, and twenty other things it happens to have a sensor for. None of them says anything about fruit. Watch what they do anyway.

Accuracy as useless columns are added

Every stored fruit, by how far away it is

…accuracy at k = 5 …farthest fruit ÷ nearest fruit …columns in total
…

The right-hand strip is the part to watch. With two columns the farthest fruit is around thirty times further off than the nearest, so "nearest" picks out a real, small group. Add noise columns and every fruit gets a random contribution in every one of them, the distances all drift towards the same middling value, and the crowd closes up. By twenty columns the farthest fruit is barely twice as far as the nearest. The word nearest has stopped selecting anybody in particular, and the vote is now being cast by a more or less random handful.

This is the curse of dimensionality, and it is not really about dimensions. It is about volume. Every column you add gives the space another direction to be empty in, and the same seventy-four fruits have to spread themselves across all of it. To keep the neighbourhood as densely populated as it was with two columns, you would need exponentially more fruit, and nobody has exponentially more fruit.

The counters, in the order worth trying:

  • Drop columns that carry nothing. The cheapest and by far the most effective. Every column has to earn its place, and a column that does not is not neutral, it is actively harmful. Distance-based models care about this more than any other family.
  • Compress rather than delete. If forty columns genuinely contain information, squeeze them into a handful of combined ones first with something like PCA, then run KNN on those.
  • Weight the features instead of trusting them equally, as in §2c, so a column that barely matters barely counts.
  • Switch to Manhattan or a fractional p. Squaring is what lets many small random gaps add up into a large one, so a measure that does not square degrades more slowly. It buys you a few columns, not thirty.
  • Use a different family. A decision tree simply ignores a useless column, and a linear model gives it a weight near zero. Neither has to be talked out of it. If you cannot get the column count down, the honest move is to stop using KNN.

4b The feature nobody wired up

The opposite failure, and much more common than the curse in practice. Apples and oranges overlap on this plot because width and weight genuinely cannot tell them apart in the region where they meet. No k fixes that. No distance measure fixes that. The information is not in the data.

The packing line has a camera. It could measure how bumpy the peel is, and an orange is dimpled where an apple is smooth. Nobody wired that value into the table.

What the machine is given: width and weight

apple orange lemon held-out fruit put in the wrong crate

What it is not given: peel roughness

…accuracy at k = 5 …fruits in the wrong crate
…

Nothing in the left-hand picture moves when you switch. The same fruits sit in the same places and the apples and oranges still overlap exactly as much as they did. The mistakes disappear anyway, because the machine is now measuring in a direction this picture cannot show. Every failure on the left was a missing column, not a bad algorithm, and no amount of tuning would have found it.

This is the counterweight to §4a and the two have to be held together. Useless columns poison KNN, and a missing useful column caps it. The work is choosing which columns, and that work is yours: no search over k, no cross-validation and no library default has any way to tell you that the camera was pointed at the fruit the whole time.

4c One fruit in the wrong crate

Somebody put an orange in the apple pile by hand, months ago, and it has been sitting in the training data ever since. At k = 1 that single mistake gets a territory of its own, and every fruit that lands in it inherits the error.

Drag the ringed fruit into the middle of the oranges and watch it carve a hole.

…of the plot this one fruit controls …accuracy on the unseen 40
…

The counter is k itself. Move the slider up by two and the island shuts. A single wrong label cannot outvote three right ones, so raising k is the cheapest noise filter there is, and it is the reason k = 1 is almost never the answer outside a textbook. Weighting votes by nearness helps too, though less than you would hope: the mislabelled fruit is genuinely the nearest one, so nearness weighting hands it the loudest voice of all.

Which leaves the boring fix, which is also the correct one: look at your labels. KNN is unusually good at showing you where they went wrong, because a mislabelled example produces a visible island rather than a slightly worse number. Run leave-one-out over the training set, list every fruit whose neighbours all disagree with it, and hand that list to whoever did the labelling.

4d One crate is much fuller than the others

Suppose the line handles ten thousand apples a day and two hundred lemons. Around any new fruit, the neighbourhood is mostly apples for the simple reason that the world is mostly apples, and lemons lose votes they should have won. Nothing has gone wrong mechanically. The vote is doing exactly what it was told, and the count is a popularity contest before it is a similarity judgment.

Weighting votes by nearness helps, because a lemon standing right beside the new fruit outweighs six apples further off. Beyond that the counters are the ones shared by every classifier, and they live on the evaluation page: resample so the classes are closer to even, weight the rare class up, and stop quoting accuracy, which will read 98 percent while the model never once says lemon.

4e The bill arrives at prediction time

The zero-cost training is not free, it is deferred. Every question means measuring against every stored example, so with a million rows and twenty columns, one prediction is twenty million multiplications. Linear regression answers the same question with twenty. The model that took no time to build is the one you cannot afford to use.

  • Index the data with a KD-tree or a ball tree, which lets whole branches be skipped once they are provably too far away. Free accuracy, real speedup, and it quietly stops working once you have more than about twenty columns, for the reasons in §4a.
  • Give up exactness. Approximate nearest neighbour libraries return almost the right neighbours in a tiny fraction of the time. Every large-scale vector search you have used today was doing this.
  • Thin the stored set. Most examples sit deep inside their own crowd and never change a vote. Keep the ones near the boundaries and drop the rest.
  • Remember what you are storing. The model is the training data, so shipping the model ships every row of it. For medical records or anything about identifiable people that is not an implementation detail, it is a disclosure, and it is the argument against KNN that comes from outside the maths.

4f The judgment point

The big one

"Because five things like you were"

KNN cannot give a reason. Ask logistic regression why and it will point at a weight. Ask a decision tree and it will read you the questions it asked. Ask KNN and the complete, honest answer is a list of five neighbours. There is no rule to inspect, no coefficient to argue with, and nothing to appeal against.

For fruit that is fine. For a person it is a different object entirely. A decision made this way says you were treated as your five closest matches were treated, and if those five were treated unfairly, the unfairness is copied forward exactly and called a prediction. The algorithm has no concept of the past being wrong. It only knows that it happened, nearby.

There is a strange honesty in that. Other models blur the same problem into a coefficient and make it look like reasoning. KNN hands you the five rows and lets you see whose lives the answer was actually copied from, which is uncomfortable, and better.

05

Prompting AI: making an assistant build it properly

KNN is four lines long, so an assistant will get it running instantly and correctly. That is the trap. The code will be right and the result will be wrong, because everything that decides whether KNN works happens before the algorithm is called and none of it is visible in the output.

"Classify my fruit data with KNN in Python."

What you typically get back

Four lines that import KNeighborsClassifier, fit it on everything, print an accuracy, and stop. No scaling, so whichever column happens to be measured in the largest units has silently decided every answer (§2c). A default k of 5 that was never chosen. A score taken on the same rows the model memorised, which for k = 1 would have read a flawless 100 percent. And no word about how many columns went in.

features never scaledk left at the defaultscored on stored datacolumn count uncheckedties resolved alphabeticallyno baseline

One extra instruction is worth more here than in any other chapter: ask it to put the scaler and the model in a single pipeline object. Scaling by hand before splitting is the most common bug in beginner KNN code, and it is invisible: the model quietly learns the mean and spread of the test set, the score comes out flattering, and nothing anywhere reports a problem.

06

Beyond AI: choosing the tool, owning the call

KNN earns its place twice. It is the honest baseline: if a neural network cannot beat "ask the five most similar rows", the network is not learning anything the data does not simply contain, and you have found that out in an afternoon. And it is the right answer outright whenever the boundary is a strange shape, the dataset is small, and new classes keep appearing, since adding a class means adding rows rather than retraining anything.

If your problem looks like thisReach forBecauseThe price you pay
Few columns, an awkward boundary, and new categories that keep turning up K-nearest neighboursthis chapter No training, no assumption about the shape of the boundary, and a new class costs you one insert. Every prediction scans everything, the model is your raw data, and it falls apart past about twenty columns.
Two groups, a roughly straight boundary, and somebody will ask you why Logistic regressionprevious chapter Instant predictions, calibrated probabilities, and a weight per feature you can read out loud. One straight boundary only, and the features have to be informative already.
Many columns, mixed types, and thresholds rather than distances Decision treeits own chapter Ignores useless columns for free, needs no scaling at all, and reads back as a list of questions. Unstable on small data, and a single tree overfits unless it is pruned or grown in a forest.
Hundreds of columns, or images, text and audio Learned embeddingsthen KNN on top A model compresses the raw thing into a short vector where distance means what you want it to, which is exactly what §4a says KNN needs. You now have a second model to train, explain and maintain, and the embedding decides what "similar" means.
No labels at all, and you want to know what groups exist K-meansthe clustering chapter Same instinct about distance, opposite job: it invents the groups rather than copying labels from neighbours. You have to choose how many groups, and it will find them whether or not they are there.

The k in KNN and the k in K-means are not the same k, and the two algorithms are not variants of one another. K-means is unsupervised and k is how many groups to invent. KNN is supervised and k is how many opinions to ask. The only thing they share is a distance function.

6b The judgment calls no prompt makes for you

Judgment call

What counts as similar

Standardising says every feature deserves an equal say. Leaving the raw units in says whichever column has the biggest numbers should decide. Both are claims about the world dressed as data preparation, and one of them is always being made, including when nobody chooses.

Judgment call

Which columns are allowed in

KNN has no way to ignore a column. Every one you include is a direction it measures in, so including a column is voting for its relevance. That includes columns that stand in for something you would never use on purpose, like a postcode that is really an income bracket.

Data reality

Whose data is stored

The model is a copy of the training rows, kept whole and shipped wherever the model goes. Nothing was summarised away, so nothing was anonymised by accident. If the rows are about people, the model is a database of people.

Responsibility

Who the neighbours were

A prediction here is a claim that this case should be treated as the nearest previous cases were. That is only fair if those cases were handled fairly. The algorithm cannot check, and it never asks.