Visualizing embedding similarity from text documents using t-SNE plots
Source notebook
Repo path:
embeddings/embedding-similarity-visualization.ipynb· Open on GitHub · intro
Embeds 20 Newsgroups text with gemini-embedding-001 and visualizes similarity clusters using t-SNE.
Summary
This notebook teaches how vector similarity appears in LLM-generated text embeddings. It fetches labeled 20 Newsgroups documents, filters and cleans the text, creates 768-dimensional embeddings with gemini-embedding-001, reduces them to two dimensions with t-SNE, and plots category clusters with seaborn.
Key code patterns
Initialize GenAI client for Vertex AI
from google import genai
PROJECT_ID = os.environ.get("GOOGLE_CLOUD_PROJECT")
LOCATION = os.environ.get("GOOGLE_CLOUD_REGION", "us-central1")
client = genai.Client(vertexai=True, project=PROJECT_ID, location=LOCATION)Configures google-genai to call Vertex AI-hosted models in a Google Cloud project and region.
Create text embeddings with retry
from google.api_core import retry
from google.genai import types
@retry.Retry(timeout=300.0)
def embed_fn(contents: str) -> list[float]:
response = client.models.embed_content(
model="gemini-embedding-001",
contents=contents,
config=types.EmbedContentConfig(output_dimensionality=768),
)
return response.embeddings[0].valuesAdds retry handling around embedding calls and requests 768-dimensional vectors.
Reduce embeddings with t-SNE
tsne = TSNE(random_state=0, max_iter=1000)
tsne_results = tsne.fit_transform(
np.array(df["embeddings"].to_list(), dtype=np.float32)
)
df_tsne = pd.DataFrame(tsne_results, columns=["TSNE1", "TSNE2"])
df_tsne["target"] = df["target"]Turns high-dimensional embedding vectors into two coordinates for visual inspection.
Plot labeled clusters
fig, ax = plt.subplots(figsize=(8, 6))
sns.set_style("darkgrid", {"grid.color": ".6", "grid.linestyle": ":"})
sns.scatterplot(data=df_tsne, x="TSNE1", y="TSNE2", hue="target", palette="hls")
sns.move_legend(ax, "upper left", bbox_to_anchor=(1, 1))
plt.axis("equal")Visualizes whether documents with the same newsgroup label appear close in embedding space.
Models & APIs used
- Models: gemini-embedding-001
- APIs / services: Vertex AI
- SDKs / libraries:
google-genai,scikit-learn,pandas,seaborn,matplotlib,numpy,google-api-core,tqdm
When to use this
Use this pattern to sanity-check whether text embeddings group labeled documents by semantic similarity before building clustering, retrieval, or classification workflows.
Gotchas & caveats
- Requires an existing Google Cloud project and the Agent Platform API enabled.
- Colab requires explicit user authentication; Agent Platform Workbench does not require that Colab auth cell.
- The notebook filters documents to 8000 characters because of the stated 8k input token limit.
- Embedding generation over 500 documents may take a minute or two.
- LOCATION defaults to us-central1 when GOOGLE_CLOUD_REGION is not set.
Best practices
- Use environment variables for GOOGLE_CLOUD_PROJECT and GOOGLE_CLOUD_REGION when notebook parameters are not provided.
- Subsample with stratification so labels are roughly evenly distributed.
- Clean emails, names, From headers, and Subject markers before embedding text.
- Use retry logic around embedding requests with a 300 second timeout.
- Set output_dimensionality to 768 before applying t-SNE for visualization.
Related
- Concepts: Embeddings & Vector Search
- Entities: Vertex AI · Google GenAI SDK · Gemini
- Area: Embeddings & Vector Search Notebooks
- Best practices: Embeddings & Vector Search - Best Practices