Skip to content
Snippets Groups Projects
Commit 748ff5e3 authored by Sonja Huber's avatar Sonja Huber
Browse files

Merge branch 'top2vec_integration' into 'master'

Top2Vec integration

See merge request !13
parents c9b609ae ac31e874
No related branches found
No related tags found
1 merge request!13Top2Vec integration
......@@ -30,4 +30,5 @@ Ausserdem gibt es die Möglichkeit die komplexere Methode "TWEC" kennenzulernen.
### Topic Modeling
Hier kannst du dir Topic Modeling Modelle zu vorgegebenen oder eigenen Parameteren erzeugen lassen.
Hier kannst du dir Topic Modeling Modelle zu vorgegebenen oder eigenen Parameteren erzeugen lassen.
Dazu stehen dir zwei Methoden zur Verfügung: Entweder mit dem gensim LDA-Modell oder mit Top2Vec.
In diesem Ordner findest du eine Anleitung und ein Skript zum Topic Modeling.
Zum Topic Modeling stehen dir hier zwei Möglichkeiten zur Verfügung: einmal Topic Modeling mit einem gensim-LDAmodel und einmal mit Top2vec.
Top2vec eignet sich in etwa ab der Grössenordnung 4000 Swissdox-Artikel.
### Vorbereitung
......@@ -46,7 +47,12 @@ im folgenden Abschnitt erklärt wird.
### Inhalte dieses Ordners
Dieser Ordner enthält zwei Skripte:
Dieser Ordner enthält einen Ordner und zwei Skripte:
**top2vec**
Hier findest du Erklärungen, Skripts zur Erstellung, Visualisierung und
zum Durchsuchen deines Korpus nach Topics.
**vrt2docperline.py**
......
# Top2Vec
Top2vec ist ein Algorithmus basierend auf [diesem Paper](https://arxiv.org/abs/2008.09470), welcher in einem Vektorraum Word- und Document Embeddings erstellt und auf dieser Grundlage Topics berechnet und ebenfalls in diesem Vektorraum projiziert.
Ein grosser Vorteil dieser Methode ist, dass die Anzahl Topics nicht angegeben werden muss, sondern selbst vom Algorithmus bestimmt wird. Die Projiektion von Word-, Document- und Topic Embeddings in denselben Raum macht ausserdem viele übergreifende Abfagen möglich. Die [Dokumentation](https://top2vec.readthedocs.io/en/latest/Top2Vec.html#) und [API-Reference](https://top2vec.readthedocs.io/en/latest/api.html) zu studieren ist deshalb sehr empfehlenswert.
Gemäss einigen (allerdings nicht umfassenden) Tests gibt top2vec etwa ab Grössenordnung 4000 Swissdox-Artikel gute Resultate zurück. Je mehr Dokumente man im Input liefern kann, tendentiell mehr Topics werden erstellt, die entsprechend feingliedriger werden. Ausserdem können, wie weiter unten noch beschrieben wird, einige Parameter an die Grösse des vorliegenden Korpus angepasst werden. Ausprobieren kann sich lohnen.
### Installation
Top2Vec kann mit pip installiert werden:
```bash
`pip install top2vec`
```
auf **Windows** sind möglicherweise noch folgende Installationen nötig, um top2vec zu installieren:
1. python developer tools:
```bash
py -m pip install python-dev-tools —user —upgrade
```
2. VisualStudio build tools:
[direkter Downloadlink](visualstuido.microsoft.com/thank-you-downloading-visual-studio/?sku=BuildTools&rel=16)
um alle verschiedenen Varianten zu installieren, führe zudem folgende Befehle aus:
```bash
pip install top2vec[sentence_encoders]
pip install top2vec[sentence_transformers]
pip install top2vec[indexing]
```
bzw auf **Mac** in doppelten Anführungszeichen:
```bash
pip3 install "top2vec[sentence_encoders]"
pip3 install "top2vec[sentence_encoders]"
pip3 install "top2vec[sentence_encoders]"
```
für die Skripts brauchst du ausserdem, wenn nicht schon installiert:
```bash
pip install pandas
pip install plotly
```
## Skripts in diesem Ordner
⚠ Stellen im Code, welche geändert werden können oder müssen, sind mit *TODO* in einem Kommentar in der unmittelbaren Nähe markiert ⚠
- **top2vec_model.py**
Hiermit kannst du ein top2vec Modell von deinem Korpus erstellen. Das Format des Korpus sollte ein Dokument pro Zeile sein,
wie du es mit dem Skript [vrt2docperline.py](/4._Korpusanalyse/Topic_Modeling/vrt2docperline.py) erstellen kannst.
In der Zeile, wo das Modell erstellt wird, kannst du verschiedene Anpassungen im Skript machen:
- *embedding_model*: ohne Änderungen ist _doc2vec_ gewählt, was neue Word- und Document embeddings aufgrund deines Korpus
erstellt. Andere Optionen sind vortrainierte Modelle, zur Auswahl stehen _universal-sentence-encoder_, _universal-sentence-encoder-multilingual_, _distiluse-base-multilingual-cased_. Um zu entscheiden, welches für dein Korpus am besten
geeignet ist, liest du am besten die Beschreibung [hier](https://top2vec.readthedocs.io/en/latest/Top2Vec.html#pretrained-embedding-models-a-name-pretrained-a). Je nach Grösse und enthaltenen Sprachen kann ein anderes Modell besser sein.
- *speed* : falls _doc2vec_ als embedding modell gewählt wurde, kann man mit _speed_ noch die Geschwindigkeit und, daran gekoppelt, die Qualität der Embeddings bestimmen. Die drei Optionen sind _fast-learn_, _learn_ und _deep-learn_, wobei _deep-learn_ am längsten dauert aber die genauesten Ergebnisse liefert.
- *workers*: wie viele Threads gleichzeitig am Training arbeiten. Je mehr, desto schneller; allerdings hängt die Anzahl machbarer Threads von der "Stärke" (genauer, der Anzahl CPUs)deines Geräts ab. Neuere Macs und MacBooks (M2) sollten problemlos 6-8 worker laufen lassen können, schwächere oder ältere Geräte vielleicht nur 2-4. Du kannst im Task-Manager oder in der Aktivitätsanzeige
beobachten, wie viel Ressourcen das Programm benötigt, und wenn nötig anpassen.
- *min_count*: Die mindestanzahl die ein Wort erreichen muss, damit von diesem Wort ein Word Embedding entstehen, und entsprechend
in die Topics einfliessen kann. Im Skript ist defaultmässig 30 angegeben, auch hier kann man je nach Korpusgrösse und gewünschtem Resultat anpassen.
Für die Erstellung des Modelles gibt es noch weitere Parameter, welche du [hier](https://top2vec.readthedocs.io/en/latest/api.html), der erste Eintrag _class top2vec.Top2Vec.Top2Vec_ nachlesen kannst.
Ausführung nach gespeicherten Anpassungen:
```bash
python3 top2vec_model.py
```
- **top2vec_overview.py**
Dieses Skript gibt dir zu deinem Topic Modell
1. Ein CSV-Skript mit der Topic ID, der Worten, die in einem Topic vorkommen und der Anzahl Dokumente pro Dokument,
2. Ein Balkendiagramm erstellt mit plotly, welches die Verteilung über die einzelnen Topics anzeigt.
Auch in diesem Skript musst du vor der Ausführung einige Anpassungen machen. Diesmal sind es Dateipfade, Titel und Masse des Diagramms und einige optionale Änderungen.
Ausführung:
```bash
python3 top2vec_overview.py
```
- **top2vec_inspect_docs.py**
Mit diesem Skript kannst du die zu einem ausgewählten Topic zugehörigen Dokumente einsehen, es gibt dir zu deinem Topic Modell ein .txt file mit den Dokumenten, eines pro Zeile, aus.
Dazu musst du die Dateipfade, die ID des Topics (ablesbar im CSV-file oder im Diagramm) und optional die Anzahl der Dokumente, die ausgegeben werden sollen, spezifizieren. Standardmässig werden alle Dokumente eines Topics ins Outputfile geschrieben.
Die Anzahl Dokumente pro Topic findest du ebenfalls im CSV file oder im Balkendiagramm von _top2vec_overview.py_.
Ausführung:
```bash
python3 top2vec_inspect_docs.py
```
from top2vec import Top2Vec
# TODO Dateipfad zum Modell angeben
model = Top2Vec.load('Dateipfad/mein/top2vec/Modell.model')
topic_sizes, topic_nums = model.get_topic_sizes()
# TODO die ID des Topic of Interest eingeben, achtung, indexing beginnt bei 0. ablesbar in der Visualisierung
topic_of_interest = 0
number_of_docs_in_topic = topic_sizes[topic_of_interest]
# TODO Hier die Anzahl Dokumente angeben, die angezeigt werden soll. Default sind alle
document_count = number_of_docs_in_topic
print(document_count)
documents, doc_scores, doc_ids = model.search_documents_by_topic(topic_of_interest, document_count)
# TODO Dateipfad zum gewuenschten Outputfile angeben
with open('Dateipfad/zum/Outfile.txt', 'w', encoding='utf-8') as outfile:
outfile.write(str(documents[topic_of_interest]))
for doc in documents:
outfile.write(doc)
from top2vec import Top2Vec
def main():
# TODO hier den Dateipfad vom momentanen Standort zu deinem Korpus angeben. Format: .txt, ein Dokument pro Zeile.
docs = []
with open("Dateipfad/mein/Korpus.txt", "r", encoding="utf-8") as data_file:
for line in data_file.readlines():
docs.append(line)
#print(len(docs))
# TODO passe die Parameter an (siehe README oder Dokumentation)
model = Top2Vec(
docs, embedding_model="doc2vec", speed="deep-learn", workers=4, min_count=20
)
# TODO hier den Dateipfad zum Modell angeben. Format: .model
curr_model_path = "Dateipfad/mein/Modell.model"
model.save(curr_model_path)
if __name__ == "__main__":
main()
from top2vec import Top2Vec
import re
import plotly.express as px
import pandas as pd
def main():
# TODO pass den Dateipfad an, um dein erstelltes Modell zu laden
model = Top2Vec.load("Dateipfad/mein/top2vec/Modell.model")
# .get_topic_sizes() gibt eine Liste mit der Grösse der Topics im Korpus zurück, und eine mit den id's der Topics.
topic_sizes, topic_nums = model.get_topic_sizes()
"""
.get_topics() nimmt die Anzahl Topics des Modelles als Argument und gibt drei Listen zurück:
1. eine Liste mit einer Liste pro Topic mit den Top 50 Worten, die das Topic ausmachen
2. eine Liste mit einer Liste pro Topic mit der Cosinus Distanz jedes Wortes zum entsprechenden Topic-Embedding
3. eine Liste mit den IDs der Topics
"""
topic_words, word_scores, topic_nums = model.get_topics(model.get_num_topics())
# TODO pass den Dateipfad zum gewuenschten csvfile an.
csv_path = "Dateipfad/CSVfile/.csv"
with open(csv_path, "w", encoding="utf-8") as csv_out:
csv_out.write("topic_number,words_in_topic,number_of_documents\n")
for topic_num in topic_nums:
string_topic_words = re.sub(r"[\n,\[,\]]", " ", str(topic_words[topic_num]))
#print(string_topic_words)
csv_out.write(
f"{topic_num},{string_topic_words},{topic_sizes[topic_num]}\n"
)
"""
Visualisierung:
Balkendiagramm aus den Topics und ihrer Anzahl.
Anpassbar sind der Titel und die Beschriftungen der Achsen in .update_layout,
die Groesse des Diagramms in .update_layout,
die Breite der Balken in .update_traces,
die Anzahl angezeigter Worte pro Topic, momentan 7.
"""
topic_df = pd.read_csv(csv_path)
# TODO passe die Anzahl der angezeigten Worte pro Topic an, momentan 7, falls gewünscht
shortened_words = topic_df["words_in_topic"].str.split().str[:7].apply(" ".join)
short_words_with_ind = []
for ind, words in enumerate(shortened_words):
new_words = words + " :" + str(ind)
short_words_with_ind.append(new_words)
fig = px.bar(
topic_df,
x=topic_df["number_of_documents"],
y=short_words_with_ind,
orientation="h",
color="number_of_documents",
)
# TODO passe den Titel und evtl. die Achsenbeschriftungen an
fig.update_layout(
title="Balkendiagramm: Beispieltitel",
xaxis_title="Topics",
yaxis_title="Anzahl Dokumente",
yaxis={"categoryorder": "total ascending"},
)
# TODO passe die Breite der Balken und die Groesse des Diagramms an, falls gewünscht
fig.update_traces(width=0.85)
fig.update_layout(width=1400, height=1200)
fig.show()
if __name__ == "__main__":
main()
......@@ -56,8 +56,10 @@ Hier ist eine Übersicht im Detail:
* Anleitung [**Visualisierung mit tensorflow**](4._Korpusanalyse/Word_Embeddings/Visualisierung_mit_tensorflow.md)
* Skript [**wvec2tsv.py**](4._Korpusanalyse/Word_Embeddings/wvec2tsv.py)
* Anleitung zu [**TWEC**](4._Korpusanalyse/Word_Embeddings/TWEC) (**T**emporal **W**ord **E**mbeddings with a **C**ompass)
* Topic Modelling: Skript und Beispielanalyse
* Skript [**topic_modeling.py**](4._Korpusanalyse/Topic_Modeling/topic_modeling.py)
* Topic Modelling: gensim LDA-Modell oder top2vec
* Skript [**topic_modeling.py**](4._Korpusanalyse/Topic_Modeling/topic_modeling.py)
* Skript [**vrt2docperline.py**](4._Korpusanalyse/Topic_Modeling/vrt2docperline.py)
* Ordner [**top2vec**](4._Korpusanalyse/Topic_Modeling/top2vec/)
5. Zugriff DeReKo:
* Skript [**KorAp_test.py**](5._Zugriff_DeReKo/KorAp_test.py)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment