Vectors and similarity
Turn things into lists of numbers, measure how far two of them point the same way, and build a tiny search engine with cosine similarity.
FreeAbout 15 min
Movies as arrows
Suppose you score every movie from 0 to 5 on two things: how much action it has and how much comedy. A car-chase thriller might score ; a romantic comedy . Each movie is now a pair of numbers, which you can draw as an arrow from the origin.
A search works the same way. Ask for "mostly action, a bit funny" and your request becomes an arrow too, say . The movies to show you are the ones whose arrows point in nearly the same direction as .
Definition (Vector)
A vector is an ordered list of real numbers , its components. Vectors are columns; to save space we often write them sideways, as in .
Real systems use the same idea with hundreds of components instead of two. A list of numbers that describes a word, a picture or a movie is called an embedding.
Drag the tips of the movies and . Which one points closer to the direction of ?
How long is a vector?
In two dimensions the arrow is the long side of a right triangle with legs and , so by Pythagoras its length is . In three dimensions, applying Pythagoras twice gives . Beyond three dimensions there's no picture to measure, so the same formula becomes the definition.
Definition (Length (L2 norm))
The length, or L2 norm, of is
A vector of length is a unit vector.
For example, the query has length .
Exercise, level: Core
The dot product
Definition (Dot product)
The dot product of multiplies matching components and adds the results:
As a matrix product it's : a row times a column.
The answer is a single number, not a vector. Each of these four rules takes one line to check from the definition (the last one is the definition of length):
| Rule | In symbols |
|---|---|
| Order doesn't matter | |
| It spreads over addition | |
| Numbers pull out | |
| A vector with itself gives its length squared |
Example (By hand)
For the query and the comedy :
What the dot product says about the angle
The dot product is built from components, yet it measures something geometric: the angle between two arrows.
Theorem (Geometric form of the dot product)
Let and be nonzero vectors in or , and let be the angle between them. Then
Proof (by the law of cosines)
The arrows and are two sides of a triangle whose third side is . The law of cosines gives
By the rules in the last step, the left side also expands as
Setting the two right-hand sides equal and cancelling leaves . Divide by .
When the arrows point the same way or opposite ways ( or ) the triangle is flat, but the law of cosines still holds, so the proof covers those cases too.
End of proof.
Lengths are positive, so the sign of the dot product is the sign of :
| Angle | The arrows… | |
|---|---|---|
| positive | less than | lean the same way |
| exactly | are perpendicular (orthogonal) | |
| negative | more than | lean opposite ways |
In more than three dimensions you can't draw the angle, so this formula becomes its definition: . That's only allowed because the right side always lies between and , which is the Cauchy–Schwarz inequality . We state it here without proof; you'll prove it in Linear Algebra for ML.
Exercise, level: Core
Exercise, level: Derivation
Cosine similarity
Divide the dot product by both lengths and only the direction is left.
Definition (Cosine similarity)
The cosine similarity of nonzero vectors is
It lies between (opposite directions) and (the same direction), and it's for orthogonal vectors.
Proposition (Length doesn't matter)
For any number , and have the same cosine similarity as and .
Proof
The numbers pull out of the dot product and out of the length ( for ), so they cancel:
End of proof.
Example (By hand, continued)
For and : , and , so
That's .
Drag the tips. Can you make the dot product ? How close to can you get the cosine similarity? And what happens to it when you make longer without turning it?
Key idea
The dot product measures how much two vectors agree. Dividing by their lengths removes size and leaves only direction: that's cosine similarity.
Exercise, level: Core
By hand: a tiny movie search
Back to the search for "mostly action, a bit funny", . Here are three movies, scored (action, comedy):
Example (Rank the movies)
Movie A is , movie B is and movie C is . The query has length .
- A: and , so . A is exactly : the same direction.
- B: and , as before.
- C: and , so .
| Movie | Dot product with | Cosine similarity |
|---|---|---|
| A | ||
| B | ||
| C |
Cosine similarity ranks A, C, B: A matches the query's taste exactly. The dot product ranks C first, only because C scores high on everything and so has the longest arrow. That's why search uses cosine similarity: it compares what a movie is like, not how much of everything it has.
In code
NumPy writes the dot product as @ and the length as np.linalg.norm. Put the movies in the rows of an array, and movies @ q computes every dot product at once. Press Run:
import numpy as np
q = np.array([2.0, 1.0]) # mostly action, a bit funny
movies = np.array([[4.0, 2.0], # A
[1.0, 3.0], # B
[5.0, 5.0]]) # C
dots = movies @ q
cosines = dots / (np.linalg.norm(movies, axis=1) * np.linalg.norm(q))
print("dot products:", dots)
print("cosine similarities:", cosines.round(3))
print("best match:", "ABC"[np.argmax(cosines)])It prints the numbers from the table: dot products , and , cosine similarities , and , and best match A. Add a fourth movie as another row and run it again.
Search engines with millions of items save work by scaling every embedding to length 1 once, in advance. After that, a plain dot product is the cosine similarity:
import numpy as np
q = np.array([2.0, 1.0])
movies = np.array([[4.0, 2.0], [1.0, 3.0], [5.0, 5.0]])
unit_movies = movies / np.linalg.norm(movies, axis=1, keepdims=True)
unit_q = q / np.linalg.norm(q)
print((unit_movies @ unit_q).round(3)) # the same cosine similaritiesshow(x, y) draws a chart. This one shows how cosine similarity falls as the angle between two vectors grows: from at , through at , to at .
import numpy as np
angles = np.linspace(0, 180, 50) # in degrees
show(angles, np.cos(np.radians(angles)), title="Cosine similarity by angle (degrees)")Where it's used in ML
Tip
Semantic search works exactly like the movie search. A language model turns your question and every document into embeddings with hundreds of components, and the search returns the documents with the highest cosine similarity to your question. Chatbots that look things up before they answer, and "you might also like" recommendations, use the same step.
Exercise, level: Derivation
Exercise, level: Exam
Want the full story, with more proofs and problems? Vectors are the first module of Linear Algebra for ML.
or press Enter