Je ne pense pas que la performance compte beaucoup ici, mais je ne peux pas résister. La fonction zip () recopie complètement les deux vecteurs (plutôt une transposition matricielle, en fait) juste pour obtenir les données dans l'ordre "Pythonic". Il serait intéressant de chronométrer la mise en œuvre des écrous et boulons:
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
Cela passe par le bruit de type C d'extraction d'éléments un par un, mais ne fait pas de copie de tableau en bloc et fait tout ce qui est important dans une seule boucle for, et utilise une seule racine carrée.
ETA: appel d'impression mis à jour pour être une fonction. (L'original était Python 2.7, pas 3.3. Le courant fonctionne sous Python 2.7 avec unfrom __future__ import print_function
instruction.) La sortie est la même, de toute façon.
CPYthon 2.7.3 sur 3.0GHz 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
Ainsi, la voie unpythonic est environ 3,6 fois plus rapide dans ce cas.