Measuring similarity: cosine, dot product, distance
Search ranks vectors by a score. The three common scores are cosine similarity, dot product and Euclidean distance.
Dot product and cosine similarity
a · b = 3.86 | cosine = 0.64
Partly aligned. Lengths: a = 3, b = 2.
Words on this page (5)
- vector
- : An ordered list of numbers. Embeddings and model activations are vectors.
- cosine similarity
- : A score from -1 to 1 for how much two vectors point the same way, ignoring their length.
- dot product
- : Multiply matching entries of two vectors and add them up. Large when they point the same way.
- embedding
- : A list of numbers that represents the meaning of a piece of text or an image, so similar things sit close together.
- recommender
- : A system that suggests items such as videos or products to each user.
The scores
multiplies matching entries and adds them. It grows with both direction match and length. divides out the lengths, so only direction counts, from -1 to 1. Euclidean distance is the straight-line distance between the two points: the square root of the sum of squared differences. Smaller means closer.
Example
a = [3, 4], b = [6, 8], c = [4, -3]. Dot a·b = 18 + 32 = 50. Cosine a,b = 50 / (5 × 10) = 1: same direction. Euclidean a,b = √(9 + 16) = 5: they differ in length. Dot a·c = 12 - 12 = 0, cosine 0: unrelated.
Which to use
Most text models are trained for cosine similarity or produce vectors of length 1, in which case dot product and cosine give the same ranking. Use the metric the model's documentation recommends. If you normalize vectors to length 1, all three metrics give the same ordering.
A worked example: why cosine ignores length
a = [1, 2] and b = [10, 20]. They point the same way, b is just ten times longer. Dot product: 1×10 + 2×20 = 50, large. Cosine: 50 / (√5 × √500) = 50 / 50 = 1, a perfect match. Euclidean distance: √(81 + 324) = 20.1, far apart. For comparing meaning you usually want cosine, so a long document is not penalized or favored for its length.
A third example: when length is a feature
Some systems learn vectors where a longer vector means a more popular item. Take a user u = [1, 1] and two items p = [2, 2] and q = [1, 1]. Dot product: u·p = 2 + 2 = 4 and u·q = 1 + 1 = 2, so p ranks first. Cosine is 1 for both, a tie. Here the dot product is what you want, because the model deliberately stored popularity in the length. The metric must match how the vectors were trained.
What goes wrong
Suppose your vectors are not normalized and you rank with the dot product. Use query [1, 1], item x = [10, 0] and item y = [1, 1.2]. Dot product: x scores 10 and y scores 2.2, so x wins. Cosine: x is 10 / (10 × 1.414) = 0.71 and y is 2.2 / (1.414 × 1.562) = 0.996. Item y points almost exactly where the query points, yet x wins on length alone.
The symptom is results that feel off-topic but oddly confident, often the same items with the longest vectors showing up for many queries. Most text-embedding models return unit-length vectors, so this applies when yours do not. To confirm, compute the length of 100 stored vectors. If the lengths vary a lot and you use the dot product, length is steering the ranking.
Reading the scores
A cosine score has no universal meaning. 0.8 can be a strong match with one model and a weak one with another. Do not copy a cutoff such as "keep results above 0.75" from a blog post. Look at the scores for 20 of your own queries, mark which results were right, and pick a cutoff from that.
Try it yourself
In a spreadsheet, enter the vectors a = [1, 2], b = [10, 20] and c = [2, 1]. Compute dot product, cosine and Euclidean distance for a against b and a against c. You should find that cosine says b is a perfect match for a (1.0) and c is 0.8, while Euclidean distance says c is closer. Check: a·c = 2 + 2 = 4, and 4 / (√5 × √5) = 0.8. Seeing the two metrics disagree on the same data explains why the choice matters.
Common mistake
Mixing metrics between indexing and querying.
A map app can measure "as the crow flies" or "by road". Both are distances, but they answer different questions. Vector search also has more than one way to say two things are close: by angle (cosine), by multiply-and-add (dot product), or by straight-line distance (Euclidean).
Check yourself
a = [3, 4] and b = [6, 8]. What is their cosine similarity?
Not quite. They point the same way, so cosine is 1 even though b is longer.
After normalizing all vectors to length 1, how do cosine and dot product rank results?
Not quite. With unit lengths the dot product equals cosine.
You index with cosine but query with Euclidean distance. What is the problem?
Not quite. Use the same metric for indexing and querying, as the model recommends.
You got 0 of 3 right.
Go deeper
- Video
3Blue1Brown · Why the dot product measures alignment.
- ArticleVector similarity explainedArticle
Pinecone · Compares the three metrics with diagrams.
- Docs
NumPy · Compute vector lengths for normalizing.
Spotted a mistake or something unclear? Report it on GitHub.