AI Engineering Academy · Les

Embeddings clusteren en visualiseren

U past k-means-clustering toe op een verzameling embeddings en visualiseert deze in 2D met UMAP om natuurlijke onderwerpgroepen in uw data te ontdekken.

Les 4 van 413 stappen

Embeddings clusteren en visualiseren is een gratis AI Engineering Academy-les op CoddyKit. Dit is les 4 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject AI Engineering Academy. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus AI Engineering Academy bevat in totaal 4 lessen.

Waarom embeddings clusteren?

Wanneer je honderden of duizenden documenten hebt, wil je vaak ontdekken welke onderwerpen erin voorkomen zonder alles handmatig te lezen. Embeddings clusteren groepeert semantisch vergelijkbare documenten automatisch, waardoor de natuurlijke structuur van je gegevens zichtbaar wordt.

Veelvoorkomende toepassingen zijn onder andere: supporttickets automatisch labelen, inhoudscategorieën ontdekken, dubbele documenten vinden en begrijpen waar gebruikers het vaakst vragen over stellen.

Overzicht van K-means-clustering

K-means verdeelt n gegevenspunten over k clusters door elk punt herhaaldelijk aan het dichtstbijzijnde zwaartepunt toe te wijzen en daarna de zwaartepunten te herberekenen als het gemiddelde van de toegewezen punten. Het algoritme convergeert wanneer de toewijzingen niet meer veranderen.

Voor embeddings vindt k-means documenten die dicht bij elkaar liggen in de hoogdimensionale embeddingruimte, waardoor ze effectief worden gegroepeerd op basis van semantische overeenkomst.

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)}')

Het juiste aantal clusters kiezen

Het kiezen van k (het aantal clusters) is het moeilijkste onderdeel. Bij de elleboogmethode wordt de inertie (de som van de gekwadrateerde afstanden tot de zwaartepunten) uitgezet voor verschillende waarden van k. Vervolgens zoek je het punt waarop extra clusters de inertie niet langer aanzienlijk verlagen.

De silhouetscore meet hoeveel beter een punt bij zijn eigen cluster past dan bij het dichtstbijzijnde andere cluster — scores dichter bij 1 zijn beter. Probeer waarden van k tussen 3 en 20 en kies de beste score.

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}')

Clusters labelen met een LLM

Na het clusteren kun je een LLM vragen om voor elk cluster een voor mensen leesbaar label te genereren door enkele representatieve documenten uit dat cluster aan het model door te geven. Zo worden ruwe clusternummers automatisch omgezet in betekenisvolle categorienamen.

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))

Dimensionaliteitsreductie met UMAP

Vectoren met 1536 dimensies kunnen niet rechtstreeks worden geplot. UMAP (Uniform Manifold Approximation and Projection) reduceert hoogdimensionale gegevens tot 2D of 3D en behoudt daarbij de structuur van lokale buurten. In tegenstelling tot PCA is UMAP niet-lineair en veel beter in het behouden van clusters.

UMAP is de standaardkeuze voor het visualiseren van tekstembeddings, omdat vergelijkbare documenten dicht bij elkaar blijven in de 2D-plot.

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)

Clusters visualiseren met Matplotlib

Zodra je 2D-coördinaten van UMAP en clusterlabels van k-means hebt, maakt een eenvoudige spreidingsgrafiek de clusterstructuur zichtbaar. Geef elk punt de kleur van zijn clusterlabel en voeg de titels van representatieve documenten toe als tekstannotaties, zodat de grafiek begrijpelijk wordt.

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')

Belangrijke UMAP-parameters

Belangrijke UMAP-hyperparameters die de kwaliteit van de visualisatie beïnvloeden:

  • n_neighbors (standaard 15): grotere waarden leggen meer globale structuur vast, kleinere waarden laten lokale clusters zien
  • min_dist (standaard 0.1): hoe dicht punten op elkaar gepakt worden; kleiner = compactere clusters, maar meer overlap ertussen
  • metric: gebruik voor tekstembeddings altijd 'cosine' — Euclidische afstand is niet geschikt

Experimenteer met n_neighbors tussen 5 en 50 om de visualisatie te vinden die de structuur van je gegevens het best zichtbaar maakt.

Alternatief: hiërarchisch clusteren

Agglomeratieve hiërarchische clustering bouwt een boom met geneste clusters zonder dat je vooraf k hoeft op te geven. Je knipt de boom bij een gekozen afstandsdrempel door om je uiteindelijke clusters te verkrijgen. Dit is nuttig wanneer je niet weet hoeveel natuurlijke onderwerpen je gegevens bevatten.

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')

Uitschieters en bijna-duplicaten vinden

Embeddings zijn ook uitstekend geschikt om bijna-gedupliceerde documenten te vinden. Bereken de paarsgewijze cosinusovereenkomst tussen alle documenten en markeer paren met een overeenkomst boven 0,95 als mogelijke duplicaten. Dit is robuuster dan tekstverschillen vergelijken, omdat het ook duplicaten met een andere formulering vindt.

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')

Praktische clusteringworkflow

Een echte clusteringworkflow volgt deze stappen in volgorde:

  1. Embed alle documenten met text-embedding-3-small
  2. Reduceer de gegevens optioneel met UMAP tot 50D voordat je clustert (dit versnelt k-means)
  3. Cluster met k-means en doorloop verschillende waarden van k om de beste silhouetscore te vinden
  4. Label elk cluster met een LLM aan de hand van 5 representatieve documenten
  5. Visualiseer de 2D-UMAP-spreidingsgrafiek, ingekleurd per cluster
  6. Controleer uitschieters (punten die ver van elk zwaartepunt liggen)

Beperkingen van clustering

Bij het clusteren van embeddings moet je rekening houden met belangrijke beperkingen:

  • K-means gaat uit van bolvormige clusters — langgerekte of onregelmatig gevormde onderwerpgroepen kunnen verkeerd worden gesplitst
  • Embeddings comprimeren betekenis — twee documenten kunnen semantisch dicht bij elkaar liggen, maar tot verschillende uitvoerbare categorieën behoren
  • Clusterlabels moeten worden gecontroleerd — neem altijd steekproeven van documenten uit elk cluster om het door de LLM gegenereerde label op redelijkheid te controleren

Gebruik clustering als hulpmiddel voor verkenning, niet als systeem voor categorisering dat als absolute waarheid geldt.

Korte controle

Test je begrip van de AI-engineeringconcepten uit deze les.

Samenvatting van de les

In deze les heb je geleerd dat k-means documenten groepeert op basis van semantische nabijheid in de embeddingruimte, dat UMAP embeddings met een hoge dimensionaliteit reduceert tot 2D voor visualisatie met behulp van cosinusafstand en dat de silhouetscore je helpt het juiste aantal clusters te kiezen zonder gelabelde gegevens. Hierna gaan we verder dan zoeken in het geheugen en verkennen we vector databases voor productieomgevingen.

Gratis beginnen

Leer Python met een AI-tutor — gratis

Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.

Cursussen
30
Lessen
120

Veelgestelde vragen

Is de les “Embeddings clusteren en visualiseren” gratis?

Ja — de volledige tekst van “Embeddings clusteren en visualiseren” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus AI Engineering Academy wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus AI Engineering Academy bevat in totaal 4 lessen.

Wat leer ik in “Embeddings clusteren en visualiseren”?

U past k-means-clustering toe op een verzameling embeddings en visualiseert deze in 2D met UMAP om natuurlijke onderwerpgroepen in uw data te ontdekken. Je oefent met AI Engineering Academy door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.

Heb ik ervaring nodig om met AI Engineering Academy te beginnen?

Ervaring vooraf is niet nodig. AI Engineering Academy op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 4 van 4.

Hoe lang duurt de les “Embeddings clusteren en visualiseren”?

De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.

Kan ik code schrijven en uitvoeren in deze les over AI Engineering Academy?

Ja. Elke les over AI Engineering Academy bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.

Alle lessen in deze cursus

  1. Wat zijn vector embeddings?
  2. Embeddings genereren met OpenAI
  3. Semantisch zoeken met NumPy
  4. Embeddings clusteren en visualiseren
← Terug naar AI Engineering Academy