I. La métrica de distancia
Primero, el número de características (columnas) en un conjunto de datos no es un factor para seleccionar una métrica de distancia para usar en kNN. Hay bastantes estudios publicados dirigidos precisamente a esta pregunta, y las bases habituales para la comparación son:
la distribución estadística subyacente de sus datos;
la relación entre las características que comprenden sus datos (son independientes, es decir, cómo se ve la matriz de covarianza); y
El espacio de coordenadas del que se obtuvieron sus datos.
Si usted no tiene conocimiento previo de la distribución (s) de los cuales se tomaron muestras de sus datos, al menos uno (bien documentada y exhaustiva) estudio concluye que la distancia euclidiana es la mejor opción.
Métrica euclidiana utilizada en motores de recomendación web a gran escala, así como en investigaciones académicas actuales. Las distancias calculadas por Euclidiana tienen un significado intuitivo y las escalas de cálculo, es decir, la distancia euclidiana se calcula de la misma manera, ya sea que los dos puntos estén en dos dimensiones o en un espacio de veintidós dimensiones.
Solo me ha fallado unas pocas veces, cada uno de esos casos la distancia euclidiana falló porque el sistema de coordenadas subyacente (cartesiano) era una mala elección. Y generalmente reconocerá esto porque, por ejemplo, las longitudes de camino (distancias) ya no son aditivas, por ejemplo, cuando el espacio métrico es un tablero de ajedrez, la distancia de Manhattan es mejor que Euclidiana, del mismo modo cuando el espacio métrico es la Tierra y sus distancias son trans -vuelos continentales, una métrica de distancia adecuada para un sistema de coordenadas polares es una buena idea (por ejemplo, Londres a Viena son 2.5 horas, Viena a San Petersburgo son otras 3 horas, más o menos en la misma dirección, pero Londres a St Petersburgo no es 5,5 horas, en cambio, es un poco más de 3 horas
Pero aparte de aquellos casos en los que sus datos pertenecen a un sistema de coordenadas no cartesiano, la elección de la métrica de distancia generalmente no es material. (Vea esta publicación de blog de un estudiante de CS, comparando varias métricas de distancia examinando su efecto en el clasificador kNN: el chi cuadrado da los mejores resultados, pero las diferencias no son grandes; un estudio más completo se encuentra en el documento académico, Estudio comparativo de Funciones de distancia para los vecinos más cercanos: Mahalanobis (esencialmente euclidiana normalizada para dar cuenta de la covarianza de la dimensión) fue la mejor en este estudio.
Una condición importante: para que los cálculos métricos de distancia sean significativos, debe volver a escalarsus datos: rara vez es posible construir un modelo kNN para generar predicciones precisas sin hacer esto. Por ejemplo, si está construyendo un modelo kNN para predecir el rendimiento deportivo, y sus variables de expectativa son altura (cm), peso (kg), grasa corporal (%) y pulso en reposo (latidos por minuto), entonces un punto de datos típico podría se parece a esto: [180.4, 66.1, 11.3, 71]. Claramente, el cálculo de la distancia estará dominado por la altura, mientras que la contribución por% de grasa corporal será casi insignificante. Dicho de otra manera, si en cambio, los datos se informaron de manera diferente, de modo que el peso corporal estaba en gramos en lugar de kilogramos, entonces el valor original de 86.1 sería 86,100, lo que tendría un gran efecto en sus resultados, que es exactamente lo que no tiene no quiero
X_new = (X_old - mu) / sigma
II La estructura de datos
Si le preocupa el rendimiento de la estructura de kd-tree, A Voronoi Tessellation es un contenedor conceptualmente simple pero que mejorará drásticamente el rendimiento y las escalas mejor que kd-Trees.
Esta no es la forma más común de conservar los datos de entrenamiento de kNN, aunque la aplicación de VT para este propósito, así como las ventajas de rendimiento consecuentes, están bien documentadas (ver, por ejemplo, este informe de Microsoft Research ). El significado práctico de esto es que, siempre que esté utilizando un lenguaje 'convencional' (por ejemplo, en el Índice TIOBE ), entonces debería encontrar una biblioteca para realizar la TV. Sé que en Python y R, hay múltiples opciones para cada idioma (por ejemplo, el paquete voronoi para R disponible en CRAN )
Usar un VT para kNN funciona así:
A partir de sus datos, seleccione al azar w puntos: estos son sus centros Voronoi. Una célula de Voronoi encapsula todos los puntos vecinos más cercanos a cada centro. Imagínese si asigna un color diferente a cada uno de los centros Voronoi, de modo que cada punto asignado a un centro determinado esté pintado de ese color. Siempre que tenga una densidad suficiente, al hacerlo se mostrarán los límites de cada centro Voronoi (como el límite que separa dos colores).
¿Cómo seleccionar los Centros Voronoi? Yo uso dos pautas ortogonales. Después de seleccionar al azar los puntos w, calcule el VT para sus datos de entrenamiento. Luego, verifique la cantidad de puntos de datos asignados a cada centro de Voronoi: estos valores deben ser aproximadamente los mismos (dada la densidad de puntos uniforme en su espacio de datos). En dos dimensiones, esto causaría un VT con mosaicos del mismo tamaño. Esa es la primera regla, aquí está la segunda. Seleccione w por iteración: ejecute su algoritmo kNN con w como parámetro variable y mida el rendimiento (tiempo necesario para devolver una predicción consultando el VT).
Imagine que tiene un millón de puntos de datos ..... Si los puntos persistieran en una estructura de datos 2D ordinaria, o en un árbol kd, realizaría en promedio un par de millones de cálculos de distancia por cadanuevos puntos de datos cuya variable de respuesta desea predecir. Por supuesto, esos cálculos se realizan en un solo conjunto de datos. Con un V / T, la búsqueda del vecino más cercano se realiza en dos pasos uno tras otro, contra dos poblaciones diferentes de datos: primero contra los centros Voronoi, luego, una vez que se encuentra el centro más cercano, los puntos dentro de la celda corresponden a se buscan en ese centro para encontrar el vecino más cercano real (mediante cálculos de distancia sucesivos) Combinados, estas dos búsquedas son mucho más rápidas que una sola búsqueda de fuerza bruta. Eso es fácil de ver: para 1 millón de puntos de datos, suponga que selecciona 250 centros Voronoi para testear su espacio de datos. En promedio, cada celda Voronoi tendrá 4,000 puntos de datos. Entonces, en lugar de realizar en promedio 500,000 cálculos de distancia (fuerza bruta), realiza mucho menos, en promedio solo 125 + 2,000.
III. Cálculo del resultado (la variable de respuesta pronosticada)
Hay dos pasos para calcular el valor predicho a partir de un conjunto de datos de entrenamiento de kNN. El primero es identificar n, o el número de vecinos más cercanos a usar para este cálculo. El segundo es cómo ponderar su contribución al valor predicho.
W / r / t el primer componente, puede determinar el mejor valor de n resolviendo un problema de optimización (muy similar a la optimización de mínimos cuadrados). Esa es la teoria; en la práctica, la mayoría de las personas solo usan n = 3. En cualquier caso, es simple ejecutar su algoritmo kNN en un conjunto de instancias de prueba (para calcular los valores pronosticados) para n = 1, n = 2, n = 3, etc. y trazar el error en función de n. Si solo desea un valor plausible para que n comience, nuevamente, use n = 3.
El segundo componente es cómo ponderar la contribución de cada uno de los vecinos (suponiendo que n> 1).
La técnica de ponderación más simple consiste en multiplicar cada vecino por un coeficiente de ponderación, que es solo el 1 / (dist * K), o la inversa de la distancia desde ese vecino a la instancia de prueba a menudo multiplicada por alguna constante derivada empíricamente, K. I No soy un fanático de esta técnica porque a menudo sobrepesa a los vecinos más cercanos (y concomitantemente subestima a los más distantes); La importancia de esto es que una predicción dada puede depender casi por completo de un solo vecino, lo que a su vez aumenta la sensibilidad del algoritmo al ruido.
Una función de ponderación mejor, que evita sustancialmente esta limitación es la función gaussiana , que en python se ve así:
def weight_gauss(dist, sig=2.0) :
return math.e**(-dist**2/(2*sig**2))
Para calcular un valor pronosticado usando su código kNN, identificaría los n vecinos más cercanos al punto de datos cuya variable de respuesta desea predecir ('instancia de prueba'), luego llame a la función weight_gauss, una vez para cada uno de los n vecinos, pasando en la distancia entre cada vecino, el punto de prueba. Esta función devolverá el peso de cada vecino, que luego se utiliza como el coeficiente de ese vecino en el cálculo del promedio ponderado.