EmbeddingsGENERALSIMULATED

Embedding Projection Caveats

A 2D plot of high-dimensional vectors is a lossy projection. PCA keeps variance, not neighbourhoods; t-SNE and UMAP keep local structure and invent global structure. The clusters, distances and neighbours in the picture are not the ones the model uses.

The problem, the obvious approach, and why it breaks

Every lesson starts where the work starts: someone has a problem, and the first model that comes to mind looks fine offline.

The question

The projection shows two clean clusters and a stakeholder wants to act on them. What does the plot preserve from the space the model actually computes in, and what did it make up?

The problem

A growth team projected user embeddings to 2D, saw a tight cluster far from the main mass, labelled it "dormant users", and designed a re-engagement campaign for it. The campaign performed at baseline: the users in the cluster behaved no differently from users outside it, and the model's own nearest neighbours for a "dormant" user were mostly in the main mass.

The obvious approach

Reduce the vectors to two dimensions with PCA, t-SNE or UMAP and plot them. Clusters in the plot are clusters in the data; distance in the plot is dissimilarity; the plot is a faithful map of the embedding space at a lower resolution.

Why it breaks

The "dormant" cluster was an artefact of the projection: t-SNE produces tight, well-separated blobs from many kinds of structure, including near-uniform data, and the distance between blobs carries no information about the distance between the groups in the full space.

How it breaks — usually after the offline metric looked fine
  • The "dormant" cluster was an artefact of the projection: t-SNE produces tight, well-separated blobs from many kinds of structure, including near-uniform data, and the distance between blobs carries no information about the distance between the groups in the full space.
  • Membership in the visual cluster and membership in the model's neighbourhood disagreed for most users. The campaign targeted a set the plot invented, and the model's actual notion of "users like this one" was never consulted.
  • The stakeholder trusted the picture more than the metric because it was a picture. A second projection with a different seed showed different clusters, which should have ended the discussion and instead was taken as "the data is noisy".
ProblemTargetDataRepresentationSplitModelTrainingEvaluationValidationDeploymentInferenceMonitoringDriftRetraining

What is being predicted, and from what data

This domain leads with these two. A target nobody defined precisely is a label nobody can trust, and a dataset nobody can describe is a model nobody can debug.

Target
  • The projection has no target of its own; it is a picture. The question it was used to answer — which users form a behavioural segment the model distinguishes — is a question about neighbourhoods in the full space, which the projection did not preserve.
  • The surrounding model predicts next-session activity; its geometry is defined in its full dimensionality and is what the campaign should have been designed against.
Data
  • User embedding rows of several dozen dimensions from a next-activity model. Pairwise distances among them are meaningful only in the full space; the projection was computed once, on a sample, and the picture was screenshotted into a deck.
  • The projection method was t-SNE with default parameters; nobody recorded the seed or the perplexity, and a re-run produced a different picture.

How it actually works

Precisely enough to predict its behaviour — not a framework API.

  • PCA rotates the space and keeps the two directions of highest variance. It is linear and deterministic, distances along the kept axes are real, and everything in the other dimensions is collapsed. Two points far apart in a dropped direction land on top of each other, so PCA preserves global shape roughly and neighbourhoods badly, and the fraction of variance in the kept axes says how much was thrown away (Dimensionality Reduction).
  • t-SNE and UMAP optimise a layout so that each point's near neighbours in the full space are near it in the plane. They are non-linear, stochastic and local: within a blob, neighbours are roughly right; between blobs, the distances and the relative sizes are artefacts of the optimisation and its parameters. Both methods make blobs out of continuous data, and both change with the seed and with perplexity or the neighbour count.
  • A projection cannot preserve pairwise distances from many dimensions to two — the Johnson–Lindenstrauss argument gives the number of dimensions needed to preserve them approximately, and two is far below it for any realistic set. So every projection is a choice of what to keep: variance, local neighbourhoods, or global shape, never all three.
  • The lab at /ml/embeddings makes this measurable: it computes each vector's nearest neighbours in the full space and in the 2D projection and reports the agreement. On the small, clean vocabulary it ships with, the neighbours already disagree for several entities; on real data of higher dimension the disagreement is larger.

What each method keeps, and what it invents

The three common methods answer different questions and none of them answers "what does the space look like". The table is the thing to have in mind when a plot arrives in a deck.

MethodPreservesDistorts or inventsDeterministicRead distances between groups?
PCAGlobal variance along two directions; distances along those axesEverything in the dropped dimensions; neighbourhoods that differ only thereYesOnly along the kept axes, and only as much as the explained variance allows
t-SNELocal neighbourhoods within a blob, approximatelyBlob sizes, inter-blob distances, the existence of blobs in continuous dataNo — seed and perplexity change the pictureNo
UMAPLocal neighbourhoods, some coarse global arrangementBlob density and separation; sensitive to neighbour count and min-distanceNo — seed and parameters change the pictureNot reliably

The neighbours the plot shows are not the model's

The check the lab performs is the one every plot should carry. For each entity, take its nearest neighbours by the model's similarity in the full space, take its nearest neighbours by distance in the plane, and count the overlap. An agreement of one means the plot is faithful for that entity; anything less is the fraction of the entity's visual neighbourhood that the model does not share.

On real embeddings of hundreds of dimensions the agreement is typically low for most entities and the distribution is wide; the entities with the lowest agreement are often the ones on which the eye is drawn to a conclusion, because they landed in a striking place.

Neighbour agreement between the full space and the plane
1import numpy as np
2
3def knn(X, k, metric):
4 # X: [n, d]; returns the k nearest indices per row under the metric
5 if metric == "cosine":
6 Xn = X / np.linalg.norm(X, axis=1, keepdims=True)
7 d = -(Xn @ Xn.T) # larger cosine = smaller "distance"
8 else:
9 sq = (X ** 2).sum(axis=1)
10 d = sq[:, None] + sq[None, :] - 2 * X @ X.T
11 np.fill_diagonal(d, np.inf)
12 return np.argsort(d, axis=1)[:, :k]
13
14def neighbour_agreement(full, projected, k=5):
15 a = knn(full, k, "cosine") # what the model uses
16 b = knn(projected, k, "euclid") # what the plot shows
17 return np.array([len(set(a[i]) & set(b[i])) / k for i in range(len(full))])
18
19# report the mean and the minimum with every plot; the minimum is where the eye will go

The metric differs between the two calls on purpose: the model ranks by cosine in the full space; the reader's eye ranks by Euclidean distance on the page. The agreement measures the gap between those two rankings, which is the gap between the picture and the model.

A segment the picture invented

The campaign was designed against a set of users that existed only in the projection. Offline, nothing was wrong: the projection did what its objective says, and no metric was computed on the segment because the plot had already been convincing.

Re-engagement campaign on a visual cluster
offline evaluation said

A t-SNE plot of user embeddings with one tight, well-separated blob; the blob labelled "dormant" by inspection of a few members; no segment-level outcome measured.

production did

Campaign response inside the "segment" indistinguishable from a random sample of users; the model's own nearest neighbours for segment members were mostly outside the segment.

What explains the gap — most likely first
  1. 1The blob is an artefact of t-SNE's objective and parameters; a re-run with a different seed places different users in it.
  2. 2Membership was defined by position in the plane, which preserves at best the local neighbourhoods of some points and not the global grouping the campaign assumed.
  3. 3The users who genuinely resemble each other under the model are spread through the main mass, where the plot had nothing to show.
what it costs to close or detect Detecting it costs a neighbour-agreement computation on the plotted sample and a held-out outcome comparison on the proposed segment defined in the full space — both cheap, both skipped because the picture was persuasive. Closing it costs the credibility of the plot as an argument, which is the point.

How to build it

Most important first.

  • Use projections to form hypotheses and never to define segments or act. Any structure seen in the plot is tested in the full space: neighbour overlap, a clustering run on the full vectors, or the downstream metric on the proposed segment (Clustering).
  • Report the projection's fidelity with the plot: explained variance for PCA, neighbour-agreement at a small k for any method, and the seed and parameters, so the picture can be reproduced and its distortion quantified.
  • When a segment is the goal, define it in the full space with the model's own similarity, and evaluate it on the outcome the segment is supposed to predict, before drawing anything.
  • Show more than one projection — different seeds, different methods — when the audience is going to act on it. Structure that survives all of them is more likely to be real; structure that appears in one is the method's.

What to measure

Which number actually maps to the decision — and which numbers look relevant and are not.

  • Neighbour agreement between the full space and the projection at a small k, per entity and on average. This is the number that says whether the plot's neighbours are the model's; it is exactly what the lab computes.
  • For a proposed segment, the downstream outcome rate inside versus outside the segment, defined in the full space, on held-out users. That is the number the campaign was about and it was never computed.
  • Do not measure a segment by how separated it looks in the plot. Visual separation is a property of the projection and its parameters.

What must stay true after deployment

The field this whole domain exists for. A model is a set of assumptions with weights attached; these are the ones a monitor or a test should be checking.

Assumptions
  • Nothing operational — no segment, no campaign, no threshold — is defined from the projected coordinates; all definitions live in the full space.
  • Any projection shown to decision-makers carries its neighbour-agreement or explained-variance figure and its parameters, so the distortion is visible next to the picture.
  • Structure that is acted on has been confirmed in the full space on held-out data, not inferred from visual separation.
How to verify — offline, online, and over time
  • Offline: for every plot, compute neighbour agreement at a small k between the full space and the projection, and explained variance for PCA; record both with the figure.
  • Before acting: define the candidate segment in the full space and test the outcome difference on held-out users, with uncertainty (Metric Uncertainty).
  • Over time: if a projection is used as a monitoring view, re-fit it on a fixed reference sample and track the neighbour agreement; a drop means the space has moved, not that the plot is wrong.

What can go wrong

Failure modes in production
  • The neighbour-agreement check is run on the sample used to fit the projection and looks acceptable; new points projected afterwards land in wrong regions because the layout was fitted to the old ones.
  • PCA is chosen "because it is deterministic" and the first two components explain a small fraction of the variance; the plot is faithful to a plane that contains almost none of the structure.
  • Colouring the plot by a known attribute produces apparent clusters by that attribute, and the eye reads the colouring as the geometry; the same points uncoloured show nothing.
What the recommended approach costs
  • Refusing to act on projections removes a persuasive tool from a team that needs to communicate with people who will not read a neighbour-agreement table.
  • Computing neighbour agreement is an exact nearest-neighbour search on the sample, which is cheap at plotting scale and must be repeated for every re-fit.
  • Showing several projections is honest and tends to convince the audience that the data has no structure, when the true statement is that the plots cannot show it.
Misreads
  • "The plot shows two clusters, so the data has two clusters." t-SNE and UMAP produce clusters from continuous data as a matter of course. A clustering run in the full space, evaluated on an outcome, is the test.
  • "Those two groups are far apart in the plot, so they are very different." Inter-cluster distance in t-SNE and UMAP is not meaningful; in PCA it is meaningful only along the kept axes, which may hold little of the variance.
  • "The plot is a lower-resolution view of the embedding space." It is a different space, fitted to keep one property of the original at the expense of the others. Which property depends on the method, and neighbourhoods are the one most often lost.

Where this applies

ML advice is stated as universal far more often than it is. These labels say what each claim is specific to — and where CONTESTED appears, the note gives the strongest form of the opposing view.

  • GENERALThat a two-dimensional layout cannot preserve the pairwise distances of a higher-dimensional set is geometry and holds for any embedding; which distortion a method introduces is specific to the method, not to the data.
  • SIMULATEDThe neighbour-agreement figures in the lab at /ml/embeddings are computed on a small hand-built vocabulary of six-dimensional vectors written for Engineer Atlas; they demonstrate that disagreement exists even in a tiny clean case and are not measurements on any real embedding.

Where the depth lives

This domain teaches the model and hands the rest off by name.

Agenticembeddings