Concepts / Training a k-Nearest Neighbors Classifier on the Iris Dataset

Training a k-Nearest Neighbors Classifier on the Iris Dataset

The dataset's target names turn the label into a word a person can read.

  • Programming
Interactive lab

Try it: k-Nearest Neighbours

How a k-nearest-neighbours classifier labels a new point: measure its distance to every known point, take the K closest, and let them vote.

How it works

  1. Measure the straight-line (Euclidean) distance from the new point to every labelled point.
  2. Rank the points from nearest to farthest.
  3. Keep the K nearest.
  4. Count how many of them belong to each class; the class with the most votes is the prediction (a tie goes to the class of the nearest tied neighbour).

Default run (15 steps): 10 labelled points and a new query point at (5, 3.5). K = 3. … Prediction: class A — A has the most votes.

Simplified: Small 2-D educational dataset (at most 30 points, three classes). Real KNN uses many features and usually scales them first.

Educational simulation

Loading the simulation…

A Flower Nobody Has Named

So far, the model you built learned from flowers whose species were already recorded. The real payoff comes when you meet a flower whose species nobody has written down. Suppose you measure a flower and get a sepal length of 5 cm, a sepal width of 2.9 cm, a petal length of 1 cm, and a petal width of 0.2 cm. You want the trained model to name its species. This article follows that measurement from your notebook into a prediction.

Keep one question in mind as you read: at which step does the flower stop being a list of numbers and start being a species name? Following that transformation is the goal of this article, and it is also the place where most beginners get confused.

What do you think happens?

You have one flower with four measurements. Before reading on, what shape do you expect its array to have: a flat list of four numbers, or a table with one row and four columns?

  • A flat list of four numbers

  • A table with one row and four columns, shape (1, 4)

Reveal answer
Answer:

A table with one row and four columns, shape (1, 4)

scikit-learn expects a two-dimensional array in which each row is one sample and each column is one feature. Even a single flower needs its own row, so the array is nested one level deeper than a flat list.

Packaging One Flower as a Row

New data for prediction must be packaged as a two-dimensional NumPy array with shape (n_samples, n_features). The first axis counts samples, which are the flowers you are asking about. The second axis counts features, which are the measurements taken on each flower. A single flower is therefore stored as one row.

The most important detail is the doubled pair of square brackets. A single flower could be written as a flat list of four numbers, but scikit-learn does not accept that shape for prediction. It always expects a two-dimensional array. Even when you have only one flower, it still needs a row, so the array has to be nested one level deeper than the list of numbers.

[0, 0]5 (sepal length, cm)[0, 1]2.9 (sepal width, cm)[0, 2]1 (petal length, cm)[0, 3]0.2 (petal width, cm)
Which position holds which measurement? Row 0 is the one flower, and the four columns hold its four features in the order they were measured.

Read the structure from the outside in. The outer brackets make the array two-dimensional by listing rows. The inner brackets form the single row for this flower. The four numbers fill that row in the same order the features were measured. Changing the order of the numbers would change which measurement the model treats as which feature, so the order matters as much as the brackets.

Calling predict on the New Flower

Once the array is in the right shape, you call the predict method on the trained knn object and pass it the new array. The method uses the model you already built to decide which class the new flower belongs to, and it returns a predicted class label. In the source example that label is stored in a variable named prediction. The printed output shows it inside square brackets, which tells you the result is an array with one entry for each sample you passed in.

python
Notes on the code
  • The doubled brackets create a 2D array with one row, which is the required (n_samples, n_features) layout.
  • The first print confirms the shape of the array you built before any model is involved.
  • predict uses the trained knn object and returns a class label, not a species name.
  • Indexing target_names with the prediction turns the label into the species name stored in the dataset.

Run the code and compare each printed line with your own guess. The first line only checks the array you built. The lines after the predict call depend on the trained model, and they show the two forms of the answer: the raw label the model returns, and the species name that the dataset attaches to that label.

Tracing the Path from Measurements to a Name

Follow the flower through the whole pipeline. The four measurements become a two-dimensional array. The predict method turns that array into a label. The dataset's target names turn the label into a word a person can read. Each step is a handoff, and each handoff changes what the data represents.

Four measurements5, 2.9, 1, 0.22D arrayshape (1, 4)knn.predictreturns a class labelInteger labela number, not a nametarget_names lookupiris_dataset['target_names']Species namea word a person can readnest into a rowpass to predictreturnsindexread
What transformations does the new flower's data go through before a person can read its species?

Notice that the model never produces a species name directly. It produces a number, and the name is recovered afterward from the dataset. This separation is why the question of where the flower stops being numbers and becomes a name has a precise answer: it happens at the target_names lookup.

From Integer Label to Species Name

The class label is a number. Numbers are convenient for the model but not for people. The target_names attribute of iris_dataset solves this: it holds the species names, and the predicted label can be used to look up the matching entry. The source example performs this lookup by indexing iris_dataset['target_names'] with the prediction. The label works as a position: it selects one entry from the stored list of names.

0predicted labeltarget_names[0]species name at position 01predicted labeltarget_names[1]species name at position 12predicted labeltarget_names[2]species name at position 2indexindexindex
If predict returns a label of 0, which entry of target_names does that select? The label is a position lookup, not a name stored alongside the label.

Because the prediction comes back wrapped in an array, the lookup also returns an array-style result. That is why the printed name appears inside brackets in the source output. The value you read as the species name is the single element inside that list. If you need a plain string, you would take that one element out of the array. The source example keeps the output in the array form shown above.

Mistakes That Hide the Answer

  • Common mistake

    Passing a flat list of four numbers straight to predict

    What it looks like
    knn.predict([5, 2.9, 1, 0.2])
    Why it fails

    scikit-learn expects a two-dimensional array, with one row per sample, even when there is only one flower.

    Do this instead

    Nest the list one level deeper: knn.predict(np.array([[5, 2.9, 1, 0.2]])).

  • Common mistake

    Reordering the four measurements

    Why it fails

    The model maps each position to the feature it learned from. Swapping numbers changes which measurement is treated as which feature.

    Do this instead

    Keep the four numbers in the same order the features were measured in the training data.

  • Common mistake

    Treating the raw prediction as the species name

    What it looks like
    print(prediction) shows a label such as an integer in brackets
    Why it fails

    predict returns a class label, which is a number. The species name is recovered from iris_dataset['target_names'].

    Do this instead

    Index target_names with the prediction to get the species name.

  • Common mistake

    Assuming a printed name is a plain string

    Why it fails

    The lookup returns an array-style result, so the name appears inside brackets.

    Do this instead

    Take the single element out of the array if you need a plain string.

How Far to Trust a Prediction

The model has now produced an answer, and it is tempting to treat that answer as settled. The right question is how we know whether we can trust it. For this flower, nobody has told us the correct species. That gap is the reason the model was built in the first place. A prediction on unlabeled data can be useful, but its correctness cannot be checked against a known answer at the moment you make it.

This does not mean predictions are worthless. It means that judging how far to rely on them is a separate step from making them. Making a prediction is one step. Deciding whether it can be trusted is another, and the earlier evaluation of the model is what gives you grounds to make that decision.

MEDIUM

Write two sentences about the prediction for the new flower. The first says what the prediction tells you. The second says what it does not tell you. Most beginners skip the second sentence, and it is the one that matters when the true species is unknown.

Hints
  • For the first sentence, think about which class the trained model selected for these four measurements.
  • For the second sentence, think about whether anyone has confirmed the true species, and what the model's evidence is based on.

Practice Tracing a New Flower

EASY

A second flower has measurements 6.1, 2.8, 4.7, 1.2 in the same feature order. Write the NumPy line that packages it for predict, then describe in order each object it passes through until it becomes a species name.

Hints
  • Wrap the four numbers in two sets of brackets so the result has one row.
  • The sequence is: array, predict call, integer label, target_names lookup, species name.
MEDIUM

Explain, without running any code, why the position of the prediction inside target_names is a lookup rather than a stored name attached to each label.

Hints
  • Think about what the integer label is used for when it is passed to target_names.

Key Takeaways

  • New data for prediction must be a two-dimensional NumPy array with shape (n_samples, n_features), so one flower is stored as one row of four features in measurement order.
  • The predict method of a trained k-Nearest Neighbors object takes that array and returns a predicted class label, which is a number.
  • The species name is recovered by indexing iris_dataset['target_names'] with the prediction, and the result comes back in array form.
  • A predicted label is an estimate for an unlabeled flower; making the prediction and deciding whether to trust it are two separate steps.

Related concepts

More concepts starting with T