Tôi không cho rằng hiệu suất quan trọng nhiều ở đây, nhưng tôi không thể cưỡng lại. Hàm zip() hoàn toàn recopies cả hai vectơ (nhiều hơn một ma trận transpose, thực sự) chỉ để lấy dữ liệu theo thứ tự "Pythonic". Nó sẽ là thú vị khi thời gian thực hiện các loại hạt và bu lông:
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
Đó đi qua các tiếng ồn C giống như chiết xuất các yếu tố một-at-a-thời gian, nhưng làm không sao chép mảng số lượng lớn và được tất cả mọi thứ quan trọng được thực hiện trong một vòng lặp đơn và sử dụng một căn bậc hai.
ETA: Cuộc gọi in được cập nhật thành một hàm. (Bản gốc là Python 2.7, không phải 3.3. Hiện tại chạy dưới Python 2.7 với câu lệnh from __future__ import print_function
.) Đầu ra là giống nhau, theo một trong hai cách.
CPython 2.7.3 trên 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
Vì vậy, cách unpythonic là khoảng 3,6 lần nhanh hơn trong trường hợp này.
Tôi thích cách SO nghiền nát linh hồn ra khỏi câu hỏi bài tập về nhà này để làm cho nó một đẹp một tài liệu tham khảo chung. OP nói "** Tôi không thể sử dụng * numpy ***, tôi phải đi theo cách toán học cho người đi bộ", và câu trả lời hàng đầu "bạn nên thử scipy, nó sử dụng numpy". Cơ học SO cấp huy hiệu vàng cho câu hỏi phổ biến. –
Nikana Reklawyks, đó là một điểm tuyệt vời. Tôi đã có vấn đề đó nhiều hơn và thường xuyên hơn với StackOverflow. Và tôi đã có một số câu hỏi được đánh dấu là "trùng lặp" của một số câu hỏi trước đó, bởi vì những người kiểm duyệt đã không dành thời gian để hiểu những gì làm cho câu hỏi của tôi trở nên độc đáo. – LRK9