2016-06-25 15 views
5

Ich habe eine Reihe von 100 Tausend Vektoren und ich muss Top-25 nächsten Vektor basierend auf Kosinusähnlichkeit abrufen.Wie schnell berechnen Cosinus Ähnlichkeit für eine große Anzahl von Vektoren in Python?

Scipy und Sklearn haben Implementierungen für die Berechnung von Kosinusabstand/Ähnlichkeit 2 Vektoren, aber ich muss den Cosinus Sim für 100k X 100k Größe berechnen und dann top-25 herausnehmen. Gibt es eine schnelle Implementierung in Python?

Per @Silmathoron Suggestion, ist es das, was ich tue -

#vectors is a list of vectors of size : 100K x 400 i.e. 100K vectors each of dimenions 400 
vectors = numpy.array(vectors) 
similarity = numpy.dot(vectors, vectors.T) 


# squared magnitude of preference vectors (number of occurrences) 
square_mag = numpy.diag(similarity) 

# inverse squared magnitude 
inv_square_mag = 1/square_mag 

# if it doesn't occur, set it's inverse magnitude to zero (instead of inf) 
inv_square_mag[numpy.isinf(inv_square_mag)] = 0 

# inverse of the magnitude 
inv_mag = numpy.sqrt(inv_square_mag) 

# cosine similarity (elementwise multiply by inverse magnitudes) 
cosine = similarity * inv_mag 
cosine = cosine.T * inv_mag 

k = 26 

box_plot_file = file("box_data.csv","w+") 

for sim,query in itertools.izip(cosine,queries): 
    k_largest = heapq.nlargest(k, sim) 
    k_largest = map(str,k_largest) 
    result = query + "," + ",".join(k_largest) + "\n" 
    box_plot_file.write(result) 
box_plot_file.close() 
+0

Was meinen Sie mit dem "Top-25 nächsten Vektor"? Die Top 25 der engsten Paare? Oder etwas anderes? –

+0

Für jeden Vektor werde ich eine Kosinusähnlichkeit mit jedem anderen Vektor berechnen und 25 Vektoren für jeden Vektor in Bezug auf die Kosinusähnlichkeit auswählen. – user3667569

+0

es hängt davon ab, wie schnell Sie es wollen ... wenn Sie uns ein Beispiel für Ihre Implementierung mit der Zeit zeigen (möglicherweise auf einer Teilprobe, wenn es wirklich zu langsam ist), und sagen Sie uns die gewünschte Geschwindigkeitserhöhung, dann können wir sagen Sie können, wenn es mit besseren algorithmischen nur in Python beschleunigt werden kann oder wenn Sie zu Cython oder Multithreading gehen müssen ... – Silmathoron

Antwort

2

Ich würde zuerst intelligente Algorithmen versuchen, anstatt Brute-Force (Rechen alle Paare von Vektoren) zu beschleunigen. KDTrees funktionieren möglicherweise, scipy.spatial.KDTree(), wenn Ihre Vektoren von geringer Dimension sind. Wenn sie eine hohe Dimension haben, benötigen Sie möglicherweise zuerst eine zufällige Projektion: http://scikit-learn.org/stable/modules/random_projection.html