Choose the metric, k value, and test sample (★). See the k nearest neighbors, the voting, the tie-breaking when necessary, and how this propagates to the confusion matrix and the accuracy of the whole set.
7.18.6 EP07_06 🟣 Complete Pipeline: Descriptors + k-NN + Multi-Class Evaluation
This exercise integrates the three central stages of the chapter into a single pipeline, reproducing in miniature the Practical Project 2 (classification of synthetic textures by LBP): a set of histograms of descriptors already extracted (as if they were LBP histograms) is used to train a k-NN classifier, which in turn is evaluated on an independent test set using a multi-class confusion matrix.
Unlike EP07_01, here the feature space has arbitrary dimension \(H\) (the histogram size), there are more than two classes, and the distance metric is an input parameter — making it possible to reproduce the metric comparison experiment discussed in the chapter.
7.18.6.1 📋 Implementation Guidelines
- Classes: Read the integer \(C\) (number of classes) followed by \(C\) class names (strings without spaces), in the order in which they should appear in the confusion matrix.
- Configuration: Read the integer \(H\) (histogram dimension), the string \(M\) (metric:
euclidianaormanhattan) and the odd integer \(k\). - Training: Read the integer \(N\) and then \(N\) lines, each containing the class name followed by \(H\) real values (the descriptor histogram).
- Testing: Read the integer \(Q\) and then \(Q\) lines, each containing the actual class name followed by \(H\) real values (the descriptor histogram of the test sample).
- Distance: For each test sample, calculate the distance to each training example using the metric \(M\): \[ d_{\text{euclidiana}}(u,v) = \sqrt{\sum_{j=1}^{H}(u_j-v_j)^2}, \qquad d_{\text{manhattan}}(u,v) = \sum_{j=1}^{H} |u_j - v_j|. \]
- k-NN Classification: Select the \(k\) closest training examples (distance tie broken by reading order, as in EP07_01) and classify by the majority class among them. In the case of a voting tie between two or more classes, choose the one that appears first in the class list from item 1.
- Confusion matrix: Build a \(C \times C\) matrix in which the row corresponds to the actual class and the column to the predicted class, following the class order from item 1.
- Accuracy: Calculate the global accuracy as the ratio of correct predictions to \(Q\).
- Output: For each test sample, in input order, print the predicted class. Then print the confusion matrix (one row per actual class, values separated by spaces, in class order). Finally, print the accuracy rounded to 4 decimal places.
7.18.6.2 📌 Computational Constraints
- Selectable metric: implement both distances; the metric \(M\) defines which one is used throughout the execution (it is not possible to mix metrics in the same run).
- Deterministic voting tie-break: the criterion from item 6 (class list order) must be followed even when the tie involves more than two classes.
- Training and test independence: there is no need to validate that the test samples do not appear in training — assume the input is valid.
7.18.6.3 🧠 Theoretical Foundation
| Exercise stage | Corresponding stage in the chapter |
|---|---|
| Training/test histograms already extracted | descritor_lbp applied to synthetic textures |
| Euclidean or Manhattan distance | metric parameter of the KNeighborsClassifier |
| Majority voting with \(k\) neighbors | KNeighborsClassifier.predict |
| \(C\times C\) confusion matrix | confusion_matrix from scikit-learn |
| Global accuracy | accuracy_score from scikit-learn |
This exercise highlights, in a controlled way, a result discussed in the chapter: the choice of distance metric and the value of \(k\) can change the predicted class for the same sample, even keeping the descriptor used fixed — reinforcing that, in classical pattern recognition, the descriptor, the metric, and the classifier form an interdependent system, not isolated parts.
7.18.6.4 📦 Input and Output Specification (VPL)
Input:
- Line 1: integer \(C\) followed by \(C\) class names.
- Line 2: integer \(H\), string \(M\), and integer \(k\).
- Line 3: integer \(N\).
- Next \(N\) training lines: class name followed by \(H\) real values.
- Next line: integer \(Q\).
- Next \(Q\) test lines: actual class name followed by \(H\) real values.
Output:
- \(Q\) lines with the predicted class of each test sample, in input order.
- \(C\) lines with the confusion matrix (one row per actual class).
- Last line:
Acuracia: <value>.
7.18.6.5 📌 Examples
| Input (summarized) | Output | Observation |
|---|---|---|
| 2 granular listrada 2 euclidiana 1 4 granular 0.9 0.1 granular 0.8 0.2 listrada 0.1 0.9 listrada 0.2 0.8 2 granular 0.85 0.15 listrada 0.15 0.85 |
granular listrada 1 0 0 1 Acuracia: 1.0000 |
With \(k=1\), each test sample is classified by the closest training neighbor. |
This simulator uses a simplified set of 3 classes (granular, striped, spotted) over fictional 2D points, solely to illustrate the voting, tie-breaking, and confusion matrix pipeline of k-NN. In EP07_07, you will apply this same logic to a real image mosaic, which introduces a fourth class (checkered) and replaces the 2D points with LBP histograms extracted directly from the image pixels.
%%writefile EP07_06.py
# Python codeOverwriting EP07_06.py
TestSuite("EP07_06.py").run()✔️ EP07_06.cases already exists in casos/
📋 5 case(s) loaded from casos/EP07_06.cases
🔍 Testing Python: EP07_06.py
⚠️ EP07_06.py: Empty file (fewer than 3 lines). Tests skipped.