Definition
cos(a, b) = (a · b) / (||a|| ||b||)
The result is 1 when the vectors point in the same direction, 0 when they are perpendicular, and −1 when they point in opposite directions. In many text and embedding systems vectors are nonnegative or normalized, so observed values may fall in a narrower range.
Worked example
Let (a=[3,2,0]) and (b=[30,20,0]). Since (b=10a), they point in exactly the same direction and their cosine similarity is 1. For (c=[0,1,5]), the dot product with (a) is 2; dividing by the vector lengths gives about 0.11. The latter shares little direction with (a).
This differs from Euclidean distance: (a) and (b) are far apart in length even though their directions match. Cosine is therefore useful for comparing document vectors when document length should not dominate. If magnitude itself carries meaning, cosine can discard useful information.
Explore the vectors
Choose Parallel, 90°, or Opposite in the visualizer and watch the angle and similarity change. Then scale one vector without changing its direction: the cosine remains constant. The demonstration makes the geometry visible; it does not imply that a high embedding similarity proves two texts mean the same thing.
Where it helps and where it fails
- Search and retrieval: rank document embeddings by similarity to a query, then evaluate whether the retrieved passages answer the query.
- Recommendations: compare user and item vectors when relative feature direction is meaningful.
- Clustering: cosine distance (
1 - similarity) can group vectors by orientation. - Zero vectors: the formula is undefined if either vector has length zero; define a handling rule or use a library implementation that handles this case.
- Meaning: similarity depends on how vectors were built and the dataset. A score is a ranking signal, not a universal semantic probability.
from sklearn.metrics.pairwise import cosine_similarity
scores = cosine_similarity([[3, 2, 0]], [[30, 20, 0], [0, 1, 5]])
print(scores) # [[1. 0.108...]]