pip install openTSNE★From PyPI (needs a C/C++ compiler).conda install -c conda-forge opentsnePrebuilt conda-forge wheel — no compiler.from openTSNE import TSNE★The main estimator.from openTSNE import affinity, initializationModular building blocks (low-level API).from openTSNE import TSNEEmbeddingThe optimizable, array-like embedding.
emb = TSNE().fit(X)★All sensible defaults → a 2-D embedding.emb = TSNE(n_jobs=-1, random_state=42).fit(X)★All cores + reproducible layout.from openTSNE.sklearn import TSNEscikit-learn wrapper …Y = TSNE().fit_transform(X)… returns a plainnp.ndarray.
perplexity=30★≈ number of neighbors to preserve.initialization="pca"★Default; deterministic, keeps global shape.metric="euclidean"Or"cosine","manhattan", a callable…n_jobs=-1★Threads;-1= all cores.random_state=42★Fix it for a reproducible map.negative_gradient_method="fft"FIt-SNE (big data);"bh"for small.learning_rate="auto"= N / exaggeration — leave it be.verbose=TruePrint KL divergence + timings.
TSNE(perplexity=30)★Default; good for small–medium sets.TSNE(perplexity=500)Large data → far better global structure.# continuous k of nearest neighborsBalances local vs global structure.# k_neighbors auto = 3 × perplexityAnd perplexity must be < n_samples.# runtime scales linearly with itHigher perplexity = longer to run.
affinity.PerplexityBasedNN(X, perplexity=30)★Standard Gaussian kNN affinities.affinity.Multiscale(X, perplexities=[50, 500])★Multi-scale → best global structure.affinity.MultiscaleMixture(X, perplexities=[...])Gaussian-mixture kernel variant.affinity.FixedSigmaNN(X, sigma=1, k=30)Fixed bandwidth; teases out tiny clusters.affinity.Uniform(X, k_neighbors=30)Uniform kernel over the kNN graph.affinity.PrecomputedAffinities(P)Bring your own N×N affinity matrix.TSNE().fit(affinities=aff)★Pass it in — overrides perplexity/metric.
initialization.pca(X, random_state=42)★Default; deterministic + global structure.initialization.spectral(aff.P)Spectral embedding of the affinity graph.initialization.random(n_samples, random_state=0)Gaussian noise — layout not reproducible.initialization.rescale(Y)Scale a custom init to a safe variance.initialization.jitter(Y)Add small noise to break ties.# custom init: std(Y) < 1e-4careLarge variance → poor embeddings.
early_exaggeration=12, early_exaggeration_iter=250★Phase 1: pull clusters tightly together.n_iter=500Phase 2: normal regime spreads them out.exaggeration=4Mild exaggeration in phase 2 (big data).initial_momentum=0.5, final_momentum=0.8Early phase looser, normal phase firmer.emb.optimize(100, exaggeration=1)★Run extra steps on an existing embedding.
# build each stage yourself, then # drive the two-phase optimization aff = affinity.PerplexityBasedNN( X, perplexity=30, n_jobs=-1) init = initialization.pca( X, random_state=42) emb = TSNEEmbedding( init, aff, negative_gradient_method="fft", n_jobs=-1, ) # ★ phase 1 — early exaggeration emb.optimize(250, exaggeration=12, momentum=0.5, inplace=True) # ★ phase 2 — normal regime emb.optimize(500, momentum=0.8, inplace=True)
# only openTSNE does thisGreat for batch effects & streaming data.
pickle.dump(emb, f)★Persist it; reload later totransform.
TSNE(n_jobs=-1)★Use every core — big wins.TSNE(negative_gradient_method="fft")★FIt-SNE; scales to millions of points.TSNE(neighbors="approx")Annoy / pynndescent kNN for large N.Multiscale(X, perplexities=[50, 500])Global structure that survives at scale.emb.optimize(750, exaggeration=4)Cleaner separation on huge sets.
TSNE(verbose=True)★Log KL divergence + timing each 50 iters.TSNE(callbacks=cb, callbacks_every_iters=50)Runcbduring optimization.def cb(iteration, error, emb): return error < 1Any callable; returnTrueto stop early.except OptimizationInterrupt as e:The stopped embedding rides on the error.
# 1 · PCA-reduce X to ~50 dims firstFaster + denoises before t-SNE.initialization="pca"Deterministic + preserves global layout.perplexity=30 → 500OrMultiscale([50, 500])for the best of both.learning_rate="auto"= N / exaggeration — the modern default.exaggeration=4For very large sets, tightens clusters.random_state=42So the map is the same every run.
cluster sizes mean nothingmytht-SNE expands dense regions, shrinks sparse ones.gaps aren't distancesmythSpacing between clusters isn't reliable.axes have no unitsmythRotation and flips are arbitrary.one run isn't truthcareTry a few seeds & perplexities.t-SNE ≠ clusteringcareDon't run k-means on the 2-D output.