t-SNE (t-distributed Stochastic Neighbor Embedding) is a nonlinear dimensionality reduction method for visualization: it places high-dimensional points in 2D or 3D so that neighborhoods are preserved. It excels at revealing cluster structure but is a visualization tool, not a general feature transform.
Pairwise Affinities (High Dim)
For each point define a conditional probability that would pick as a neighbor under a Gaussian centered at :
The bandwidth is set per point so the neighborhood has a target size (see perplexity). Symmetrize to .
Student-t in Low Dim
In the low-dimensional map, similarities use a Student-t distribution with one degree of freedom (a Cauchy), which has heavy tails:
KL Objective
The map is found by minimizing the Kullback-Leibler divergence between the high-dim and low-dim affinities via Gradient Descent:
Because KL is asymmetric, a large modeled by a small (nearby points placed far apart) is heavily penalized, so t-SNE prioritizes preserving local structure over global distances.
Perplexity
Perplexity sets the effective number of neighbors each targets:
Typical values are 5 to 50. Small perplexity emphasizes very local structure; large perplexity blends broader neighborhoods.
The Crowding Problem
In high dimensions there is far more room for a point to have many roughly-equidistant neighbors than in 2D. A Gaussian low-dim kernel would force moderately distant points to crush together. The heavy-tailed Student-t fixes this: it allocates more room at moderate distances, letting clusters spread out and separate cleanly.
Contrast with PCA and UMAP
| Aspect | PCA | t-SNE | UMAP |
|---|---|---|---|
| Type | linear | nonlinear | nonlinear |
| Preserves | global variance | local neighborhoods | local + some global |
| Deterministic | yes | no (random init) | no |
| Speed | fast | slow | faster than t-SNE |
| New-point map | trivial (project) | not natively | supports transform |
A common pipeline runs PCA first (to ~50 dims) to denoise and speed things up, then t-SNE for the final 2D plot.
sklearn Usage
from sklearn.decomposition import PCA
from sklearn.manifold import TSNE
X50 = PCA(n_components=50).fit_transform(X) # denoise / speed up
emb = TSNE(
n_components=2,
perplexity=30,
learning_rate="auto",
init="pca",
random_state=0,
).fit_transform(X50)Pitfalls
- Cluster sizes and inter-cluster distances in a t-SNE plot are NOT meaningful; do not read them as real densities or gaps.
- Results depend on perplexity and the random seed; try several settings before trusting a picture.
- t-SNE does not learn a reusable mapping for new data (use UMAP or a parametric model if you need that).
- Do not feed t-SNE coordinates into a downstream classifier; it is for visualization only.