Burada performansın pek önemli olduğunu sanmıyorum ama karşı koyamıyorum. Zip () işlevi, verileri "Pythonic" sırasına göre elde etmek için her iki vektörü de (aslında bir matris devrikinden daha fazlası) tamamen yeniden kopyalar. Somun ve cıvata uygulamasını zamanlamak ilginç olurdu:
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
Bu, öğeleri birer birer ayıklamanın C benzeri gürültüsünden geçer, ancak toplu dizi kopyalaması yapmaz ve önemli her şeyi tek bir for döngüsünde yapar ve tek bir karekök kullanır.
ETA: Yazdırma çağrısı bir işlev olacak şekilde güncellendi. (Orijinal Python 2.7 idi, 3.3 değil. Şu anki Python 2.7 altında bir from __future__ import print_function
ifade ile çalışıyor.) Çıktı her iki şekilde de aynı.
3.0GHz Core 2 Duo üzerinde CPYthon 2.7.3:
>>> 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
Bu durumda, pirtonik olmayan yol yaklaşık 3.6 kat daha hızlıdır.