Post on 05-Jan-2016
description
7/17/2019 KNN (K-Nearest Neighbors)
http://slidepdf.com/reader/full/knn-k-nearest-neighbors 1/10
1.02 KNN (K-Nearest Neighbors)
KNN es un algoritmo extremadamente simple, se trata de encontrar a partir de un punto cuales son los “k”
vecinos más cercanos al mismo. Este algoritmo puede usarse de muchas formas: para encontrar los
documentos más cercanos a un query, para clasificar en base a las clases de los vecinos más cercanos,etc. A partir de aquí vamos a usarlo como si fuera un algoritmo de clasificación pero debe entenderse que
su uso puede extenderse a muchísimas aplicaciones.
Usar KNN para clasificar un punto es muy simple: contamos con un set de entrenamiento que son puntos
en “n” dimensiones para los cuales conocemos a que clase pertenecen. Cuando queremos clasificar un
punto nuevo buscamos los “k” puntos más cercanos y asignamos al punto la clase que tenga mayoría entre
estos vecinos.
El algoritmo no tiene fase de entrenamiento ya que simplemente usa los puntos del mismo para clasificar.
La fase de clasificación, en cambio, es costosa ya que hay que comparar al punto que queremos clasificar
con todos los demás puntos del set de datos.
El código para KNN es realmente muy simple ya que solo usamos funciones básicas que ya hemos visto
con anterioridad.
La función es muy sencilla y devuelve varias cosas:
- neighbors es un vector de “k” puntos, los más cercanos al “x” pasado.
- classes son las clases de los “k” puntos más cercanos (si existe el vector de labels)
- distances son las “k” distancias a los puntos
- indexes son los “k” indices de los puntos más cercanos en la matriz “points” (filas)
A partir de esta función es muy sencillo construir una función que clasifique un punto en base a la clase de
sus “k” vecinos más cercanos por simple mayoría:
7/17/2019 KNN (K-Nearest Neighbors)
http://slidepdf.com/reader/full/knn-k-nearest-neighbors 2/10
Notemos que además de devolver la clase podemos devolver la probabilidad de la misma como la cantidad
de puntos sobre k que responden a dicha clase. Cuando hay empates devolvemos una clase cualquiera.
Ejemplo: Tenemos el siguiente conjunto de puntos y sus clases. (‘knnset2.mat’)
>> load(‘knnset2.mat’);
>> scatter(knn2(:,1),knn2(:,2),52,labels2,'filled')
Queremos clasificar un punto nuevo por ejemplo el [0.5 0.5]:
>> scatter(knn2(:,1),knn2(:,2),52,labels2,'filled')
>> hold on
>> plot(0.5,0.5,'kx','Markersize',10);
7/17/2019 KNN (K-Nearest Neighbors)
http://slidepdf.com/reader/full/knn-k-nearest-neighbors 3/10
Corremos el algoritmo con k=3 y encontramos lo siguiente:
>> [n,c]=KNN([0.5 0.5],knn2,3,labels2);
Como vemos de los tres puntos más cercanos hay dos azules y uno verde por lo que a nuestro punto “X” lo
clasificaríamos como azul.
Es interesante notar que el set de datos nos define un diagrama de frontera en donde cada posible punto
de nuestro espacio de n-dimensiones tiene asignada una clase. Esta frontera cambia según el valor de “k”
que usamos.
7/17/2019 KNN (K-Nearest Neighbors)
http://slidepdf.com/reader/full/knn-k-nearest-neighbors 4/10
Podemos llamar la siguiente función:
>> KNNPlot(knn2,labels2,k)
Probando diferentes valores para “k”
Aquí vemos el efecto de ir variando “k” en nuestro set de datos, a medida que aumentamos k la clase verde
que tiene más puntos que las demás domina todo el espacio Es decir que KNN es sensible a unadistribución desbalanceada de las clases cuando usamos un K alto.
Notemos también que pese a ser un algoritmo extremadamente sencillo KNN es capaz de aprender
clasificaciones no-lineales de forma arbitraria en nuestro espacio de n-dimensiones. De todos los algoritmos
de clasificación KNN es el único que puede lograr esto con un procedimiento sencillo, los demás, como
veremos, requieren de varias maniobras para aprender una clasificación no-lineal.
Encontrando K
Para encontrar el K óptimo la mejor alternativa es usar cross-validation y verificar cual es el valor de K que
funciona mejor. El procedimiento consiste en separar un conjunto de puntos del set de entrenamiento (por
ejemplo el 20%) y clasificarlos en base al 80% restante de los puntos usando diferentes valores de K. El K
que mejor resultados logre es el elegido.
Veamos el siguiente ejemplo:
>> load(‘knnset3.mat’)
>> scatter(knn3(:,1),knn3(:,2),52,labels3,'filled')
7/17/2019 KNN (K-Nearest Neighbors)
http://slidepdf.com/reader/full/knn-k-nearest-neighbors 5/10
Como podemos ver diferentes valores de K tienen diferente efecto en los puntos azules que están de visita
en la zona roja. Con K=11 o K=17 dividimos el espacio en dos zonas, roja y azul lo curioso es que
desconocemos si esto es algo bueno, malo, muy bueno o muy malo. Dependiendo del tipo de clasificación
que estemos haciendo podría tener sentido usar K=3 o K=17.
7/17/2019 KNN (K-Nearest Neighbors)
http://slidepdf.com/reader/full/knn-k-nearest-neighbors 6/10
Hay que destacar que el K óptimo de acuerdo al set de entrenamiento no siempre es el K que mejor
funciona para clasificar a los datos que desconocemos, esto se soluciona si tenemos un set de
entrenamiento muy numeroso. En algunos casos en KNN la diferencia entre usar K=3, 5 o 17 no es para
nada clara y sin embargo el funcionamiento del algoritmo depende completamente de este parámetro.
KNN & BigData
Desafortunadamente KNN tiene problemas escalando a datos masivos, es necesario por cada punto a
clasificar compararlo contra todos los demás puntos y esto no es bueno. Existen estructuras de datos
llamadas índices espaciales que tienen como objetivo limitar la cantidad de puntos que hay que recorrer
entre estas estructuras podemos nombrar los KD-Trees, R-Trees, Quad-Trees y muchos otros.
Lamentablemente estas estructuras de datos degradan su performance rapidamente a medida que
nuestros datos tienen mayor cantidad de dimensiones, a punto tal que para 4 o más dimensiones la
mayoría de estas estructuras no aportan ventaja significativa con respecto a una simple búsqueda por
fuerza bruta. Esto es producto de la “maldición de la dimensionalidad” y es uno de los temas más
importantes que tenemos que resolver.
En capítulos posteriores vamos a ver varios algoritmos para resolver este problema, es decir encontrar los
puntos más cercanos a un punto dado sin tener que realizar una búsqueda por fuerza bruta de todos los
puntos.
KNN & CIFAR
Vamos a ver un ejemplo de KNN en acción usando como set de datos CIFAR-10 que contiene 50.000
imágenes repartidas en 10 (diez) clases diferentes:
El set de datos se puede cargar con:
7/17/2019 KNN (K-Nearest Neighbors)
http://slidepdf.com/reader/full/knn-k-nearest-neighbors 7/10
>> load('all_data.mat')
Que nos deja una matriz “imgs” de 50.000 x 3072 para las imágenes (son de 32x32 pixeles x3 canales =
3072) y un vector labels con las 50.000 clases asignadas.
Como un primer ejercicio tomemos algunas imágenes al azar de CIFAR-10 y calculemos sus 10 vecinos
más cercanos.
El script cifarknntest1.m toma 5 imágenes al azar de CIFAR y busca las 8 imágenes más cercanas a cada
una de ellas.
Aquí vemos KNN en acción con todo lo bueno y lo malo del método al mismo tiempo. En la fila de abajo el
caballito tiene 8 vecinos caballitos KNN lo clasificaría perfectamente. En la fila de arriba sin embargo el
caballito se parece mucho a un montón de aviones, principalmente por el fondo de la imagen. Podemos
sacar varias conclusiones aquí, KNN es un buen método para clasificar pero las imágenes en crudo no son
la mejor fuente de datos para calcular distancias. Por este motivo veremos más adelante varios algoritmos
que tienen como objetivo extraer de un conjunto de datos los features que necesitamos para poder
clasificarlos.
Probemos ahora intentar clasificar CIFAR-10 usando KNN. Vamos simplemente a probar con las 50.000
imágenes calculando en base a las 5 imágenes más cercanas la clase.
7/17/2019 KNN (K-Nearest Neighbors)
http://slidepdf.com/reader/full/knn-k-nearest-neighbors 8/10
Este proceso es terriblemente lento! En próximos capítulos veremos todo tipo de algoritmos y técnicas para
que KNN sea más eficiente. Así de importante es este algoritmo. Veremos que alcanzamos una precisión
de alrededor del 30% lo cual es mucho comparado con el 10% que sería clasificar al azar y muy poco
comparado con lo que lograría un ser humano que es cercano al 94%. CIFAR-10 es un set de datos muy
difícil de clasificar, vamos a usarlo en muchas oportunidades para probar diferentes estrategias y
algoritmos.
Podemos usar un script para tomar particiones al azar de por ejemplo 3000 puntos de CIFAR-10 y probar
con diferentes valores de K a ver que resultados tenemos. Esto nos ayuda a encontrar el K más
conveniente.
Notemos que en KNN no hace falta tener separado una parte del set de entrenamiento para
cross-validation ya que el algoritmo no hace absolutamente nada en la fase de entrenamiento, es decir, no
tiene fase de entrenamiento. Simplemente clasifica en base a los k puntos más cercanos.
7/17/2019 KNN (K-Nearest Neighbors)
http://slidepdf.com/reader/full/knn-k-nearest-neighbors 9/10
El script va a hacer 3 rondas de tomar 3000 puntos al azar y clasificarlos con valores de k=1,3,5,7,9,11,13.
Luego promedia la precisión para cada valor de k y genera un plot.
7/17/2019 KNN (K-Nearest Neighbors)
http://slidepdf.com/reader/full/knn-k-nearest-neighbors 10/10
Según este resultado en particular el mejor K es 7. Es notable que K=1 es mucho mejor que K=3, como
podemos ver la selección del K óptimo en KNN tiene algunos misterios.
Conclusión
KNN es uno de los algoritmos más importantes de nuestro libro, es un método sencillo que permite
clasificar de forma no-lineal, también lo usaremos en una buena cantidad de otros algoritmos que necesitan
buscar puntos cercanos a un cierto punto del conjunto de datos. Es un algoritmo tan importante que vamos
a dedicar una buena cantidad de tiempo a optimizarlo.
Ejercicios
1. Evaluar cuál es el mejor “k” para clasificar diferentes sets de datos. Graficar la precisión del
clasificador en función de “k” para Mnist, CIFAR-10 y CIFAR-100.
2. Utilizar un KD-Tree para ayudar a KNN a encontrar los puntos más cercanos. Probar con sets de
datos sintéticos de diferente número de dimensiones. Comparar el tiempo necesario en cada caso
contra el tiempo necesario del método por fuerza bruta. ¿Qué conclusiones podemos sacar?
3. Usando KNN averiguar cuál es el punto de cada clase para el cuál todos sus vecinos pertenecen a
su clase para el k más alto posible. Usar estos puntos como centroides iniciales de K-Means. ¿Son
estos centroides los óptimos para aplicar K-Means en todos los casos? Explique por qué sí o no.
4. Tenemos una cantidad de puntos a clasificar en usando KNN y k=7, proponemos clasificar primero
los puntos que tienen sus 7 vecinos en la misma clase, agregándolos al set de entrenamiento luego
de clasificarlos, luego los que tienen 6 vecinos y así sucesivamente. Compare los resultados
obtenidos con una única pasada de KNN sobre el set de entrenamiento. Pruebe con diferente
cantidad de clases y vea que conclusiones podemos extraer.