Ich denke, Leistung ist hier nicht sehr wichtig, aber ich kann nicht widerstehen. Die Funktion zip () kopiert beide Vektoren vollständig neu (eigentlich eher eine Matrixtransponierung), um die Daten in der Reihenfolge "Pythonic" zu erhalten. Es wäre interessant, die Implementierung der Schrauben und Muttern zeitlich zu planen:
import math
def cosine_similarity(v1,v2):
"compute cosine similarity of v1 to v2: (v1 dot v2)/{||v1||*||v2||)"
sumxx, sumxy, sumyy = 0, 0, 0
for i in range(len(v1)):
x = v1[i]; y = v2[i]
sumxx += x*x
sumyy += y*y
sumxy += x*y
return sumxy/math.sqrt(sumxx*sumyy)
v1,v2 = [3, 45, 7, 2], [2, 54, 13, 15]
print(v1, v2, cosine_similarity(v1,v2))
Output: [3, 45, 7, 2] [2, 54, 13, 15] 0.972284251712
Dies geht durch das C-ähnliche Rauschen des einzelnen Extrahierens von Elementen, führt jedoch kein Kopieren von Bulk-Arrays durch und erledigt alles Wichtige in einer einzigen for-Schleife und verwendet eine einzelne Quadratwurzel.
ETA: Der Druckaufruf wurde aktualisiert, um eine Funktion zu sein. (Das Original war Python 2.7, nicht 3.3. Das aktuelle läuft unter Python 2.7 mit afrom __future__ import print_function
Anweisung ausgeführt.) Die Ausgabe ist in beiden Fällen dieselbe.
CPYthon 2.7.3 auf 3.0 GHz Core 2 Duo:
>>> timeit.timeit("cosine_similarity(v1,v2)",setup="from __main__ import cosine_similarity, v1, v2")
2.4261788514654654
>>> timeit.timeit("cosine_measure(v1,v2)",setup="from __main__ import cosine_measure, v1, v2")
8.794677709375264
Der unpythonische Weg ist in diesem Fall also etwa 3,6-mal schneller.