forked from keon/algorithms
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcosine_similarity.py
More file actions
71 lines (51 loc) · 1.58 KB
/
cosine_similarity.py
File metadata and controls
71 lines (51 loc) · 1.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
"""
Cosine Similarity
Calculate the cosine similarity between two vectors, which measures the
cosine of the angle between them. Values range from -1 (opposite) to 1
(identical direction).
Reference: https://en.wikipedia.org/wiki/Cosine_similarity
Complexity:
Time: O(n)
Space: O(1)
"""
from __future__ import annotations
import math
def _l2_distance(vec: list[float]) -> float:
"""Calculate the L2 (Euclidean) norm of a vector.
Args:
vec: Input vector as a list of numbers.
Returns:
The L2 norm of the vector.
"""
norm = 0.0
for element in vec:
norm += element * element
norm = math.sqrt(norm)
return norm
def cosine_similarity(vec1: list[float], vec2: list[float]) -> float:
"""Calculate cosine similarity between two vectors.
Args:
vec1: First vector.
vec2: Second vector (must be same length as vec1).
Returns:
Cosine similarity value between -1 and 1.
Raises:
ValueError: If vectors have different lengths.
Examples:
>>> cosine_similarity([1, 1, 1], [1, 2, -1])
0.4714045207910317
"""
if len(vec1) != len(vec2):
raise ValueError(
"The two vectors must be the same length. Got shape "
+ str(len(vec1))
+ " and "
+ str(len(vec2))
)
norm_a = _l2_distance(vec1)
norm_b = _l2_distance(vec2)
similarity = 0.0
for vec1_element, vec2_element in zip(vec1, vec2, strict=False):
similarity += vec1_element * vec2_element
similarity /= norm_a * norm_b
return similarity