Ich habe in meiner Studienarbeit eine einfache Suche nach nächsten Nachbarn implementiert. Tatsache ist, dass die grundlegende numpy Implementierung gut funktioniert, aber nur den '@jit' Dekorator hinzufügend (kompilierend in Numba), die Ausgaben sind differents (es kopiert einige Nachbarn am Ende aus irgendeinem unbekannten Grund ...)Unterschiede in den Ausgaben von numba
Hier ist der grundlegende Algorithmus:
import numpy as np
from numba import jit
@jit(nopython=True)
def knn(p, points, k):
'''Find the k nearest neighbors (brute force) of the point p
in the list points (each row is a point)'''
n = p.size # Lenght of the points
M = points.shape[0] # Number of points
neighbors = np.zeros((k,n))
distances = 1e6*np.ones(k)
for i in xrange(M):
d = 0
pt = points[i, :] # Point to compare
for r in xrange(n): # For each coordinate
aux = p[r] - pt[r]
d += aux * aux
if d < distances[k-1]: # We find a new neighbor
pos = k-1
while pos>0 and d<distances[pos-1]: # Find the position
pos -= 1
pt = points[i, :]
# Insert neighbor and distance:
neighbors[pos+1:, :] = neighbors[pos:-1, :]
neighbors[pos, :] = pt
distances[pos+1:] = distances[pos:-1]
distances[pos] = d
return neighbors, distances
Zum Testen:
p = np.random.rand(10)
points = np.random.rand(250, 10)
k = 5
neighbors = knn(p, points, k)
OHNE @jit Dekorateur, eine die richtige Antwort bekommt:
In [1]: distances
Out[1]: array([ 0.3933974 , 0.44754336, 0.54548715, 0.55619749, 0.5657846 ])
Aber die Numba Compilation gibt seltsame Ausgänge:
Out[2]: distances
Out[2]: array([ 0.3933974 , 0.44754336, 0.54548715, 0.54548715, 0.54548715])
Jemand helfen kann? Ich weiß nicht, warum es passiert ...
Vielen Dank.
Sie können in der scipy interessiert sein [KDTree] (http://docs.scipy.org/doc/scipy/ Referenz/generierte/scipy.spatial.cKDTree.html) Implementierung. – Daniel
@Ophion Danke für den Tipp. Ich habe mit der KDTree-Implementierung von sklearn gespielt (ich nehme an, sie sind ähnlich) und sie sind gut für die Vorverarbeitung der Daten für zukünftige multiple Abfragepunkte. In meiner Arbeit muss ich die Nachbarn finden, die ständig die Punkteliste ändern (in Sachen Bildverarbeitung), und diese Art von Implementierungen wird zu langsam. Und es scheint, dass die KDTree-Implementierung nicht besser ist als Brute-Force, wenn die Raumdimension groß ist (beispielsweise größer als 25). –