Pour une application d'apprentissage automatique, mon groupe doit calculer la distance euclidienne au ème voisin le plus proche dans un ensemble pour chaque (pour entre 5 et environ 100 , et quelques centaines à quelques millions). Nous utilisons actuellement soit l'approche par force brute , soit l'approche évidente avec un arbre kd sur , qui lorsque est élevé etest relativement faible ne gagne jamais. (Tout est en mémoire.)X x ∈ ( X ∪ Y ) ⊂ R d d | X | ≈ | Y | O ( d | X | | X ∪ Y | ) X d | X |
Il semble qu'il doit y avoir un meilleur moyen que la force brute, au moins un qui tire parti de l'inégalité du triangle, ou peut-être avec des hachages sensibles à la localité. Une approximation raisonnablement serrée est également potentiellement acceptable.
La recherche que j'ai pu trouver semble se concentrer sur le problème de trouver le seul voisin le plus proche (ou celui qui est approximativement le plus proche). Le problème que je recherche a-t-il un autre nom ou existe-t-il un lien avec un problème connexe auquel je n'ai pas pensé?
Réponses:
Voici une astuce simple qui pourrait être utile. Prenons un échantillon aléatoire qui sélectionne chaque point avec une probabilité de 1 / k. Il est facile de vérifier qu'avec une bonne probabilité, exactement l'un de vos k voisins les plus proches se trouverait dans l'échantillon. Calculez le plus proche voisin dans l'échantillon. Répétez cette O (k log n) fois. Avec une probabilité élevée, les k points les plus proches des points calculés sont les k voisins les plus proches de votre requête. Ainsi, trouver le k voisin le plus proche équivaut à effectuer requêtes du voisin le plus proche.O ( k log n )O(klogn) O(klogn)
En bref, donnez-moi une structure de données rapide pour répondre aux requêtes du plus proche voisin, et je serais heureux de vous donner une structure de données rapide de k-plus proche voisin.
la source
Une solution approximative bon marché utilisant un "hachage sensible à la localité" serait de convertir chaque point en sa forme entrelacée de bits:
[xxx, aaaa, zzz] -> xyzxyzxyz
puis tri radix pour le prétraitement.
Voir également cet article de Callahan et Kosaraju.
la source