Dot product
Rank documents by dot product, cosine and L2 distance and explain the role of normalization and model choice.
THE IDEA
Dot product as a score
The dot product q·d multiplies matching coordinates and adds them. It grows with how well d is aligned with q and with the length of d. Many retrieval models are trained to be used with a dot product, so the length can carry useful information. But if lengths vary for reasons that have nothing to do with relevance, they change the ranking.
| document | vector | dot product with q | rank |
|---|---|---|---|
| A | [1, 0] | 1 | 2 |
| B | [7.07, 7.07] | 7.071 | 1 |
The defaults are the chapter's example: q = [1, 0], A = [1, 0], B = [10, 10] (length 14.1 at 45°). B ranks first although it points 45° away: its length wins.
Predict first. Does doubling a document vector double its dot product with a fixed query?
Chapter context
Semantic search represents queries and documents as vectors in a compatible space. Good retrieval depends on the encoder, its training objective and the candidate data; choosing a distance formula alone does not create semantic relevance.
TRY IT YOURSELF
Part 1. Do it hands-on
Rank the two documents by dot product, then write ranking code and detect when scaling flips it.
| document | vector | dot product with q | rank |
|---|---|---|---|
| A | [1, 0] | 1 | 2 |
| B | [7.07, 7.07] | 7.071 | 1 |
The defaults are the chapter's example: q = [1, 0], A = [1, 0], B = [10, 10] (length 14.1 at 45°). B ranks first although it points 45° away: its length wins.
- To do: Query q = [1, 0], documents A = [1, 0] and B = [10, 10]. Dot product q·A?
- To do: q·B?
- To do: Which document ranks first by dot product? Type A or B
- To do: If document A's vector is doubled to [2, 0], what is q·A now?
Part 2. Do it in code
- dot_scores(q, docs): the dot product of the query with every document row (docs is a 2-D array).
- rank_by_dot(q, docs, k=None): indices sorted by dot product, best first (ties: lower index first); only the first k if k is given.
- scale_doc(docs, i, factor): a copy of docs with row i multiplied by factor.
- magnitude_flips_ranking(q, docs, i, factor): True if scaling row i by `factor` changes the order of rank_by_dot.
Stuck, or something not working? You can come back to it any time.
CHECK YOUR UNDERSTANDING
Does doubling a document vector double its dot product with a fixed query?
Chapter reference: math, worked example & code
This section belongs to the whole chapter, so it is the same on every lesson in it and may cover a different lesson's topic. The code for the experiment you just ran is inside the experiment itself.
Math and notation
For unit-normalized vectors, squared L2 is , so their rankings agree under the appropriate direction. Zero vectors require a defined handling policy.
Worked example
Let q=[1,0], A=[1,0] and B=[10,10]. Raw dot products are 1 and 10, so B ranks first by dot product. Cosines are 1 and 1/sqrt(2), so A ranks first by cosine. This is a deliberate example of magnitude changing the retrieval objective.
Reference code
The following example uses the Python standard library and does not call a remote service.
from math import sqrt,isclose
q,a,b=[1,0],[1,0],[10,10]
dot=lambda u,v: sum(x*y for x,y in zip(u,v))
norm=lambda u: sqrt(dot(u,u))
assert dot(q,b) > dot(q,a)
assert dot(q,a)/(norm(q)*norm(a)) > dot(q,b)/(norm(q)*norm(b))
assert isclose(dot(q,b)/(norm(q)*norm(b)),1/sqrt(2))
assert 128*4 == 512
Python examples are provided for study and local execution; this page does not execute Python.
Common mistakes
Do not mix embedding spaces or metric directions. Normalize only when it matches the model and search objective. Similarity is not factual verification.