FromZero2AI
CoursesPlaygroundBlog
Support on Ko-fi
Embeddings & Vector Databases • Module B: Vector DatabasesLesson 5: Similarity Search: ANN & Distance Metrics
PreviousNext

Lesson 5: Similarity Search: ANN & Distance Metrics

Explore cosine similarity, dot product, and Euclidean distance. Understand why Approximate Nearest Neighbor (ANN) search is essential at scale.

Built with AI for beginners. Free forever.

Support on Ko-fi•About•Blog•Privacy Policy•Terms of Service

Semantic search is only as good as its distance metric. The way you measure “how close” two vectors are determines what your retrieval system considers similar — and the wrong choice produces subtly wrong results that are hard to debug.

The Three Distance Metrics

All modern vector databases support three distance metrics. Understanding when each applies will save you hours of debugging mysterious retrieval failures.

Cosine Similarity

(A · B) / (‖A‖ × ‖B‖)

Range: −1 to 1 (higher = more similar)

Measures the angle between two vectors, ignoring their magnitude. A document with 1,000 words and one with 5 words about the same topic will score ~1.0.

Best for: General-purpose text retrieval, RAG pipelines, normalized embeddings

A Worked Example: Why Magnitude Matters

Consider three 2D vectors (simplified for illustration). In the real world, these would be 1,536-dimensional, but the math is identical:

A = [0.6, 0.8] — a short document about AI

B = [0.8, 0.6] — a different short document about AI

C = [6.0, 8.0] — a very long document about AI (A × 10)

PairCosineDot ProductEuclidean
A vs B (same length, similar topic)0.96000.96000.2828
A vs C (same direction, C is 10× longer)1.000010.00009.0000

Cosine similarity correctly identifies that A and C point in the same direction(score 1.0000) even though C is 10× larger. Dot product ranks C much higher than B, even though they're about equally relevant — the length difference is inflating the score.

ANN: Why Exact Search Doesn't Scale

Finding the exact nearest neighbor requires computing the distance from the query to every vector in the index — O(n × d) where n is the number of vectors and d is the dimension. At 10M vectors × 1536 dims, that is 15.36 billion multiply-add operations per query. Even on a GPU, this takes seconds.

Approximate Nearest Neighbor (ANN)algorithms build an index that lets you skip most comparisons. The most popular algorithm, HNSW, typically achieves >95% recall at 1-10ms query time — covered in depth in the next lesson.

Configuring ChromaDB for the Right Metric

import chromadb

client = chromadb.PersistentClient(path="./db")

# IMPORTANT: set the metric at collection creation time — it cannot be changed later
cosine_collection = client.get_or_create_collection(
    name="rag_docs",
    metadata={"hnsw:space": "cosine"},     # Most common for text
)

dot_collection = client.get_or_create_collection(
    name="recommendations",
    metadata={"hnsw:space": "ip"},         # Inner product (dot product)
)

l2_collection = client.get_or_create_collection(
    name="image_search",
    metadata={"hnsw:space": "l2"},         # Euclidean distance
)

The Normalization Shortcut

If you L2-normalize all your vectors before storing them (so each has unit length, i.e. ‖v‖ = 1), then dot product and cosine similarity become equivalent. This is why many providers return pre-normalized vectors — you can use the faster dot product operation and still get cosine semantics.

import numpy as np

def normalize(vec: list[float]) -> list[float]:
    v = np.array(vec)
    return (v / np.linalg.norm(v)).tolist()

# After normalization, dot product == cosine similarity
vec_a = normalize([0.6, 0.8])
vec_b = normalize([0.8, 0.6])

dot = sum(a * b for a, b in zip(vec_a, vec_b))
cos = cosine_similarity(vec_a, vec_b)

print(f"dot:    {dot:.6f}")  # → 0.960000
print(f"cosine: {cos:.6f}")  # → 0.960000  (identical!)

Coding Tasks — Complete in the editor

  • [ ]Implement cosine_similarity, dot_product, and euclidean_distance from scratch using NumPy.
  • [ ]Verify: for two unit-normalized vectors, show that dot product equals cosine similarity to 6 decimal places.
  • [ ]Create a ChromaDB collection with hnsw:space: cosine, add 5 documents, and run a query that returns the top 3 results with distances printed.

Next: how HNSW actually builds the graph index that makes ANN search fast — and what parameters control the speed vs. recall trade-off.