Embeddings

core 9 minrepresentationembeddingsnlp

Builds on:Dot product, norms, and similarity

The idea

Neural networks compute with continuous vectors, but much of the world is discrete: words, users, products, categories. The naive encoding — one-hot vectors — is dimension-bloated (one axis per item) and, worse, geometry-free: every pair of one-hots is orthogonal, so cat is exactly as far from dog as from carburetor, and nothing learned about one item can transfer to a similar one.

An embedding replaces each item with a learned dense vector of modest dimension (dd from tens to a few thousand), stored as rows of a matrix E∈RV×dE \in \mathbb{R}^{V \times d}. "Looking up an embedding" is just indexing row ii (equivalently, multiplying a one-hot by EE). The rows are ordinary parameters, trained by backprop against whatever loss the model has.

The magic is why geometry emerges: the loss can only fall if items that behave similarly under the training objective — words in similar contexts, products bought by similar users — get vectors the rest of the network can treat similarly, i.e. nearby vectors. Nobody assigns meaning to axes; similar usage → similar vectors is an optimization consequence. word2vec made this famous with pure self-supervision (skip-gram: predict context words from the center word), yielding geometry clean enough that king−man+womanking - man + woman lands nearest queen.

Similarity is measured with cosine,

cos⁡(u,v)=u⋅v∥u∥ ∥v∥∈[−1,1]\cos(u, v) = \frac{u \cdot v}{\lVert u \rVert\, \lVert v \rVert} \in [-1, 1]

when only direction should matter (norms often encode frequency), or the raw dot product when magnitude is genuine signal. Two generational upgrades to know: static → contextual (a transformer encoder gives each token a vector that depends on its sentence, splitting the senses of "bank"), and word → sentence/document embeddings (pooled contextual vectors trained contrastively), which power semantic search and retrieval-augmented generation.

Dot product
5.40
Cosine similarity
0.66
Angle
49°

Drag either vector: stretching one along its own direction moves the dot product but leaves cosine similarity unchanged — magnitude is nuisance, alignment is signal.

Worked example

Toy 2-d embeddings: cat=(0.9,0.2)\mathit{cat} = (0.9, 0.2), dog=(0.85,0.3)\mathit{dog} = (0.85, 0.3), car=(0.1,0.95)\mathit{car} = (0.1, 0.95).

For cat versus dog:

cat⋅dog=0.9⋅0.85+0.2⋅0.3=0.825,∥cat∥=0.85≈0.922,∥dog∥=0.8125≈0.901,cos⁡(cat,dog)=0.8250.922×0.901≈0.99.\begin{aligned} \mathit{cat}\cdot\mathit{dog} &= 0.9\cdot0.85 + 0.2\cdot0.3 = 0.825, \\ \lVert\mathit{cat}\rVert &= \sqrt{0.85} \approx 0.922, \\ \lVert\mathit{dog}\rVert &= \sqrt{0.8125} \approx 0.901, \\ \cos(\mathit{cat},\mathit{dog}) &= \frac{0.825}{0.922\times0.901} \approx 0.99. \end{aligned}

Cosine of cat vs car: dot =0.09+0.19=0.28= 0.09 + 0.19 = 0.28, ∥car∥≈0.955\lVert \mathit{car} \rVert \approx 0.955, giving 0.28/(0.922×0.955)≈0.320.28 / (0.922 \times 0.955) \approx 0.32. The animals are nearly parallel (0.99); animal-vs-vehicle is weakly related (0.32). Distances now mean something — the entire point, in two dimensions.

And that is already a retrieval system: given the query cat, ranking all other vectors by cosine returns dog first and car last. Semantic search over a million documents is this exact computation with dd in the hundreds and an approximate nearest-neighbor index (HNSW, IVF) standing in for the brute-force scan once exhaustive comparison gets too slow.

Scale check for real systems: a 50k-word vocabulary at d=768d = 768 is a 50,000×76850{,}000 \times 768 table ≈ 38.4M parameters — often the largest single layer in a small model, and the reason embedding tables get tied between input and output, quantized, or hashed in production recsys.

Cheat sheet

Gotchas