El algoritmo KNN ponderado en Arduino

Ya hemos visto como funciona el algoritmo KNN en Arduino, simplemente busca los vecinos más cercanos y mira cuales es la clase más numerosa entre ellos. Esta estrategia puede tener problemas cuando las distintas categorías están muy mezcladas o en puntos que están en la frontera entre dos categorías. En esos casos un punto puede estar muy cerca de unos pocos vecinos de una clase pero la mayoría de vecinos (más lejana) ser de otra clase.

Una forma de solucionar esto es que no todos los vecinos valgan lo mismo. Los más cercanos valen más que los más lejanos. En el algoritmo KNN tradicional cada vecino vale lo mismo «1», en la versión ponderada cada vecino vale una constante fija w dividida por la distancia (w/dist). Ahora sumamos cada uno de esos valores de cada clase y asignamos la clase que más sume. La constate w se usa para evitar que el resultado sea muy pequeño cuando las distancias son muy grandes.

La confianza también cambia, ahora es el valor de la suma de los vecinos de la clase mayoritaria, dividida entre el total de la suma de los pesos de todos los K vecinos.

Un ejemplo lo podemos ver en la imagen de debajo donde los puntos verdes son clasificados como pertenecientes a la clase azul (X) en lugar de a la clase roja (+) si se usa el algoritmo KNN normal, pero son correctamente clasificados si se usa la versión ponderada.

Para K = 3 los puntos verdes son mal clasificados por KNN

La librería ArduinoKNN no contempla este algoritmo por lo que tendremos que implementarlo nosotros usando esta librería como base. Podéis usar la librería Arduino_KNNw que implementa algunas mejoras sobre

En este caso tenemos que usar la función; classifyWeighted(input, K ,w ); Siendo input el elemento a clasificar (un array), K el número de vecinos que se tendrán en cuenta y w la constate por la que se dividirá la distancia, w = 1 por defecto. Si ya sabemos usar Arduino_KNN (si no aquí podéis leerlo) su uso es idéntico:

int class = myKNN.classifyWeighted(input, 3);
float confidence = myKNN.confidence();

Podéis ver un ejemplo aqui.