Looking inside an embedding space
You've trained embeddings. Are they any good? What's actually in them? These questions are harder than they look, because embedding spaces are high-dimensional, and every way of summarizing them (a benchmark number, an analogy, a 2-D picture) throws information away. This section teaches the standard tools and, just as important, how each one can fool you.
Nearest neighbors, the first sanity check
The simplest probe is the one you built in §1.3. For a query word, list the words with the highest cosine similarity. If frog's neighbors are toad, frogs, lizard, salamander, training probably worked. If they're the, of, said, something is broken. Typical causes are missing subsampling, too few epochs, a forgotten scatter-add, or comparing raw dot products instead of cosines.
Neighbors are qualitative, but they catch most bugs, and they reveal what kind of similarity your setup learned, substitutable words or merely associated ones (§1.4).
Intrinsic evaluation asks whether cosines agree with people
Similarity benchmarks give word pairs rated by humans, such as (tiger, cat) = 7.35 or (king, cabbage) = 0.23 on a 0 to 10 scale. We compute the cosine for each pair and measure how well the two rankings agree, using Spearman's rank correlation ,
where is the ordinary Pearson correlation. In plain words, replace every score by its position in sorted order, then ask how linearly related the two lists of positions are. Ranks, not raw values, because human scales and cosine scales aren't comparable. Only the order matters, so any monotone transformation of the cosines leaves unchanged.
When there are no ties, has a closed form in terms of the rank differences over pairs, . A worked example with four pairs. Humans give and the model gives cosines . The human ranks (lowest is 1) are , the model ranks are , the differences are , and . The model swapped the top two pairs and got everything else right.
Common benchmarks are WordSim-353 (Finkelstein et al., 2002), MEN (Bruni et al., 2014), and SimLex-999 (Hill et al., 2015).
Extrinsic evaluation plugs the embeddings into a real task (sentiment classification, named-entity recognition, retrieval) and measures task performance. That's what ultimately matters, and intrinsic scores don't always predict it. Chiu, Korhonen and Pyysalo (2016) found that word-similarity scores correlated poorly, and sometimes negatively, with performance on downstream tagging tasks.
Spearman correlation from scratch (with ties)
Implement spearman(x, y) without SciPy. Convert each array to ranks, giving tied values the average of their ranks (values [10, 20, 20, 30] get ranks [1, 2.5, 2.5, 4]), then return the Pearson correlation of the ranks. (The closed form with is only valid without ties, which is why we don't use it here.)
Analogies, the famous trick and its fine print
The result that made word2vec famous is
The analogy a is to b as c is to ? ("man is to king as woman is to ?") is answered by the word whose vector is most similar to . With unit vectors, this 3CosAdd rule is
(The second form holds because, for unit vectors, the cosine with the target is the dot product with it divided by the target's length, which is the same for every candidate .) In plain words, find the word that is similar to king and woman, and dissimilar to man.
A worked example with five hand-made 3-D vectors, the same ones the exercise uses. They are man , woman , king , queen , apple . After normalizing, the target is about . Its cosines with the five words are man , woman , king , queen , apple . Queen wins here even without excluding the inputs, but notice how close woman comes. In real embedding spaces the input word usually wins.
Geometrically, this works when a relation (male to female, country to capital, verb to past tense) corresponds to a roughly constant offset vector. Why would training produce such offsets? Here is a heuristic explanation via PMI (§1.5). If king and queen differ in their co-occurrence statistics in the same way that man and woman do (more he and his versus more she and her), then because , the vector differences align. Allen and Hospedales (2019) make this argument precise under explicit assumptions.
Analogies with 3CosAdd and 3CosMul
Implement analogy(E, vocab, a, b, c, method="add", exclude=True) that returns the answer word for a is to b as c is to ?. E has one (not necessarily normalized) row per word in vocab. For "mul", shift cosines to with and use . When exclude=True, never return , , or .
The tests use a hand-built space where 3CosAdd and 3CosMul disagree.
Analogy accuracy over a whole benchmark, with no loops
Benchmarks like the Google analogy set have about 19,500 questions, and a loop over them in Python is slow. Implement analogy_accuracy(E, quads, method="add") where quads is an (Q, 4) int array of rows (a, b, c, d) meaning "a is to b as c is to d". Predict every answer at once with one (Q, V) score matrix, exclude each question's own a, b, c, and return (accuracy, predictions).
Looking at the space by projecting to 2-D
We can't see 300 dimensions, so we project to 2 (or 3). The methods differ in what they choose to keep, and that determines what they distort.
PCA, the best flat shadow
Principal component analysis finds the orthogonal directions of maximum variance and projects onto the top two. With centered data (rows are words, the mean row subtracted) and SVD , the 2-D coordinates are . That's the same Eckart–Young optimality as §1.4, the best rank-2 approximation in squared error. The fraction of variance kept is
where are the singular values of the centered data. In plain words, each squared singular value is the variance along one principal direction (times the number of rows), so this ratio is the share of the total spread that the picture shows.
PCA is linear and faithful in one specific sense. Distances in the picture are never larger than the real ones, because an orthogonal projection can only shrink vectors. Large-scale structure (which clusters are far apart) is preserved as well as two dimensions allow. Its weakness is that if the top two directions only explain, say, 15% of the variance, most of the structure is invisible, and distinct groups can land on top of each other. Centering matters too. Without it, the first "component" mostly points at the mean vector, which for anisotropic embeddings (§1.9) is a large shared offset that says nothing about differences between words.
PCA from the SVD
Implement pca(X, k) returning (Z, components, explained), where components is (k, d) with orthonormal rows (the top principal directions), Z = (X - mean) @ components.T is (n, k), and explained is the (k,) fraction of variance along each component. Make the signs deterministic by flipping each component so that its largest-magnitude entry is positive.
t-SNE keeps the neighbors and sacrifices everything else
t-SNE (van der Maaten & Hinton, 2008) doesn't try to preserve distances at all. It tries to preserve who is near whom, in three steps.
- In the original space, turn distances into neighbor probabilities, , normalized over . The precision (written in the paper) is tuned per point so the distribution has a fixed perplexity , where is the entropy in bits. Perplexity is roughly "the effective number of neighbors" (§0.5 explains why). Then symmetrize, , where is the number of points.
- In 2-D, use a heavy-tailed Student-t kernel, , normalized over all pairs.
- Move the 2-D points to minimize , by gradient descent with gradient
In plain words, pairs that are neighbors in the original space but too far apart in the picture () attract, pairs that are too close repel, and the force is damped for points that are already far apart.
The heavy tail solves the crowding problem. There isn't enough room in 2-D to place all of a point's moderately distant neighbors at faithful distances, so the t-kernel lets non-neighbors be pushed far away. That's what makes t-SNE clusters look so crisp. It also means sizes and gaps in a t-SNE plot are not to be trusted. Because each adapts to local density, a tight cluster and a diffuse one come out about the same size.
t-SNE input affinities with perplexity calibration
The first step of t-SNE is a nice interview problem, because it combines numerics and a search. Implement tsne_affinities(X, perplexity) returning (P_cond, P). P_cond is the (n, n) matrix of (rows sum to 1, zero diagonal) with each row's precision found by bisection so that its perplexity matches the target to within 0.1%. P is the symmetrized joint matrix . Do the bisection for all rows at once (vectorized), not row by row.
The tests also check that scaling the data by 10 leaves P_cond unchanged. Perplexity is defined on the shape of the distribution, so the precisions must absorb the scale.
Wattenberg, Viégas and Johnson (2016) collected the lessons of reading t-SNE plots. Run the next cell to see three of them on synthetic data where we know the truth.
Here is what to notice.
- Cluster sizes mean nothing. Blue is 10 times tighter than orange in reality, but t-SNE draws them about the same size, because it adapts its precision to local density.
- Distances between clusters may mean nothing. The gap from blue to green (about 134 in the original space) is 10 times the gap from blue to orange (about 13), but t-SNE doesn't show that reliably.
- Hyperparameters change the story. Perplexity changes the picture, sometimes completely.
UMAP
UMAP (McInnes, Healy & Melville, 2018) builds a weighted -nearest-neighbor graph, treats it as a fuzzy topological structure, and optimizes a 2-D layout whose graph matches it, using a cross-entropy loss and negative sampling (the same trick as §1.5). It's much faster than exact t-SNE, scales to millions of points, and is often said to preserve more global structure. But Kobak and Linderman (2021) showed that much of that difference comes from initialization. Both methods preserve global structure better when initialized with PCA. The same warnings apply. n_neighbors and min_dist change the picture, and sizes and gaps are unreliable.
| method | preserves | distorts | use it for |
|---|---|---|---|
| PCA | global variance, linear structure | everything beyond the top 2 directions | first look, honest overview, checking scale |
| t-SNE | local neighborhoods | cluster sizes, inter-cluster distances, density | finding local groups, spotting outliers |
| UMAP | local neighborhoods (plus some global with good init) | sizes, distances, density | the same as t-SNE, at scale |
Quantify how much a 2-D picture lies
Here is a principled check for any projection. For each point, what fraction of its nearest neighbors in the original space are also among its nearest neighbors in the projection? Implement knn_preservation(X, Y, k) returning the average overlap in , using Euclidean distance in both spaces and excluding each point itself. Vectorize the distance computations (reuse the trick from Exercise 1.1d).
Then, optionally, use it to compare PCA and t-SNE on the data in the cell above for . For structureless data the overlap of a random picture is about , which gives you a baseline to beat.
In PyTorch and the ecosystem
PCA is a few lines of linear algebra, so it runs in PyTorch directly, on the GPU if you like.
For t-SNE and UMAP, use the standard libraries rather than writing your own optimizer.
Read more
- Hill, Reichart & Korhonen (2015). SimLex-999. Similarity versus relatedness.
- Chiu, Korhonen & Pyysalo (2016). Intrinsic Evaluation of Word Vectors Fails to Predict Extrinsic Performance. Why benchmark scores are not the whole story.
- Levy & Goldberg (2014). Linguistic Regularities in Sparse and Explicit Word Representations. 3CosMul.
- Linzen (2016), Issues in evaluating semantic spaces using word analogies, and Nissim et al. (2020), Fair Is Better than Sensational. The fine print on analogies.
- van der Maaten & Hinton (2008). Visualizing Data using t-SNE. The original paper, including the crowding problem.
- Wattenberg, Viégas & Johnson (2016). How to Use t-SNE Effectively. Interactive lessons on reading t-SNE.
- Kobak & Linderman (2021). Initialization is critical for preserving global data structure in both t-SNE and UMAP.
- Coenen & Pearce. Understanding UMAP. A visual explainer from Google PAIR.