Calcular la distancia al késimo vecino más cercano para todos los puntos del conjunto

9

Para una aplicación de aprendizaje de máquina, mis necesidades de grupo para calcular la distancia euclídea a la ésimo vecino más cercano en un conjunto para cada (para entre 5 y aproximadamente 100 , y algunos cientos hasta unos pocos millones). Actualmente estamos utilizando el enfoque de fuerza bruta o el obvio con un árbol kd en , que cuando es alto yes relativamente bajo, nunca gana. (Todo está en la memoria).kXx(XY)Rdd|X||Y|O(d|X||XY|)Xd|X|

Sin embargo, parece que debe haber una mejor manera que la fuerza bruta, al menos una que aproveche la desigualdad del triángulo, o tal vez con hashes sensibles a la localidad. Una aproximación razonablemente ajustada también está potencialmente bien.

La investigación que he podido encontrar parece centrarse en el problema de encontrar el vecino más cercano (o uno que sea aproximadamente el más cercano). ¿El problema que busco tiene otro nombre o hay una conexión con un problema relacionado en el que no he pensado?

Dougal
fuente
2
Los árboles kd SÍ aprovechan la desigualdad del triángulo. ¿Has intentado usar otros árboles de partición de datos espaciales? Otra cosa que podría considerar (no sé nada de su algoritmo de aprendizaje automático) si los puntos específicos tienden a tener estructura, lo que podría ayudarlo a encontrar rápidamente hiperplanos y usarlos en un árbol similar a kd en lugar de la mediana habitual por- división de coordenadas que funciona mal en altas dimensiones.
Ross Snider el
@RossSnider gracias por las sugerencias. Y claro, los árboles KD usan la desigualdad del triángulo, pero estaba pensando en algo que sería más rápido que la fuerza bruta. :) ¿Qué otros tipos de árboles de partición de datos espaciales recomendaría? De la lista de Wikipedia, tal vez solo los árboles vp parezcan aplicables, y no parecen ser mejores que los árboles kd para la distancia euclidiana. Y pensaré si hay una mejor forma específica de problemas para definir la separación de hiperplanos, pero no se me ocurre uno.
Dougal
Supongo que esperaba que el hecho de que sabemos que estamos evaluando esto para todos X(así como otros puntos) permitiría algún tipo de ayuda en el algoritmo. Sin embargo, no estoy seguro de que sea así.
Dougal
que es ktípicamente en sus aplicaciones?
Suresh Venkat
1
@SureshVenkat Usualmente usamos un kde aproximadamente 3, a veces un poco más grande.
Dougal

Respuestas:

10

Aquí hay un truco simple que podría ser útil. Considere una muestra aleatoria que selecciona cada punto con probabilidad 1 / k. Es fácil verificar que con buena probabilidad exactamente uno de sus k vecinos más cercanos estaría en la muestra. Calcule el vecino más cercano en la muestra. Repita esto O (k log n) veces. Con alta probabilidad los k puntos más cercanos en elO(klogn)los puntos calculados son los k vecinos más cercanos a su consulta. Por lo tanto, encontrar el k vecino más cercano es equivalente a hacerO(klogn) consultas vecinas más cercanas.

En resumen, dame una estructura de datos rápida para responder a las consultas de vecinos más cercanos, y me complacería darte una estructura de datos rápida de k-vecino más cercano.

Sariel Har-Peled
fuente
Buen truco. También debería estar bien reutilizar las muestras para diferentes puntos de consulta, ¿verdad? Entonces para calcular elk-nearest-neighbour para cada punto del conjunto, solo necesito construir la estructura de datos O(kIniciar sesiónnorte)veces.
Dougal
1
Reutilizar las muestras es complicado, porque entonces se requiere que una muestra fija funcione para CUALQUIER consulta (la cuantificación se invierte) y, por lo tanto, las probabilidades cambiarían. La idea general sería construir un conjunto de muestras de mayor tamaño (esto depende de las # consultas) y usarlas, si eso es un problema.
Suresh Venkat
@SureshVenkat Ah, por supuesto. Me sentaré y averiguaré las probabilidades reales. ¡Gracias a todos!
Dougal
Si lo haces O(kIniciar sesión(1/ /δ)) muestras, entonces cada consulta tiene éxito con probabilidad 1-δ. Tenga en cuenta que este truco es un poco mejor de lo que parece a primera vista: tieneO(kIniciar sesiónnorte) muestras, cada una de ellas de tamaño O(norte/ /k) (con alta probabilidad si kno es muy grande) Lo que significa un mejor tiempo de consulta para cada una de las muestras.
Sariel Har-Peled
3

Una solución aproximada barata que utiliza un "hash sensible a la localidad" sería convertir cada punto en su forma intercalada:

[xxx, aaa, zzz] -> xyzxyzxyz

luego la clasificación de radix para el preprocesamiento.

Elija su punto de consulta y listo k apunta en ambas direcciones para obtener un tamaño 2kconjunto; entonces toma elkthmás cercano a tu punto. También vea este artículo de Connor y Kumar.

También vea este artículo de Callahan y Kosaraju.

Chad Brewbaker
fuente