Machine Learning: Besser kategorisieren mit Topic Modeling
Seite 2: Vom Graph zu Hierarchie
Um aus dem Graphen eine Hierarchie zu erstellen, sortieren man die Kanten aufsteigend nach Distanz beziehungsweise MRD. Nun verbindet ein Algorithmus schrittweise diejenigen Punkte miteinander, die die gleiche Mutual Reachability Distance haben. Das Resultat lässt sich als Dendrogramm visualisieren.
DBSCAN, eine Variante von HDBSCAN, verwendet vereinfacht dargestellt das Dendrogramm, zieht eine horizontale Linie und selektiert alle Kanten als Cluster, die die Linie durchschneiden. Die Schwierigkeit liegt einerseits im Bestimmen der Linie. Andererseits ist auf die Weise das Ermitteln von Clustern mit unterschiedlichen Dichten schwierig.
HDBSCAN löst die Probleme durch das sogenannte Kondensieren des Baums. Von oben nach unten gelesen wird im Dendrogramm deutlich, dass häufig wenige Punkte die Cluster teilen. An der Stelle setzt HDBSCAN an: Statt Cluster zu teilen, verliert der Cluster einzelne Punkte. Bei jedem Split eines Clusters prüft die Methode, ob das neue Cluster die Minimum Cluster Size unterschreitet. In dem Fall behält sie das ursprüngliche Cluster bei und entfernt lediglich die Punkte. Ist das Cluster größer, teilt der Algorithmus es in zwei Cluster auf. Auf die Weise erhält man eine bessere Darstellung über die Cluster und deren Persistenz.
Abschließend selektiert die Methode die Cluster mit einer hohen Persistenz – diejenigen, die in der Darstellung besonders hervortreten. Bei der Auswahl gilt es zu beachten, dass der Algorithmus keine Cluster selektieren darf, deren Vorgänger er bereits selektiert hat.
Topics extrahieren mit c-TF-IDF
Um die Schlüsselwörter zu finden, die das Cluster charakterisieren, kommt mit c-Tf-idf eine Variante von Tf-idf zum Einsatz. Tf-idf ist insbesondere im Bereich der Verarbeitung natürlicher Sprache weit verbreitet, da es ein einfaches und robustes Verfahren ist, um Terme aus Texten zu extrahieren.
Tf steht für Term Frequency und beschreibt die Häufigkeit eines Worts innerhalb eines Textes. IDF bedeutet Inverse Document Frequency und gibt die Spezifität eines Worts im gesamten Textkorpus an. Je näher der Wert bei null ist, desto häufiger kommt das Wort und desto weniger Aussagekraft hat es. Stoppwörter wie "und", "der" und "die" haben beispielsweise einen sehr niedrigen Wert. Die Formel für den Wert lautet folgendermaßen:
N gibt die Anzahl der Dokumente im Korpus an. Die Summe im Nenner entspricht der Anzahl der Dokumente, die das Wort t enthalten. Durch das Kombinieren beider Werte ergibt sich eine Aussage über die Relevanz des Worts für ein Dokument. BERTopic wendet diese Metrik nun auf alle Dokumente des Korpus an. Dazu hängt er sie aneinander und ermittelt die Tf-idf Scores. Die Wörter mit den höchsten Scores sind die ermittelten Topics.
Die Suche nach den Hyperparametern
Wie in jedem Machine-Learning-Algorithmus gibt es auch bei BERTopic eine ganze Reihe an Parametern, um das Modell anzupassen. Diese Hyperparameter können das Ergebnis des Clustering und damit der resultierenden Topics wesentlich zum Positiven oder Negativen beeinflussen.
Die folgenden Beispiele sind im Notebook zum Artikel verfügbar. Als Grundlage dient der Datensatz 10kGNAD, der etwa 10.000 deutsche Nachrichtenartikel enthält, die in neun Themengebiete unterteilt sind.
Zu Beginn gilt es, die Texte durch ein geeignetes Embedding-Modell zu konvertieren. Es findet sich wie viele andere nützliche Modelle im Hub von Hugging Face und zwar bei den Sentence-Similarity-Modellen. Das Laden erfolgt über das Framework SentenceTransformers:
sentence_model =
SentenceTransformer("Sahajtomar/German-semantic", device="cuda")
Die encode
-Funktion des Modells kann den Text nun umwandeln. Je nach Größe des Modells, dem Umfang des Datensatzes und der Leistungsfähigkeit des verwendeten Systems kann das einigen Minuten in Anspruch nehmen. Empfehlenswert ist der Einsatz einer GPU.
Mit den generierten Vektoren lassen sich die Hyperparameter von UMAP optimieren. Folgende Methoden initialisieren das Modell zunächst mit den Hyperparametern und starten anschließend das Training:
umap_model = UMAP(n_neighbors=30, n_components=2,
min_dist=0.0, metric='cosine')
umap_model.fit(embeddings)
umap_embeddings = umap_model.transform(embeddings)
Der Parameter n_components
gibt an, wie viele Dimensionen der neue Projektionsraum haben soll. Für eine visuelle Evaluierung verwendet der Code zwei Dimensionen. Jenseits der Visualisierung, beispielsweise für das Topic Modeling bietet es sich jedoch durchaus an, diesen Wert zu verändern.
Der Parameter n_neighbours
gibt das Verhältnis zwischen den lokalen und den globalen Strukturen an. Bei einem niedrigen Wert behält das Modell mehr lokale Strukturen bei. Je größer der Wert ist, umso mehr fokussiert sich der Algorithmus auf globale Strukturen. Abbildung 6 zeigt den Vergleich zwischen dem Wert 2 und 20.
Ist der Wert zu niedrig eingestellt, lassen sich keine Cluster extrahieren, ist er dagegen zu hoch, erzeugt das Modell kaum abgrenzbare Bereiche mit einer hohen Dichte. Gute Startwerte sind 15 oder 20.
Schließlich erfolgt das Initialisieren und Trainieren von HDBSCAN:
clusterer = hdbscan.HDBSCAN(min_cluster_size=50)
clusterer.fit(umap_embeddings)
Anschließend lassen sich die gefundenen Cluster über clusterer.labels_
ausgeben. Der Parameter min_cluster_size
hat großen Einfluss auf das Ergebnis. Er bestimmt beim Kondensieren des resultierenden Minimum Spanning Tree den Grenzwert der Punkte, ab der das bestehende Cluster geteilt wird. Je kleiner der Wert ist, umso kleiner sind die endgültigen Cluster.
Der Parameter min_samples
geht mit dem Evaluieren der min_cluster_size
einher. Er bestimmt, wie viele Punkte in der Nachbarschaft sein müssen, damit ein Punkt als Core Point gilt. Über ihn lässt sich somit steuern, wie viele Punkte das Modell als Outlier (Kategorie -1) ansieht. Je höher der Wert, desto mehr Punkte verwirft das Modell.
Generell lässt sich ableiten: Je spezifischer Cluster sein sollen, desto niedriger müssen die beiden Parameter sein. Möchte man die globale Struktur als generelle Cluster abbilden, aber trotzdem die Details innerhalb der Cluster erhalten, sollte man einen hohen Wert für min_cluster_size
, aber einen niedrigen für min_samples
wählen.
Mit der finalen Extraktion der Schlüsselwörter für die jeweiligen Cluster durch c-Tf-IDF lässt sich der Einfluss der angesprochenen Parameter beobachten. Dazu kann man die Implementierung von BERTopic verwenden, muss jedoch einige interne Variablen anpassen. Näheres findet sich im Notebook zum Artikel.
Den größten Effekt hat min_cluster_size
: Je höher der Wert ist, desto weniger sind die Cluster spezifiziert, wodurch das Modell weniger und allgemeinere Topics findet. Wer eine hohe Zahl an Ausreißern erwartet, sollte den Parameter min_samples
erhöhen, damit sie als Outlier gekennzeichnet sind und nicht in das Clustering einfließen.
Die Metrik Density-based Clustering Validation (DBCV) kann ein guter Anhaltspunkt für das Evaluieren der Hyperparameter sein. Sie setzt sich aus zwei Komponenten zusammen: dem Bereich mit der geringsten Dichte innerhalb der Cluster und der Region mit maximaler Dichte zwischen den Clustern.
Diese Metrik lässt sich in einer Hyperparameter-Suche wie der Methode GridSearchCV
von scikit-learn verwenden, um einen ersten Anhaltspunkt für die Wahl der Parameter zu erhalten. Davon ausgehend lässt sich das Ergebnis je nach gewünschten Granularitäts-Level anpassen.