I'm building a computer vision real-time application, and for this project, I want to use the well known KNN (K-Nearest Neighbors) algorithm in a quite unusual way. I need to manage an incoming stream of data (that can be described as points with labels) so my idea is to fed KNN with the data that I have at the moment, ask for classification of some unknown points. And when new data will come, updating KNN with those new data and repeat again and again. In general, I will re-train KNN hundred of times, each time with a few (less than 5) points more.
I'm using python (3.8.3) with OpenCV (4.1.3) for the entire project, and in the future, I will need to convert everything into C++, so I'm hoping to find a solution with those technologies.
I'm having trouble with cv::ml::KNearest that allows me to train the model, but each training completely ignores the previous training and it forgets data, so I'm not able to "update KNN". How can I solve it?
- In OpenCV (2.4) there was the parameter that I'm looking for, used to update the model:
updateBasebut in version 4 it seems disappeared. - Is it efficient to store in the code outside all the points and then feed KNN all times with the whole points of training?
- I've written my own version of KNN to clarify what my goal is. Of course, is not optimized, especially the
classifyfunction, if there is no solution to the previous two questions, how do you suggest to improve this implementation?
class MyKNN:
def __init__(self):
self.knnPoints = []
self.knnLabels = []
def train(self, points, labels) -> None:
if len(points) != len(labels):
print("Error: len(points) != len(labels)")
else:
[ self.knnPoints.append(el) for el in points ]
[ self.knnLabels.append(el) for el in labels ]
def classify(self, query, k: int=5) -> "label":
distances = []
for point in self.knnPoints:
dist = spatial.distance.sqeuclidean(query, point)
distances.append(dist)
topK = heapq.nsmallest(k, zip(distances, self.knnLabels, self.knnPoints))
for (i, (score, label, point)) in enumerate(topK):
print("The {} match has score {:.3f} and label {}".format(i+1, score, str(label)))
print("")
return(topK)