Cosine similarity between all embeddings
Easy10 min10 hidden tests
A help center embeds each of its articles as a vector, and the docs team wants to find near-duplicate articles. Cosine similarity compares two vectors by their angle: 1 when they point the same way, 0 at right angles, -1 when opposite. Write cosine_similarity_matrix(E) that returns the similarity between every pair of rows of E. An article whose embedding is all zeros has no direction, so every similarity with it is 0.
Drag the two vectors
cos = a · b / (|a| |b|)Cosine 0.74 = 5.52 / (2.79 × 2.68). Stretch either vector along its own line and the cosine stays the same.
Angle 42 degrees, cosine 0.74.
Examples
Rows 0 and 2 are at right angles, so their similarity is 0
cosine_similarity_matrix([[1, 0], [1, 1], [0, 2]])
returns [[1, 0.707107, 0], [0.707107, 1, 0.707107], [0, 0.707107, 1]]
Row 1 is all zeros, and rows 0 and 2 point in opposite directions
cosine_similarity_matrix([[3, 4], [0, 0], [-6, -8]])
returns [[1, 0, -1], [0, 0, 0], [-1, 0, 1]]
Requirements
Eis a 2-D list or array of shape (n, d), one embedding per row.- Return a float array of shape (n, n). Entry [i, j] is the dot product of rows i and j divided by the product of their lengths.
- Any entry that involves an all-zero row is 0.0, including that row's own diagonal entry.
- Use array operations instead of a Python loop over pairs.
The idea behind it
An embedding model turns text, images or products into vectors so that similar things land close together. The usual way to compare two embeddings is cosine similarity:
cos(a, b) = a . b / (|a| |b|)
It measures the angle between the vectors and ignores their length. A long document and a short one about the same topic can have very different lengths but point the same way. The result runs from -1 (opposite) through 0 (unrelated, at right angles) to 1 (same direction).
To compare every pair, scale each row to length 1 first. Then the dot product of two unit rows is their cosine, and one matrix product, U @ U.T, gives the whole table. Vector databases do the same thing, and many store vectors already normalized so a dot product is all a query needs. An all-zero vector has no direction, so cosine is undefined for it; returning 0 keeps it from matching anything.
Worked solution
Give it a real try first. Then read the solution and why each line is there.