Méthode efficace pour trouver KNN de tous les nœuds dans un arbre KD
Je suis actuellement en train de trouver des K plus proches voisins de tous les nœuds d'un équilibré KD-Tree (avec K=2).
Mon application est une variation du code de la Article de Wikipedia et c'est décemment rapide de trouver des KNN de n'importe quel nœud O(log N).
Le problème réside dans le fait que j'ai besoin de trouver KNN de chaque nœud. Venir avec sur O(N log N) si je itérer sur chaque nœud et d'effectuer la recherche.
Est-il un moyen plus efficace de faire cela?
source d'informationauteur St. John Johnson
Vous devez vous connecter pour publier un commentaire.
En fonction de vos besoins, vous voudrez peut-être essayer avec des approximations techniques. Pour plus de détails, la caisse Arya et le Mont's de travail sur le sujet. Une clé de papier est ici. BigO complexité des détails sont situés dans leur '98 papier.
Une illustration graphique de l'ouvrage est illustré ci-dessous:
Source: http://www.cs.umd.edu/~mount/ANN/Images/annspeckle.gif
J'ai utilisé leur bibliothèque à de très hautes dimensions des ensembles de données contenant des centaines de milliers d'éléments. C'est plus rapide que tout autre chose, j'ai trouvé. La bibliothèque gère à la fois exacte et approximative des recherches. Le paquet contient certaines CLI utilitaires que vous pouvez utiliser de l'expérience facilement avec votre jeu de données; et même la possibilité de visualiser le kd-tree ( voir ci-dessus ).
FWIW: j'ai utilisé le R Liaisons.
De ANN manuel de l':
J'ai utilisé la couverture de l'arbre pour résoudre ce problème. Voici le lien: http://hunch.net/~jl/projects/cover_tree/cover_tree.html
Dans un ensemble de données pour 50M de la taille(Tous les kNN requête, k=100), couvercle arbre a pris de 5,5 s pour la création, et 120s pour l'interrogation. Ann lib a pris 3.3 s pour la création de l'arbre, et 138s pour l'interrogation.
mis à jour:Le plus proche voisin n'est pas une relation symétrique. Considérez ceci:Un(0,0) B(1,0) (C) (3,0). B est le plus proche de C, tandis que le C n'est pas le plus proche de B
Si les nœuds eux-mêmes sont requête points, puis le temps de recherche peut être inférieure. Vous pouvez commencer avec des retours en arrière scène et les premiers nœuds testés sont déjà à proximité du point de requête. Puis de grandes zones de l'arbre peuvent être nettoyées à bientôt.
Le plus proche voisin est une relation symétrique (si n1 est un voisin le plus proche de la n2, la même chose s'applique à n2) donc vous avez seulement besoin de chercher la moitié des nœuds sauter tous les nœuds déjà marqué comme voisins les plus proches. Juste une idée.
Vous pouvez également essayer de KD-Tree BBF (Best-Bin d'Abord) de recherche, qui vous aidera à rechercher le plus proche de nœuds (bacs) plus tôt. J'ai mis en œuvre ce en C#, donc écrivez-moi si vous êtes intéressé dans le code source.
Bien sûr, le temps d'exécution dépend de la dimensionnalité, KD-Tree structure et la répartition des points dans votre jeu de données.
Le regroupement des points peuvent également être approprié.
Le terme à rechercher est knn rejoindre. Plus précisément, vous voulez probablement faire une auto-jointure.
Peut-être les résultats de la recherche de l'aide:
J'ai seulement vu knn des algorithmes de jointure pour le R*-tree. Cependant, dans mes propres expériences, ils n'étaient pas en mesure de surclasser une requête répétée. J'ai peut-être pas certains de la mise en œuvre des idées. Mais en général, contenant les données de façon appropriée pour un arbre de jointure est beaucoup plus délicat que d'un seul knn requête.