📐 Embedding Geometry & Semantic Search Playground¶
Estimated time to read: 43 minutes
Welcome to the interactive playground for LAB-02 (Embedding Geometry & Manifold Hypothesis).
This notebook demonstrates:
- Generating high-dimensional word representations showing the Manifold Hypothesis.
- Computing Cosine Similarity mathematically.
- Running a local Semantic Search Engine.
- Projecting high-dimensional metrics to 2D/3D using PCA and t-SNE.
0. Environment Setup¶
If you are running in Google Colab, this cell will automatically clone the repository and install all required dependencies. If running locally, it does nothing.
import os
import sys
import sys
from pathlib import Path
try:
import google.colab
IN_COLAB = True
except ImportError:
IN_COLAB = False
if IN_COLAB:
print("🤖 Running in Google Colab. Setting up environment...")
!pip install -q numpy scikit-learn matplotlib loguru
# Clone repository to access custom local source modules
if not os.path.exists("production-ai-systems"):
!git clone https://github.com/RogerioLS/production-ai-systems.git
sys.path.append("production-ai-systems")
print("🎉 Colab environment successfully initialized!")
# Ensure project root is in the path when running locally
if not IN_COLAB:
# Localiza dinamicamente a raiz do repositório procurando por 'pyproject.toml'
current_dir = Path.cwd()
root_dir = current_dir
for parent in [current_dir] + list(current_dir.parents):
if (parent / "pyproject.toml").exists() or (parent / "projects").exists():
root_dir = parent
break
if str(root_dir) not in sys.path:
sys.path.insert(0, str(root_dir))
print(f"📁 Project root added to sys.path: {root_dir}")
📁 Project root added to sys.path: /home/runner/work/production-ai-systems/production-ai-systems
1. Setup & Imports¶
Let's import our custom libraries and standard requirements. Make sure you are running this in your active Conda environment.
import matplotlib.pyplot as plt
import numpy as np
from projects.a_llm_basics.src.lab_02_embeddings.embeddings import WordCategoryEmbedder
from projects.a_llm_basics.src.lab_02_embeddings.reducer import DimensionalityReducer
from projects.a_llm_basics.src.lab_02_embeddings.semantic_search import SemanticSearchEngine, cosine_similarity
print("✅ Imports loaded successfully!")
✅ Imports loaded successfully!
2. Computing Cosine Similarity Manually¶
Recall the formula for Cosine Similarity: $$\text{Similarity}(u, v) = \frac{u \cdot v}{\|u\|_2 \|v\|_2}$$
Let's check our manual implementation against basic orthogonal and collinear vectors.
vector_a = np.array([1.0, 0.0, 0.0])
vector_b = np.array([0.0, 1.0, 0.0]) # Orthogonal
vector_c = np.array([-1.0, 0.0, 0.0]) # Opposite
print(f"Similarity A vs B (Orthogonal): {cosine_similarity(vector_a, vector_b):.4f}")
print(f"Similarity A vs C (Opposite): {cosine_similarity(vector_a, vector_c):.4f}")
print(f"Similarity A vs A (Collinear): {cosine_similarity(vector_a, vector_a):.4f}")
Similarity A vs B (Orthogonal): 0.0000 Similarity A vs C (Opposite): -1.0000 Similarity A vs A (Collinear): 1.0000
3. Let's Load Semantic Word Embeddings¶
We will initialize our WordCategoryEmbedder with dimension=100 and small noise. It maps words to categories (food, tech, sports, animals).
embedder = WordCategoryEmbedder(dimension=100, noise_std=0.06, seed=42)
# Look at vocabulary categories
for category, words in embedder.categories.items():
print(f"Category: {category:<8} | Words: {words}")
2026-09-30 21:12:05 | INFO | projects.a_llm_basics.src.lab_02_embeddings.embeddings:__init__:122 - Initialized WordCategoryEmbedder (dimension=100, noise_std=0.06) with 4 semantic categories.
Category: food | Words: ['apple', 'banana', 'orange', 'grape', 'tomato', 'pizza', 'sushi', 'bread'] Category: tech | Words: ['python', 'java', 'computer', 'software', 'database', 'ai', 'hardware', 'internet'] Category: sports | Words: ['football', 'soccer', 'tennis', 'basketball', 'athlete', 'stadium', 'referee', 'run'] Category: animals | Words: ['lion', 'tiger', 'elephant', 'giraffe', 'monkey', 'dog', 'cat', 'panda']
Similarity Matrix¶
Let's measure similarity between specific words. We expect apple to be very similar to banana (same category) but orthogonal to python (different category).
word_pairs = [
("apple", "banana"),
("python", "java"),
("apple", "python"),
("soccer", "athlete")
]
for w1, w2 in word_pairs:
v1 = embedder.embed_text(w1)
v2 = embedder.embed_text(w2)
sim = cosine_similarity(v1, v2)
print(f"Similarity between '{w1}' and '{w2}': {sim:.4f}")
Similarity between 'apple' and 'banana': 0.7049 Similarity between 'python' and 'java': 0.7159 Similarity between 'apple' and 'python': 0.0575 Similarity between 'soccer' and 'athlete': 0.7024
4. Interactive Semantic Search Engine¶
Let's feed some text documents to our SemanticSearchEngine and query them semantically.
engine = SemanticSearchEngine(embedder=embedder)
# Index standard semantic documents
engine.add_documents([
"apple",
"python",
"soccer",
"dog"
])
# Enter your custom query words below
query = "computer"
results = engine.search(query, top_k=3)
print(f"🔎 Search Results for query: '{query}'")
for rank, (doc, score) in enumerate(results, 1):
print(f"#{rank} Word: '{doc}' with Cosine Similarity: {score:.4f}")
2026-09-30 21:12:05 | INFO | projects.a_llm_basics.src.lab_02_embeddings.semantic_search:__init__:88 - Initialized SemanticSearchEngine with embedder dimension: 100
2026-09-30 21:12:05 | INFO | projects.a_llm_basics.src.lab_02_embeddings.semantic_search:add_documents:109 - Indexed 4 new documents. Total corpus size: 4
2026-09-30 21:12:05 | INFO | projects.a_llm_basics.src.lab_02_embeddings.semantic_search:search:152 - Completed semantic search for query 'computer'. Returned 3 results.
🔎 Search Results for query: 'computer' #1 Word: 'python' with Cosine Similarity: 0.7751 #2 Word: 'apple' with Cosine Similarity: 0.0644 #3 Word: 'soccer' with Cosine Similarity: -0.0297
5. Visualizing High-Dimensional Manifolds (PCA vs t-SNE)¶
Let's generate 2D and 3D plots showing the geometry of the embedding space.
# Gather all words in categories
all_words = []
all_labels = []
all_colors = []
color_map = {
"food": "#ff7f0e",
"tech": "#1f77b4",
"sports": "#2ca02c",
"animals": "#d62728"
}
for category, cat_words in embedder.categories.items():
for w in cat_words:
all_words.append(w)
all_labels.append(category)
all_colors.append(color_map[category])
vectors = embedder.embed_batch(all_words)
# Project to 2D using PCA & t-SNE
pca = DimensionalityReducer(method="pca", n_components=2)
tsne = DimensionalityReducer(method="tsne", n_components=2, perplexity=5)
coords_pca = pca.fit_transform(vectors)
coords_tsne = tsne.fit_transform(vectors)
# Plotting 2D projections
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(16, 7))
# PCA Scatter
for cat, col in color_map.items():
indices = [i for i, label in enumerate(all_labels) if label == cat]
ax1.scatter(coords_pca[indices, 0], coords_pca[indices, 1], c=col, label=cat.capitalize(), edgecolors="k", s=120, alpha=0.85)
ax1.set_title("PCA Projection (2D)", fontsize=13, fontweight="bold")
ax1.grid(True, linestyle="--", alpha=0.5)
for i, w in enumerate(all_words):
ax1.annotate(w, (coords_pca[i, 0], coords_pca[i, 1]), textcoords="offset points", xytext=(0, 6), ha="center", fontsize=8)
# t-SNE Scatter
for cat, col in color_map.items():
indices = [i for i, label in enumerate(all_labels) if label == cat]
ax2.scatter(coords_tsne[indices, 0], coords_tsne[indices, 1], c=col, label=cat.capitalize(), edgecolors="k", s=120, alpha=0.85)
ax2.set_title("t-SNE Projection (2D)", fontsize=13, fontweight="bold")
ax2.grid(True, linestyle="--", alpha=0.5)
for i, w in enumerate(all_words):
ax2.annotate(w, (coords_tsne[i, 0], coords_tsne[i, 1]), textcoords="offset points", xytext=(0, 6), ha="center", fontsize=8)
plt.suptitle("Dimensionality Reduction Comparison", fontsize=16, fontweight="bold")
plt.legend(loc="upper center", bbox_to_anchor=(-0.1, -0.08), ncol=4)
plt.show()
2026-09-30 21:12:05 | INFO | projects.a_llm_basics.src.lab_02_embeddings.reducer:__init__:65 - Initialized DimensionalityReducer with method='pca', target_dim=2.
2026-09-30 21:12:05 | INFO | projects.a_llm_basics.src.lab_02_embeddings.reducer:__init__:65 - Initialized DimensionalityReducer with method='tsne', target_dim=2.
2026-09-30 21:12:05 | INFO | projects.a_llm_basics.src.lab_02_embeddings.reducer:fit_transform:106 - Successfully projected embeddings from shape (32, 100) to (32, 2) using PCA.
2026-09-30 21:12:05 | INFO | projects.a_llm_basics.src.lab_02_embeddings.reducer:fit_transform:106 - Successfully projected embeddings from shape (32, 100) to (32, 2) using TSNE.
6. Interactive 3D PCA Scatter¶
Run this cell to render a 3D scatter plot of the embedding space. If you run this in an interactive Jupyter environment, you can rotate and zoom this plot.
%matplotlib inline
pca_3d = DimensionalityReducer(method="pca", n_components=3)
coords_3d = pca_3d.fit_transform(vectors)
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(projection="3d")
ax.set_facecolor("#fcfcfc")
# Draw 3D scatter
for cat, col in color_map.items():
indices = [i for i, label in enumerate(all_labels) if label == cat]
ax.scatter(
coords_3d[indices, 0], coords_3d[indices, 1], coords_3d[indices, 2],
c=col, label=cat.capitalize(), edgecolors="k", s=100, alpha=0.85
)
# Annotate text
for i, w in enumerate(all_words):
ax.text(coords_3d[i, 0], coords_3d[i, 1], coords_3d[i, 2], w, fontsize=8, fontweight="semibold")
ax.set_xlabel("PC 1")
ax.set_ylabel("PC 2")
ax.set_zlabel("PC 3")
ax.set_title("3D Embedding Projection (PCA)", fontsize=14, fontweight="bold")
plt.legend()
plt.show()
2026-09-30 21:12:05 | INFO | projects.a_llm_basics.src.lab_02_embeddings.reducer:__init__:65 - Initialized DimensionalityReducer with method='pca', target_dim=3.
2026-09-30 21:12:05 | INFO | projects.a_llm_basics.src.lab_02_embeddings.reducer:fit_transform:106 - Successfully projected embeddings from shape (32, 100) to (32, 3) using PCA.
findfont: Failed to find font weight semibold for DejaVu Sans, now using 700.