Project · 2023 · completed
KNN and K-means classification benchmark
From-scratch C++ implementations of K-nearest neighbors and K-means for classifying precomputed image feature vectors.
Problem
The project compares supervised and unsupervised approaches to classifying numeric image descriptors. The main challenge is to implement the algorithms, data splitting, cluster-to-class mapping, timing, and evaluation metrics without relying on a machine-learning framework, then measure how hyperparameters and random splits affect the result.
Approach
Feature files are loaded into class-aware vectors based on their filenames and split into training and evaluation subsets. KNN assigns the majority label among the closest training samples. K-means iteratively refines centroids, then maps every cluster to the majority training class it contains so that clustering can be evaluated as a classifier. Experiments sweep several values of k over 100 deterministic random seeds.
Technical implementation
Both algorithms use Euclidean distance over std::vector<float> features. The KNN implementation sorts distance-label pairs and performs a majority vote. K-means initializes centroids from a shuffled training set, alternates assignment and mean updates, and exposes the fitted centroids to an evaluation layer. The benchmark computes accuracy, confusion matrices, per-class precision, recall, F1 score, inference time, and K-means fitting time for several feature representations.
float euclideanDistance(const std::vector<float>& a,
const std::vector<float>& b) {
float distance = 0.0f;
for (std::size_t i = 0; i < a.size(); ++i)
distance += std::pow(a[i] - b[i], 2.0f);
return std::sqrt(distance);
}