Grupowanie i wizualizacja embeddingów
Uczestnicy zastosują grupowanie k-means do zbioru embeddingów i zwizualizują je w dwóch wymiarach za pomocą UMAP, aby odkryć naturalne grupy tematyczne w danych.
Grupowanie i wizualizacja embeddingów to bezpłatna lekcja AI Engineering Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej AI Engineering Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs AI Engineering Academy zawiera 4 lekcji w sumie.
Dlaczego klasteryzować embeddingi?
Gdy mają Państwo setki lub tysiące dokumentów, często chcą Państwo odkryć, jakie tematy się w nich pojawiają, bez ręcznego czytania wszystkiego. Klasteryzacja embeddingów automatycznie grupuje semantycznie podobne dokumenty, ujawniając naturalną strukturę danych.
Typowe zastosowania obejmują automatyczne tagowanie zgłoszeń do pomocy technicznej, odkrywanie kategorii treści, znajdowanie redundantnych dokumentów oraz analizowanie tematów, o które użytkownicy pytają najczęściej.
Wprowadzenie do klasteryzacji K-means
K-means dzieli n punktów danych na k klastrów, iteracyjnie przypisując każdy punkt do najbliższego centroidu, a następnie ponownie obliczając centroidy jako średnią przypisanych punktów. Algorytm kończy działanie, gdy przypisania przestają się zmieniać.
W przypadku embeddingów k-means znajduje dokumenty położone blisko siebie w wielowymiarowej przestrzeni embeddingów, skutecznie grupując je według podobieństwa semantycznego.
from sklearn.cluster import KMeans
import numpy as np
# corpus_embeddings: (n_docs, 1536) — pre-computed
corpus_embeddings = np.random.randn(200, 1536) # placeholder
kmeans = KMeans(n_clusters=5, random_state=42, n_init='auto')
kmeans.fit(corpus_embeddings)
labels = kmeans.labels_
print(f'Cluster assignments: {labels[:10]}')
print(f'Unique clusters: {set(labels)}')Wybór właściwej liczby klastrów
Wybór k, czyli liczby klastrów, jest najtrudniejszą częścią zadania. Metoda łokcia przedstawia wykres inercji (sumy kwadratów odległości od centroidów) dla różnych wartości k i wskazuje punkt, w którym dodawanie kolejnych klastrów przestaje znacząco zmniejszać inercję.
Współczynnik silhouette mierzy, o ile lepiej punkt pasuje do własnego klastra niż do najbliższego innego klastra — wartości bliższe 1 są lepsze. Należy wypróbować wartości k od 3 do 20 i wybrać tę z najlepszym wynikiem.
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
import numpy as np
corpus_embeddings = np.random.randn(200, 50) # placeholder (50D for speed)
best_k, best_score = 2, -1
for k in range(2, 11):
km = KMeans(n_clusters=k, random_state=42, n_init='auto')
labels = km.fit_predict(corpus_embeddings)
score = silhouette_score(corpus_embeddings, labels, sample_size=100)
print(f'k={k}: silhouette={score:.3f}')
if score > best_score:
best_score, best_k = score, k
print(f'Best k: {best_k}')Nadawanie klastrom etykiet za pomocą LLM
Po klasteryzacji można poprosić LLM o wygenerowanie czytelnej dla człowieka etykiety dla każdego klastra, przekazując modelowi kilka reprezentatywnych dokumentów z danego klastra. Dzięki temu surowe numery klastrów zostają automatycznie zamienione na znaczące nazwy kategorii.
from openai import OpenAI
client = OpenAI()
def label_cluster(cluster_docs, n_examples=3):
examples = '\n'.join(f'- {d}' for d in cluster_docs[:n_examples])
prompt = f'Given these documents, provide a 3-word category label:\n{examples}\nLabel:'
response = client.chat.completions.create(
model='gpt-4o-mini',
messages=[{'role': 'user', 'content': prompt}],
max_tokens=20
)
return response.choices[0].message.content.strip()
# Example usage:
# cluster_0_docs = [documents[i] for i in range(len(documents)) if labels[i] == 0]
# print(label_cluster(cluster_0_docs))Redukcja wymiarowości za pomocą UMAP
Wektorów o 1536 wymiarach nie można bezpośrednio przedstawić na wykresie. UMAP (Uniform Manifold Approximation and Projection) redukuje dane wielowymiarowe do 2D lub 3D, zachowując strukturę lokalnych sąsiedztw. W przeciwieństwie do PCA UMAP jest metodą nieliniową i znacznie lepiej zachowuje klastry.
UMAP jest standardowym wyborem do wizualizacji embeddingów tekstu, ponieważ podobne dokumenty pozostają blisko siebie na wykresie 2D.
import umap
import numpy as np
corpus_embeddings = np.random.randn(200, 1536) # placeholder
reducer = umap.UMAP(
n_components=2,
metric='cosine', # important for text embeddings
random_state=42
)
embeddings_2d = reducer.fit_transform(corpus_embeddings)
print(f'Reduced shape: {embeddings_2d.shape}') # (200, 2)Wizualizacja klastrów za pomocą Matplotlib
Gdy mają już Państwo współrzędne 2D uzyskane za pomocą UMAP oraz etykiety klastrów wygenerowane przez k-means, prosty wykres punktowy uwidacznia strukturę klastrów. Należy pokolorować każdy punkt zgodnie z etykietą klastra i dodać tytuły reprezentatywnych dokumentów jako adnotacje tekstowe, aby wykres był czytelny.
import matplotlib.pyplot as plt
import numpy as np
# Assume: embeddings_2d (n, 2), labels (n,), documents list
# Placeholder data:
np.random.seed(42)
embeddings_2d = np.random.randn(50, 2)
labels = np.random.randint(0, 5, 50)
fig, ax = plt.subplots(figsize=(10, 7))
scatter = ax.scatter(
embeddings_2d[:, 0],
embeddings_2d[:, 1],
c=labels,
cmap='tab10',
s=60,
alpha=0.8
)
plt.colorbar(scatter, label='Cluster')
ax.set_title('Document Embedding Clusters (UMAP)')
plt.tight_layout()
plt.savefig('/tmp/clusters.png', dpi=150)
print('Saved cluster plot')Istotne parametry UMAP
Najważniejsze hiperparametry UMAP wpływające na jakość wizualizacji:
- n_neighbors (domyślnie 15): większe wartości uwzględniają szerszą strukturę globalną, a mniejsze ujawniają klastry lokalne
- min_dist (domyślnie 0.1): określa, jak ciasno układają się punkty; mniejsza wartość oznacza ciaśniejsze klastry, ale większe nakładanie się ich na siebie
- metric: dla embeddingów tekstu należy zawsze używać
'cosine'— odległość euklidesowa jest nieodpowiednia
Należy eksperymentować z wartością n_neighbors od 5 do 50, aby znaleźć wizualizację najlepiej ujawniającą strukturę danych.
Alternatywa: klasteryzacja hierarchiczna
Aglomeracyjna klasteryzacja hierarchiczna buduje drzewo zagnieżdżonych klastrów bez konieczności wcześniejszego określania k. Drzewo można przeciąć przy wybranym progu odległości, aby uzyskać ostateczne klastry. Jest to przydatne, gdy nie znają Państwo liczby naturalnych tematów występujących w danych.
from sklearn.cluster import AgglomerativeClustering
import numpy as np
corpus_embeddings = np.random.randn(100, 50) # placeholder
cluster = AgglomerativeClustering(
n_clusters=None,
distance_threshold=1.5,
metric='cosine',
linkage='average'
)
labels = cluster.fit_predict(corpus_embeddings)
n_clusters = len(set(labels))
print(f'Found {n_clusters} natural clusters')Znajdowanie wartości odstających i niemal duplikatów
Embeddingi doskonale nadają się także do znajdowania niemal zduplikowanych dokumentów. Należy obliczyć pary podobieństwa cosinusowego między wszystkimi dokumentami i oznaczyć pary o podobieństwie powyżej 0.95 jako potencjalne duplikaty. Jest to rozwiązanie bardziej odporne niż porównywanie różnic tekstowych, ponieważ wykrywa również duplikaty o zmienionym sformułowaniu.
import numpy as np
def find_near_duplicates(corpus_vecs, threshold=0.95):
# corpus_vecs assumed L2-normalized
sim_matrix = corpus_vecs @ corpus_vecs.T # (n, n)
duplicates = []
n = len(corpus_vecs)
for i in range(n):
for j in range(i + 1, n):
if sim_matrix[i, j] >= threshold:
duplicates.append((i, j, float(sim_matrix[i, j])))
return duplicates
# pairs = find_near_duplicates(corpus_embeddings)
# print(f'Found {len(pairs)} near-duplicate pairs')Praktyczny proces klasteryzacji
Rzeczywisty proces klasteryzacji obejmuje następujące kroki wykonywane w tej kolejności:
- Wygenerowanie embeddingów wszystkich dokumentów za pomocą
text-embedding-3-small - Opcjonalne zmniejszenie wymiarowości do 50D za pomocą UMAP przed klasteryzacją (przyspiesza działanie k-means)
- Wykonanie klasteryzacji za pomocą k-means i przetestowanie różnych wartości k w celu znalezienia najlepszego wyniku silhouette
- Nadanie każdemu klastrowi etykiety za pomocą LLM na podstawie 5 reprezentatywnych dokumentów
- Wizualizacja dwuwymiarowego wykresu punktowego UMAP z kolorami odpowiadającymi klastrom
- Przeanalizowanie wartości odstających (punktów oddalonych od każdego centroidu)
Ograniczenia klasteryzacji
Klasteryzacja embeddingów ma istotne ograniczenia, o których należy pamiętać:
- K-means zakłada kulisty kształt klastrów — wydłużone lub nieregularne grupy tematyczne mogą zostać nieprawidłowo podzielone
- Embeddingi kompresują znaczenie — dwa dokumenty mogą być bliskie semantycznie, ale należeć do różnych kategorii operacyjnych
- Etykiety klastrów wymagają weryfikacji — należy zawsze przeanalizować przykładowe dokumenty z każdego klastra, aby sprawdzić poprawność etykiety wygenerowanej przez LLM
Klasteryzację należy traktować jako narzędzie eksploracyjne, a nie system kategoryzacji stanowiący źródło prawdy.
Szybki test
Sprawdź swoją znajomość zagadnień inżynierii AI z tej lekcji.
Podsumowanie lekcji
W tej lekcji nauczyli się Państwo, że: k-means grupuje dokumenty na podstawie podobieństwa semantycznego w przestrzeni embeddingów, UMAP redukuje wielowymiarowe embeddingi do 2D na potrzeby wizualizacji, używając odległości cosinusowej, a wskaźnik sylwetki pomaga wybrać właściwą liczbę klastrów bez danych z etykietami. Następnie wyjdziemy poza wyszukiwanie w pamięci i poznamy produkcyjne wektorowe bazy danych.
Często zadawane pytania
Czy lekcja „Grupowanie i wizualizacja embeddingów” jest bezpłatna?
Tak — pełny tekst „Grupowanie i wizualizacja embeddingów” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu AI Engineering Academy, przejdź na CoddyKit PRO. Kurs AI Engineering Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Grupowanie i wizualizacja embeddingów”?
Uczestnicy zastosują grupowanie k-means do zbioru embeddingów i zwizualizują je w dwóch wymiarach za pomocą UMAP, aby odkryć naturalne grupy tematyczne w danych. Ćwiczysz AI Engineering Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć AI Engineering Academy?
Nie wymagamy żadnego doświadczenia. AI Engineering Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.
Ile czasu zajmuje lekcja „Grupowanie i wizualizacja embeddingów”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji AI Engineering Academy?
Tak. Każda lekcja AI Engineering Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Czym są embeddingi wektorowe?
- Generowanie embeddingów za pomocą OpenAI
- Wyszukiwanie semantyczne z NumPy
- Grupowanie i wizualizacja embeddingów