Schlüsselwörter

figure a

Menschen nutzen Sprache, um ihrem Leben Bedeutung zu geben. In den Sozial- und Geisteswissenschaften sind sprachliche Daten deshalb ein zentraler Untersuchungsgegenstand. Dabei kann es sich um extra für wissenschaftliche Zwecke erhobene Daten wie Interviews handeln, aber auch um Dokumente wie Pressemitteilungen, Inschriften auf Grabsteinen oder Postings auf Sozialen Netzwerkseiten. Mit automatisierten Textanalysen lässt sich die Bedeutung von Sprache zwar nur auf einer formalen Ebene erfassen, das aber kann sehr hilfreich sein. So können aus Wörtern und Sätzen systematisch Erkenntnisse destilliert werden, insbesondere um sich einen Überblick über unübersichtliche oder umfangreiche Textsammlungen zu verschaffen.

In Bezug auf Text lassen sich drei verschiedene Bereiche unterscheiden, bei denen Computer eine Rolle spielen (siehe auch Krippendorff 2013, S. 213):

  1. 1.

    Textanalyse: Texte können in ihre Bestandteile zerlegt und dann deskriptiv beschrieben werden. Hierzu zählen Verfahren wie Wortfrequenzanalyse (die Häufigkeit von Wörtern wird ausgezählt), Kollokationsanalysen (das gemeinsame Auftreten von Wörtern wird ausgezählt) oder Keyword-in-Context-Analysen (KWIC; die Umgebung von Schlüsselwörtern wird angezeigt). Gemeinsam ist diesen Verfahren, dass sie im Wesentlichen auf der Ebene von Textformen arbeiten, also Wörter ohne weitere Bedeutungszuschreibung und häufig auch ohne Berücksichtigung von Syntax – damit sind die sprachlichen Beziehungen zwischen den Wörtern und Zeichen gemeint – verarbeiten. Aus sprachwissenschaftlicher Sicht fallen diese Verfahren in den Bereich der Korpuslinguistik.

  2. 2.

    Inhaltsanalyse: Im sozialwissenschaftlichen Kontext sind häufig latente Konstrukte von Interesse, die im Zuge von Inhaltsanalysen mit manifesten Merkmalen gemessen werden (Merten 1995, S. 59). Ausgehend von Eigenschaften auf der Textoberfläche muss dann auf semantische oder pragmatische Sinngehalte geschlossen werden. Sentimentanalysen unterstellen beispielsweise, dass bestimmte Wörter als Indikatoren für positive oder negative Einstellungen stehen. Auch wenn ein Korpus auf eine geringe Menge an Themen reduziert werden soll (Clustering, Topic Modeling, siehe Abschn. 8.2), ist man auf der Suche nach den datengenerierenden Prinzipien hinter einem Text. Damit ist gemeint, dass nicht der Text selbst von Interesse ist, sondern die menschlichen Verhaltensweisen, die einen Text hervorgebracht haben oder die ein Text auslöst.

  3. 3.

    Annotation & Edition: Während bei Text- oder Inhaltsanalysen Teile der Analyse automatisiert werden, setzen insbesondere interpretative bzw. hermeneutische Verfahren auf intellektuelle Interpretation. Computer unterstützen dabei die Aufbereitung von Texten oder sind ein Hilfsmittel, um relevante Textstellen zu identifizieren, die dann manuell interpretiert werden. In den Geisteswissenschaften werden Editionen von Texten beispielsweise mit Oxygen als XML-Dokumente aufbereitet (SyncroSoft 2022). In den Sozialwissenschaften wird üblicherweise Software wie MAXQDA (VERBI Software 2021) oder ATLAS.ti (ATLAS.ti 2022) zur Organisation von Textkorpora eingesetzt. Textstellen werden markiert und verschlagwortet, diese sogenannten Codes oder Annotationen wiederum kommentiert.

In vielen Studien und Tools werden automatisierte und interpretative Verfahren kombiniert (Jünger et al. 2022). Im Folgenden geht es allerdings zunächst um die ersten beiden Punkte, das heißt um Textanalysen und Inhaltsanalysen.

1 Wortfrequenzanalysen

Wir lernen im Kindesalter, Sprache zu sprechen und gesprochene Sprache zu verstehen. Um gehörte Laute und gelesene Grapheme als Zeichen mit einer Bedeutung zu erkennen, ist ein jahrelanger, komplexer Lernprozess nötig. Zudem ist Sprache vielfältig und verändert sich fortlaufend, sodass die automatische Erkennung mit Computern keine leichte Aufgabe ist. Die Komplexität von Sprache kann für maschinenbasierte Analysen reduziert werden, indem Texte zunächst als Ansammlung von Wörtern behandelt werden – man spricht dann vom Bag-of-Words-Ansatz.

Um die Anzahl von Wörtern in einem Text zu ermitteln, wird zwischen Types und Token unterschieden (Peirce 1906, S. 506). Token (auch Terms genannt) bezeichnen dabei das konkrete Auftreten von Wörtern in einem Text – also aus wie vielen Einzelwörtern ein Text besteht. Die Types geben dagegen die verschiedenen Wortarten an – also aus wie vielen unterschiedlich geschriebenen Wörtern ein Text besteht. Die Sätze „Furcht ist der Pfad zur dunklen Seite. Furcht führt zu Wut, Wut führt zu Hass, Hass führt zu unsäglichem Leid.“ bestehen beispielsweise aus 20 Token und 13 Types.Footnote 1 Ein Datenformat, mit dem Types und Token erfasst werden können und das häufig die Grundlage für automatisierte Textanalysen ist, stellt die Document-Term-Matrix (allgemein auch Document-Feature-Matrix genannt) dar. In dieser Matrix ist jedes Dokument, etwa jeder Satz oder jeder Text, in einer Zeile erfasst. Die Spalten bestehen aus den Wörtern des gesamten untersuchten Korpus. In den Zellen ist dann festgehalten, ob bzw. wie oft ein Wort in einem Dokument auftaucht (Tab. 9.1).

Tab. 9.1 Eine Document-Term-Matrix

Dass durch die statistische Behandlung von Text Informationen verloren gehen, ist offenkundig. Im Gegensatz zum menschlichen „close reading“, bei dem die konzentrierte und schrittweise Lektüre von Äußerungen nach und nach zu einer Interpretation führt, geht es beim automatisierten „distant reading“ umgekehrt darum, aus aggregierten Verteilungen und Strukturen Sinn zu destillieren. Diese Vorgehensweise hat in der Literaturwissenschaft einen kritischen Diskurs in Gang gesetzt. Der Literaturwissenschaftler Franco Moretti, der diese Methoden populär gemacht hat, beschreibt eine solche Form der Analyse als „a little pact with the devil: we know how to read texts, now let’s learn how not to read them“ (Moretti 2013, S. 48). Sprachliche Äußerungen werden teilweise so in Einzelteile zerlegt, dass die Reihenfolge und die Zusammenhänge zwischen den Wörtern verloren gehen. Eine Filmkritik wie „nicht gut, sehr langweilig“ wird damit in die Wörter „nicht“, „gut“, „sehr“ und „langweilig“ zerteilt. Betrachtet man nur das reine Vorkommen der Wörter, dann ist dies gleichwertig zu „nicht“, „langweilig“, „sehr“ und „gut“. Zählt man die Adjektive in diesen Texten aus, würde die Anzahl für „gut“ und für „langweilig“ in beiden Fällen gleich sein.

Trotz des Informationsverlustes, oder vielleicht sogar gerade wegen der Konzentration auf die wesentlichen bedeutungstragenden Teile eines Textes, lassen sich allein mit Wortfrequenzanalysen durchaus hilfreiche Einsichten gewinnen. So kann man sich einen schnellen Überblick über umfangreiche Korpora verschaffen. Für diese Analysen gibt es spezialisierte Programme wie AntConc (Anthony 2022) und Sketch Engine (Lexical Computing 2022). Sie lassen sich aber auch mit Statistiksoftware wie R oder Python (siehe Kap. 5) umsetzen. Während auf Textanalyse zugeschnittene Programme einen guten Einstieg erlauben und durch die Benutzeroberflächen typische Analysen vorgeben, gewinnt man durch Programmiersprachen eine hohe Flexibilität, muss dafür aber jede einzelne Entscheidung bei der Textverarbeitung selbst treffen. Das folgende R-Skript verdeutlicht zunächst einige typische Schritte, die in dieser oder ähnlicher Form am Beginn jeder Textanalyse stehen.

Schritt 1: Texte einlesen

Im Gegensatz zu fertigen Datensätzen liegen Textkorpora häufig als einzelne Textdateien oder auch als Word- oder PDF-Dateien vor. Diese Dateien lassen sich mit der Funktion readtext() aus dem gleichnamigen Package einlesen (Benoit et al. 2021). Angenommen alle Dateien liegen als UTF8-kodierte Textdateien (siehe Abschn. 3.2) vom Projektverzeichnis aus gesehen im Unterordner korpus, dann können sie wie folgt eingelesen werden (☛ Repositorium):Footnote 2

library(readtext) texte <- readtext("korpus", encoding = "UTF-8")

Das Ergebnis ist eine Tabelle mit den Dateinamen in der ersten Spalte und dem Inhalt der jeweiligen Datei in der zweiten Spalte (Tab. 9.2). Schauen Sie sich für diese und die im Folgenden verwendeten Funktionen die Hilfe an.Footnote 3 Es gibt zahlreiche Optionen für vielfältige Eventualitäten.

Tab. 9.2 Ausschnitt des eingelesenen Textkorpus in RStudio

Schritt 2: Texte tokenisieren

Im nächsten Schritt werden die Texte in einzelne Sätze, Wörter oder andere Einheiten zerlegt. Die einzelnen Einheiten werden Token genannt, der Vorgang entsprechend Tokenisierung. Eine gute Wahl für erste eigene Versuche ist die Funktion unnest_token() aus dem Package tidytext (Silge und Robinson 2016). Der erste Parameter gibt den Dataframe mit den Texten an. Der zweite Parameter bestimmt den Namen der Output-Variable, das heißt, wie die Spalte mit den einzelnen Wörtern heißen soll. Der dritte Parameter bestimmt schließlich den Namen der Input-Spalte, die den zu zerlegenden Text enthält:

library(tidytext) woerter <- unnest_tokens(texte, wort, text)

Aus dem oben angeführten Beispiel wird eine neue Tabelle erstellt. Der Dateiname bleibt in der ersten Spalte doc_id erhalten, in der zweiten Spalte wort werden untereinander die einzelnen Wörter der entsprechenden Datei aufgeführt (Tab. 9.3).

Tab. 9.3 Ausschnitt des Outputs nach der Tokenisierung von Texten in Wörter

Diese Funktion kann auch dazu genutzt werden, den Text in größere Einheiten wie Sätze sowie in kleinere Einheiten wie Zeichen zu zerlegen. Dafür wird innerhalb der Funktion der Parameter token verwendet (zum Beispiel token="sentence"); voreingestellt ist dieser Parameter auf token="words".Footnote 4

Schritt 3: Texte bereinigen

Im Zusammenhang mit der Tokenisierung werden die Daten häufig bereinigt. Typischerweise zählen dazu folgende Schritte, die aber an die konkrete Fragestellung angepasst werden müssen:

  • Groß- oder Kleinschreibung: Durch die Funktion unnest_token() werden alle Wörter in Kleinschreibung umgewandelt. Das ist in der Regel sinnvoll, da etwa Adjektive am Satzanfang großgeschrieben werden, ohne dass dies einen inhaltlichen Unterschied zu kleingeschriebenen Wörtern innerhalb eines Satzes darstellt. Für ein Computerprogramm würde es sich sonst um zwei unterschiedliche Zeichenfolgen handeln.

    Mit dem Parameter to_lower=F kann die Voreinstellung verändert werden. Falls die Daten erst später in Kleinschreibung umgewandelt werden sollen, hilft die Funktion str_to_lower() aus dem Package stringr weiter (Wickham 2019a). Das folgende Beispiel bettet diese Funktion in ein typisches Tidyverse-Muster mit Zuweisungsoperator <-, Pipe %>% und mutate()-Funktion ein (siehe Abschn. 5.1):

    woerter <- woerter %>% mutate(wort = str_to_lower(wort, locale = "de"))

    Die Angabe locale="de" stellt zusätzlich sicher, dass Umwandlungskonventionen an der deutschen Sprache orientiert sind.

  • Zahlen und Sonderzeichen: Auch die anderen Funktionen aus dem Package stringr sind sehr hilfreich für die Aufbereitung von Texten. Zahlen und Sonderzeichen lassen sich bei Bedarf mit regulären Ausdrücken (siehe Abschn. 4.1.1) entfernen. Der Ausdruck [0-9]+ würde zum Beispiel alle Zahlen finden oder der Ausdruck ^[a-zäöüß]+$ alle Zeichenketten, die von Anfang (Caret ^) bis Ende (Dollar $) ausschließlich aus den angegebenen Kleinbuchstaben bestehen. In Kombination mit den Funktionen filter() zum Filtern von Zeilen und str_detect() zum Entdecken der Zeichenketten lassen sich mit diesem Ausdruck alle Wörter mit Sonderzeichen entfernen (bzw. diejenigen ohne Sonderzeichen behalten):

    woerter <- woerter %>% filter(str_detect(wort, "^[a-zäüöß]+$"))

  • Stoppwörter: Die häufigsten Wörter in einem Text sind häufig am wenigsten interessant. Dazu zählen vor allem Artikel wie „der“ oder „ein“. Diese für eine Analyse unbedeutenden Wörter werden Stoppwörter genannt und in der Regel vor der Auswertung entfernt. Eine Liste typischer deutscher Stoppwörter liefert die Funktion stopwords() aus dem gleichnamigen Package (Benoit, Muhr und Watanabe 2021):

    library(stopwords) stopwords("de")

    Die ersten neun Stoppwörter in dieser Liste lauten:

    [1] "aber" "alle" "allem" [4] "allen" "aller" "alles" [7] "als" "also" "am"

    Eine Möglichkeit zum Abgleich der Wörtertabelle mit einer solchen Liste besteht darin, die Liste der Stoppwörter zunächst in ein Dataframe bzw. Tibble umzuformen:

    stoppwoerter <- tibble(wort = stopwords("de"))

    Anschließend kann ein anti_join()Footnote 5 verwendet werden, um nur diejenigen Datensätze zu behalten, die nicht in der Stoppworttabelle enthalten sind. Im Beispiel wird die Spalte wort in beiden Tabellen so abgeglichen, dass in der Wörtertabelle nur Zeilen beibehalten werden, die nicht in der Stoppworttabelle zu finden sind:

    woerter <- woerter %>% anti_join(stoppwoerter, by = "wort")

    Diese Technik kann auch verwendet werden, um eine eigene Liste mit Stoppwörtern einzubinden. Dazu können Sie die Stoppwörter als CSV-Datei anlegen, in R einlesen und mit dem tokenisierten Datensatz abgleichen.

  • Stemming und Lemmatisierung: Wenn man nicht an den konkreten Wortformen interessiert ist, sondern nur an den semantischen Dimensionen, wird man die Wörter in der Regel auf ihren Wortstamm reduzieren. Dieses sogenannte Stemming entfernt grammatisch bedingte Endungen. So wird aus den Wörtern „Hauses“ und „Häusern“ das Wort „Haus“ oder aus den Verben „läuft“ und „laufen“ wird „lauf“. Das Package SnowballC (Bouchet-Valat 2020) liefert eine entsprechende Funktion für die deutsche Sprache:

    library(SnowballC) woerter <- woerter %>% mutate(stem = wordStem(wort, language = "de"))

    Anstelle von Stemming wird mitunter eine Lemmatisierung vorgenommen. Der Unterschied besteht darin, dass alle Wörter nicht auf den Stamm, sondern auf die Grundform zurückgeführt werden. So wird aus „läuft“ der Infinitiv „laufen“, was sich bei der Ausgabe leichter interpretieren lässt.

  • Relative pruning: Statt festgelegte Stoppwörter zu entfernen, können die häufigsten und seltensten Wörter entfernt werden und zum Beispiel nur Wörter beibehalten werden, die in mindestens 1 % und maximal 99 % der Texte vorkommen. Insbesondere wenn statistische Modelle (z. B. Topic Modeling, siehe Abschn. 8.2) erstellt werden, ist dieser Schritt sinnvoll. Denn Wörter, die in sehr vielen Texten vorkommen, können nicht zur Unterscheidung der Texte verwendet werden. Wenn Modelle darauf aufbauen, dass Wörter gemeinsam in einem Dokument auftreten (Kookkurrenz, siehe unten), sollten auch die sehr seltenen Wörter entfernt werden, denn sie eignen sich nicht gut zur Schätzung typischer Kombinationen. Zum Bestimmen der häufigen und seltenen Wörter können die im Folgenden beschriebenen Verfahren zum Auszählen der Wörter verwendet werden.

Mit diesen fünf Aufbereitungsschritten gehen einerseits Informationen verloren. Andererseits wird der Text bereits auf wesentliche Elemente reduziert. Weitere teils aufwendigere Maßnahmen zur Textaufbereitung umfassen die Auflösung von Synonymen oder die Desambiguierung gleichlautender Wörter. Auch eine Kategorisierung von Wortarten ist mitunter angebracht (POS-Tagging, siehe unten).

Schritt 4: Wörter auszählen

Ist ein Text erst einmal in die Form eines Datensatzes überführt und aufbereitet worden, kann die Auswertung mit statistischen Funktionen beginnen. Am einfachsten ist das Auszählen von Worthäufigkeiten:

woerter %>% count(wort, sort = T)

Der Parameter sort=T sorgt dafür, dass die häufigsten Wörter zuerst ausgegeben werden (Tab. 9.4).

Tab. 9.4 Die häufigsten Wörter im Beispielkorpus

Da es sich hierbei um einen Dataframe handelt, kann das Ergebnis in einem neuen Objekt abgelegt und bei Bedarf als CSV-Datei exportiert werden. Das Ergebnis kann auch für Visualisierungen verwendet werden. Welche Wörter in einem Korpus besonders häufig auftauchen, lässt sich schnell in Wordclouds erkennen. Das Package ggwordcloud (Le Pennec und Slowikowski 2019) ist eine Erweiterung des Visualisierungspackages ggplot2, mit dem solche Wordclouds in R erstellt werden können (siehe Abschn. 5.1.5). Damit die Grafik nicht mit allen Wörtern des Korpus überladen wird, lohnt es sich, nur die häufigsten Wörter abzubilden. Mit der Funktion slice_head() lässt sich der Output der count()-Funktion auf die oberen Zeilen einschränken – beispielsweise durch die Angabe n = 50 auf die Top-50 der häufigsten Wörter:

topterms <- woerter %>% count(wort, sort = T) %>% slice_head(n = 50)

Die Wordcloud kann anschließend als ggplot2-Grafik erstellt werden. Dabei werden, wie bei ggplot2 üblich, zunächst über die Funktion aes() die Daten den visuellen Merkmalen zugeordnet. Die Wörter werden als label übergeben. Der optionale Parameter size legt fest, wovon die Größe der Wörter in der Wordcloud abhängen soll – im Beispiel von den ausgezählten Häufigkeiten n, sodass häufigere Wörter größer dargestellt werden als seltenere Wörter. Über den Parameter color lässt sich die Farbe zuordnen. An diese Ausgangsdefinition werden mit einem + weitere Schichten der Grafik angehängt. Die Verwandlung in eine Wordcloud übernimmt die Funktion geom_text_wordcloud(). Es folgen weitere Formatierungen, im Beispiel die maximale Größe der Wörter und das Theme mit einer Angabe der Basisschriftgröße:

topterms %>% ggplot(aes(label = wort, size = n, color = n)) + geom_text_wordcloud() + scale_size_area(max_size = 15) + theme_bw(base_size = 10)

Die Wordcloud wird in RStudio ausgegeben und kann mithilfe der Funktion ggsave()abgespeichert werden (Abb. 9.1).

Abb. 9.1
figure 1

Wordcloud mit den häufigsten 50 Wörtern des Beispielkorpus. (Quelle: eigene Darstellung)

Schritt 5: Kookkurrenz

Eine einfache Häufigkeitsanalyse ist vor allem vergleichend interessant, etwa um in der Berichterstattung den Wandel der Themen und des Sprachgebrauchs über Jahrzehnte zu verfolgen oder wenn man die Öffentlichkeitsarbeit von Organisationen (PR) der publizistischen Berichterstattung (Journalismus) gegenüberstellen will. Aufschlussreich ist aber nicht nur der Vergleich verschiedener Dokumente untereinander, sondern auch der Zusammenhang von Wörtern innerhalb der Texte. Eine einfache Analysemöglichkeit besteht darin, das gemeinsame Auftreten von Wörtern in einem Dokument auszuzählen (Kookkurrenz).Footnote 6 Nach der Tokenisierung liegt zunächst eine lange Tabelle vor, in der in einer Spalte doc_id der Dateiname des Statements und in einer anderen Spalte wort das Wort steht. Nun kann mit der Funktion pairwise_count() aus dem widyr-Package ausgezählt werden, in wie vielen Dokumenten verschiedene Wörter gemeinsam vorkommen (Robinson et al. 2021):Footnote 7

library(widyr) kookkurrenz <- woerter %>% pairwise_count(wort, doc_id)

Sortiert man das Ergebnis nach der Häufigkeit, offenbaren sich typische Zusammenhänge. Im Beispiel (Tab. 9.5) zeigt sich, dass die Begriffe „daten“ und „werbung“ sehr häufig zusammen auftreten.

Tab. 9.5 Kookkurrenz von Wörtern im Beispielkorpus (Auszug)

Diese reine Häufigkeitsauszählung sagt noch wenig darüber aus, ob die häufigen Wörter oder die gefundenen Kookkurrenzen in dem Sinne bedeutsam sind, dass sie häufiger sind als typischerweise zu erwarten wäre. Das lässt sich hier gut daran erkennen, dass Wörter wie „dass“ oder „jedoch“ sehr häufig in Kombination mit anderen Wörter vorkommen – die verwendete Stoppwortliste ist im Beispiel nicht ideal.Footnote 8 So ist es wahrscheinlich, dass auch im alltäglichen Sprachgebrauch das Wort „dass“ häufig verwendet wird und dementsprechend auch häufig mit dem Wort „daten“ zusammen auftritt – ohne dass dies direkt auf eine Anomalie hindeutet. Neben inferenzstatistischen Verfahren, bei denen die statistische Signifikanz geprüft wird, lässt sich die Auffälligkeit von einzelnen Wörtern mittels Tf-idf-Werten und die Bedeutsamkeit von Kookkurrenzen mithilfe von PMI-Werten berechnen.

Das Tf-idf-Maß gibt an, wie spezifisch ein Wort für jedes einzelne Dokument ist, sodass sich je Dokument die im Vergleich zu allen anderen Dokumenten auffälligen Wörter bestimmen lassen. Der Wert setzt sich aus der Häufigkeit eines Wortes in einem Dokument (tf = term frequency) und der Häufigkeit aller Dokumente mit diesem Wort (df = document frequency) zusammen. Je höher die Term Frequency ist, umso häufiger kommt das Wort in einem Dokument vor. Ein Wert von 0,06 für das Wort „anzeigen“ in Dokument 31 besagt, dass dieses Wort 6 % aller Wörter in diesem Dokument ausmacht (Tab. 9.6). Die Document Frequeny gibt an, in wie vielen Dokumenten des Korpus das Wort enthalten ist und wird durch Logarithmieren und Invertieren (idf = inverse document frequency) zu einem Gewichtungsfaktor umgerechnet, der dann mit der Term Frequency multipliziert wird.Footnote 9 Je höher dieser Gewichtungsfaktor ist, desto seltener ist das Wort in allen Dokumenten. Dadurch werden die seltenen Wörter hochgewichtet und die sehr häufigen Wörter heruntergewichtet. Das daraus hervorgehende Tf-idf-Maß ist dann umso höher, je spezifischer das Wort für das Dokument ist.

Tab. 9.6 Beispiele für Tf-idf-Werte in einem Beispielkorpus zum Thema Daten

Auf diese Weise lassen sich in den einzelnen Dokumenten die jeweils bedeutsamen Wörter bestimmen. Ein hoher Tf-idf-Wert für das Wort „datenweitergabe“ in Text 47 würde besagen, dass dieser Text sich anders als die anderen Texte besonders mit diesem Aspekt beschäftigt. Gleichzeitig erhalten gängige und unspezifische Wörter wie „dass“ oder „jedoch“ einen geringen Wert, weil sie in einer Vielzahl von Dokumenten vorkommen. Darüber lassen sich also auch nach der Datenaufbereitung weitere korpusspezifische Stoppwörter identifizieren und ggf. ausfiltern. Interessant ist eine solche Berechnung vor allem dann, wenn man verschiedene Artikel vergleichen oder besonders relevante Artikel identifizieren will.

In R hilft das Package tidytext bei der Berechnung von Tf-idf. Grundlage ist zunächst, dass man die Anzahl der Wörter je Dokument auszählt, dann kann die Funktion bind_tf_idf() daraus die entsprechenden Werte berechnen:

tfidf <- woerter %>% count(wort, doc_id) %>% bind_tf_idf(wort, doc_id, n)

Tf-idf quantifiziert damit die Beziehung zwischen Dokumenten und Wörtern. In Bezug auf auffällige Kookkurrenzen, das heißt die Beziehung zwischen zwei Wörtern, ist dagegen die Berechnung von Pointwise Mutual Information (PMI) hilfreich (siehe auch Bouma 2009). Ein hoher PMI-Wert besagt, dass zwei Wörter häufiger gemeinsam auftreten als zu erwarten wäre. Auch hierfür wird das gesamte Korpus als Vergleichsmaßstab herangezogen. Nehmen wir an, ein Korpus besteht aus 5000 Wörtern, das Wort „daten“ kommt darin 100-mal vor und das Wort „computer“ 50-mal. Dann beträgt die Auftretenswahrscheinlichkeit für „daten“ 100/5000 = 0,02. Die Auftretenswahrscheinlichkeit für „computer“ liegt bei 50/5000 = 0,01. Die Wahrscheinlichkeit, dass beide Wörter gemeinsam auftreten, kann dann durch Multiplikation berechnet werden und beträgt also 0,02 × 0,01 = 0,0002. Kommt diese Kombination nun aber tatsächlich häufiger vor, so ist sie potenziell bedeutsam. Um die Bedeutsamkeit zu quantifizieren, wird die tatsächliche zur erwarteten Wahrscheinlichkeit ins Verhältnis gesetzt. Durch Logarithmieren wird das Verhältnis 1,0 (wenn die Wahrscheinlichkeiten gleich sind) zu einem PMI von 0, Verhältnisse darunter werden zu negativen und darüber zu positiven Werten.

Die PMI kann zum einen auf Grundlage von Kookkurrenz in Dokumenten berechnet werden, aber auch auf Grundlage von Wortkombinationen. Solche Wortkombinationen werden als N-Gramme bezeichnet, wobei das N die Anzahl der Wörter angibt. Ein Unigram oder 1-Gram bezeichnet einzelne Wörter, ein Bigram oder 2-Gram die Abfolge von zwei Wörtern und ein Trigram bzw. 3-Gram die Sequenz aus drei Wörtern.Footnote 10 Bei der Tokenisierung von Text lassen sich demnach nicht nur Unigramme erzeugen, sodass jedes Wort getrennt wird, sondern auch andere N-Gramme. Auf diese Weise geraten die syntaktischen Zusammenhänge zwischen Wörtern etwas stärker in den Blick; der Bag-of-Words-Ansatz wird gelockert, indem Wortkombinationen analysiert werden.

Wie bei der Kookkurrenz von Wörtern in einem Dokument lässt sich berechnen, inwiefern Bigramme häufiger vorkommen als zu erwarten wäre. Eine solchermaßen signifikante Wortkombination wird auch Kollokation genannt. Bei der praktischen Umsetzung kann man zweistufig vorgehen und zunächst die Bigramme extrahieren und nummerieren. Anschließend werden die Bigramme wieder in einzelne Wörter zerlegt, um die Kookkurenz der Wörter innerhalb der Bigramme auszuzählen:

# Bigramme extrahieren bigrams <- texte %>% unnest_tokens(bigram, text, token = "ngrams", n = 2) # Kollokationen zählen bigrams <- bigrams %>% mutate(bigram_no = row_number()) %>% unnest_tokens(wort, bigram) %>% pairwise_count(wort, bigram_no)

Daraus lassen sich dann der Anteil des Bigrams am Korpus, der Anteil der einzelnen Wörter an allen Wörtern und schließlich die Pointwise Mutual Information berechnen. Das tatsächliche Auftreten eines Bigrams wird wieder ins Verhältnis zum zufällig erwartbaren Auftreten gesetzt, welches auf Grundlage geschätzter Einzelwahrscheinlichkeiten der Wörter berechnet wird. Daraus wird durch Logarithmieren die PMI gewonnen. Negative Werte weisen auf Kombinationen hin, die seltener als erwartbar auftreten, und positive Werte zeigen überzufällig häufige Kombinationen an:

bigrams <- bigrams %>% # Auftretenswahrscheinlichkeit p des Bigrams mutate(p = n / sum(n)) %>% # Auftretenswahrscheinlichkeit p1 für Wort 1 group_by(item1) %>% mutate(n1 = sum(n)) %>% ungroup() %>% mutate(p1 = n1 / sum(n)) %>% # Auftretenswahrscheinlichkeit p2 für Wort 2 group_by(item2) %>% mutate(n2 = sum(n)) %>% ungroup() %>% mutate(p2 = n2 / sum(n)) %>% # Berechnung von pmi mutate(pmi = log(p / (p1 * p2)))

Im hier verwendeten Beispielkorpus treten die Wörter „bereich“ und „kritischen“ jeweils nur ein- bzw. zweimal innerhalb eines Bigrams auf. Dass ausgerechnet diese beiden Wörter dann in einer Kombination auftreten, wäre bei vollständiger Unabhängigkeit nicht zu erwarten und führt deshalb zu einem hohen PMI (Tab. 9.7). Dennoch muss man bei der Interpretation von solch seltenen Kombinationen zurückhaltend sein – eine Aussage, die auf lediglich einer Kombination beruht, ist kaum belastbar. Solche Einzelfallkombinationen kommen prinzipbedingt durchaus oft vor, im Beispielkorpus finden sich über 18.000 singuläre Bigramme. Das rührt daher, dass die meisten Wörter in einem Korpus eher selten vorkommenFootnote 11 und jedes Wort aber natürlich auch immer in mindestens einer Kombination steht. Erst wenn man sich in höheren Bereichen umschaut – etwa Bigramme, die mindestens drei-, fünf- oder zehnmal vorkommen – gewinnt man eine etwas bessere Interpretationsgrundlage.

Tab. 9.7 Beispiele für Bigramme in einem Beispielkorpus zum Thema Daten

Eine noch robustere Einschätzung liefern Zusammenhangsmaße, bei denen solche Einzelfälle auf Grundlage weiterer statistischer Überlegungen zum Informationsgehalt von seltenen Wörtern und Kombinationen aussortiert werden. In der Computerlinguistik verbreitet ist das Log-Likelihood-Ratio (LLR, auch G2 genannt; siehe Dunning 1993), mit dem der Überraschungswert einer Kookkurrenz berechnet wird (☛ Repositorium). Hierdurch lassen sich etwa Kombinationen wie „daten verwendet“, „daten verkauft“ oder „jedoch weitergegeben“ finden, die durchaus typisch für den untersuchten Anwendungsbereich erscheinen.

Die drei angesprochenen Werte – Tf-idf, PMI und LLR – sind vergleichsweise einfache Verfahren, um sich einen Überblick über Wörter und Kombinationen in einem Text zu verschaffen. Grundlegend ist stets, dass das Vorkommen von Wörtern in Texten ausgezählt wird. Zu beachten ist, dass weder häufige Wörter noch seltene Kombinationen automatisch bedeutsam sind, sondern eine statistische und interpretative Einordnung vorgenommen werden muss.

Schritt 6: Keywords-in-Context

Für weitere interpretative Schritte lohnt sich ein Blick in das Package quanteda (Benoit et al. 2022). Die vorher mit readtext() oder anderen Verfahren eingelesenen Texte werden in ein Korpus-Objekt umgewandelt und können dann mit vorbereiteten Auswertungsfunktionen analysiert werden. Die Funktion kwic() (= keywords in context) zeigt beispielsweise den KotextFootnote 12 zu ausgewählten Schlüsselwörtern an, das heißt vorangegangene und folgende Wörter. Das folgende Beispiel gibt die Kotexte des Worts „Daten“ aus:

# Dateien aus dem Ordner korpus laden texte <- readtext("korpus", encoding = "UTF-8") # In quanteda-Corpus umwandeln texte <- corpus(texte) # Überblick über das Korpus summary(texte) # Tokenisierung token <- tokens(texte) # Keywords-in-Context zum Wort "daten" kwic_daten <- kwic(token, "daten")

Damit wird ein Dataframe erzeugt, der in RStudio als durchsuchbare Liste aufbereitet wird und so einen schnellen Überblick über den Kontext von ausgewählten Schlüsselwörtern erlaubt (Tab. 9.8).

Tab. 9.8 Keywords-in-context-Analyse für das Wort „Daten“

Das Package quanteda ebnet darüber hinaus mit einer Vielzahl von weiteren Funktionen den Weg zu elaborierten Verfahren automatischer Textanalyse, etwa wenn Topic Modeling zum Extrahieren der Themenstruktur eines Korpus eingesetzt werden soll (siehe Abschn. 8.2), und auch zu Visualisierungstechniken wie Wordclouds. Für eine Einführung in quanteda ist das Quickstart-Tutorial des Packages empfehlenswert.Footnote 13

Die bislang besprochenen Verfahren zeichnen sich allesamt dadurch aus, dass sie zwar harte Zahlen über die Verteilung von Wörtern oder Kombinationen in einem Korpus liefern, dabei aber immer explorativ und interpretationsbedürftig sind. Die Berechnung von Wortfrequenzen, Wahrscheinlichkeiten, Tf-idf-Werten, Kookkurenzen oder Pointwise Mutual Information unterstützt vorrangig die inhaltliche Auseinandersetzung mit einem Korpus, um einen Überblick über typische und seltene Fälle zu erhalten, sowie die Datenaufbereitung.

2 Diktionärbasierte Inhaltsanalyse

Führt man sich die Entstehung von Texten vor Augen, dann stellt ein Text immer nur eine Realisation von vielen äquivalenten Möglichkeiten dar. Die Abneigung oder Zustimmung zu einem Sachverhalt kann beispielsweise auf ganz unterschiedliche Weise ausgedrückt werden. Menschen haben einen umfangreichen Wortschatz lobender oder beleidigender Wörter und können sich mal einfach und mal elaboriert ausdrücken. Themen wie Datenschutz, die Entstehung der Menschheit oder Wahlen lassen sich auf sehr unterschiedliche Weise besprechen. Während die bislang dargestellte Herangehensweise – Auszählen von Wörtern – bei den konkreten Texten startet und auf Bedeutungen schließt, geht eine diktionärsbasierte Inhaltsanalyse umgekehrt vor. Hier stehen am Anfang der Analyse sogenannte latente Konstrukte wie Einstellungen, Themen oder auch spezielle Konstrukte wie Inzivilität und Diskursqualität, die dann im zweiten Schritt so operationalisiert werden, dass manifeste sprachliche Äußerungen als Indikator für diese Konstrukte verwendet werden. Latente Konstrukte umfassen also die nicht direkt messbaren Prozesse und Zustände, von denen man annimmt, dass sie hinter den beobachtbaren, manifesten sprachlichen Zeichen stehen. Der Vorgang, die latenten Konstrukte messbar zu machen, wird Operationalisierung genannt (Döring und Bortz 2016, S. 224).

Eine einfache Möglichkeit der Operationalisierung besteht darin, eine Reihe von Wörtern festzulegen, die beispielsweise für eine positive oder eine negative Einstellung stehen. Diese Form der Analyse, bei der die Valenz von Texten bestimmt wird, nennt sich Sentimentanalyse. Hierfür stehen einige wenige in wissenschaftlichen Projekten bereits erprobte Wörterbücher zur Verfügung. Ein deutschsprachiges Wörterbuch ist der SentimentWortschatz (Goldhahn et al. 2012), welcher von der Projektseite der Universität Leipzig heruntergeladen werden kann.Footnote 14 Die Daten gehen auf eines der ersten Digital-Humanities-Projekte zur automatisierten Textanalyse zurück. Das Diktionär des Programms General Inquirer (Stone et al. 1966) wurde mit Wörtern aus Zeitungskorpora unter Zuhilfenahme von Verfahren wie Kookkurrenzanalyse ergänzt und schließlich durch menschliche Kodierer:innen überprüft. In diesem Diktionär sind zu jeweils einem Lemma die Wortart (= PoS; Part-of-Speech), ein negativer bis positiver Sentimentwert und flektierte Wortformen enthalten (Tab. 9.9). Verbindet man diese Wortliste mit den Wörtern in einem tokenisierten Text, lässt sich die Anzahl positiver oder negativer Wörter in einem Text als Indikator für die Valenz des Textes verstehen. Dass diese einfache Grundidee eine Reihe von Komplexitäten birgt, wird das folgende R-Beispiel verdeutlichen.Footnote 15

Tab. 9.9 Beispiele für negative und positive Wörter aus dem SentiWS

Schritt 1: Texte einlesen

Lesen Sie zunächst wie oben beschrieben das Korpus ein, tokenisieren Sie die Texte und führen Sie ein Stemming durch:

texte <- readtext("korpus", encoding = "UTF-8") woerter <- unnest_tokens( texte, wort, text, to_lower = T ) %>% mutate(stem = wordStem(wort, language = "de"))

Im Ergebnis liegt ein Dataframe woerter vor, in der ersten Spalte wird für jeden Text eine doc_id vermerkt und in der letzten Spalte stem sind fortlaufend die Wortstämme enthalten.

Schritt 2: Wörterbuch einlesen

Das Diktionär (☛ Repositorium) muss für den Abgleich auf die gleiche Weise wie das Textkorpus vorbereitet werden, das heißt, die Lemmata werden in Kleinschreibung umgewandelt und auf die Wortstämme zurückgeführt:

sentiws <- read_csv("sentiws/SentiWS20.csv", na = "") sentiws <- sentiws %>% mutate(wort = str_to_lower(lemma)) %>% mutate(stem = wordStem(wort, language = "de"))

Dadurch entsteht ein Dataframe, der unter anderem eine Spalte stem und zu jedem Wortstamm in der Spalte sentiment einen Sentimentwert zwischen −1 und +1 enthält. Durch die Aufbereitung ist es möglich, dass ein Wortstamm doppelt, aber mit unterschiedlichen Sentiments, auftritt. Damit eine eindeutige Zuordnung zwischen den Texten und dem Diktionär möglich ist, können Sie die Wortstämme so zusammenfassen, dass nur das mittlere Sentiment verzeichnet ist. Das leistet die Funktion summarise() in Kombination mit mean(), wobei die Zusammenfassung mit group_by() für jeden Wortstamm getrennt durchgeführt wird (dieses Muster wird in Abschn. 5.1 erklärt):

sentiws_mean <- sentiws %>% group_by(stem) %>% summarise(sentiment = mean(sentiment)) %>% ungroup()

Zur weiteren Vereinfachung der Analyse wird noch eine neue Spalte sent_pos eingeführt, in der mit den Wahrheitswerten TRUE und FALSE (kurz: T und F) vermerkt wird, ob es sich um ein Wort mit einem positiven oder negativen Sentimentwert handelt:

sentiws_mean <- sentiws_mean %>% mutate(sent_pos = ifelse(sentiment > 0, T, F)) %>% mutate(sent_neg = ifelse(sentiment < 0, T, F))

Im nächsten Schritt kann ausgezählt werden, wie viele Wörter in einem Text positiv oder negativ konnotiert sind. Diese Vorbereitungsschritte für das Korpus und das Diktionär zeigen bereits auf, dass eine Sentimentanalyse häufig stark vereinfachend vorgeht und entsprechend vorsichtig interpretiert werden muss. Die Ambivalenz von Wörtern (wenn sie gleichzeitig positive und negative Aspekte beinhalten) und auch Synonyme (wenn ein Wort verschiedene Bedeutungen hat) werden geglättet. Eine solche automatisierte Textanalyse ist zwar objektiv in dem Sinne, dass sie sich unabhängig von den ausführenden Wissenschaftler:innen wiederholen lässt. Trotzdem ergibt sich die Bedeutung von Wörtern, Sätzen und Texten aus dem Wechselspiel von Mitteilung und Rezeption und kann deshalb nicht nur von Rezipient:in zu Rezipient:in unterschiedlich ausfallen, sondern auch ein und die gleiche Person kann morgens zu einer anderen Einschätzung kommen als am Abend.

Schritt 3: Wörter den Texten zuordnen

Sind Korpus und Wörterbuch auf die gleiche Art und Weise aufbereitet, können die beiden Tabellen verbunden werden. Jedem Wort aus den Texten lässt sich über einen left_join() ein Eintrag aus dem Wörterbuch zuordnen, indem die Spalte stem abgeglichen wird (zu Joins siehe Abschn. 4.2.2):

woerter_sentiment <- woerter %>% left_join(sentiws_mean, by = "stem")

Das Ergebnis besteht aus einem Dataframe, in den ersten Spalten finden sich die Daten aus der Wörterliste in doc_id und wort, in den letzten Spalten die Angaben sentiment und sentpos aus dem Diktionär, dazu die Spalte stem, über die der Abgleich vorgenommen wurde. Betrachtet man einen Ausschnitt aus dem Ergebnis (Tab. 9.10), fällt auf, dass nicht alle Wörter im Diktionär verzeichnet sind – im verwendeten Beispielkorpus lassen sich 17 % der Wörter zuordnen. Darunter sind viele Wörter wie „Firmen“, denen sich nicht ohne Weiteres eine Tendenz zuordnen lässt, aber auch Wörter wie „Hackerangriff“, die zwar intuitiv positiv bzw. negativ bewertet werden können, die aber für das Diktionär zu speziell sind. Während einige Zuordnungen wie ein negatives Sentiment zum Wort „verletzt“ durchaus gut nachvollziehbar sind, treten auch Unschärfen auf. Das Wort „schon“ wird durch die Zurückführung auf einen Wortstamm mit dem gleichen Sentiment wie das Wort „schön“ belegt. Und das als positiv erkannte Wort „größeren“ ließe sich je nach Kontext auch negativ interpretieren, etwa wenn es um einen größeren Schaden geht.

Tab. 9.10 Zuordnung von Wörtern zu Sentiments (Auszug)

Schritt 4: Auswertung

Unschärfen bedeuten nicht zwangsläufig, dass keine sinnvollen Aussagen getroffen werden können. Wichtig ist vor allem, dass jedes Wort lediglich als Indikator verstanden wird – wenn viele Indikatoren gleichzeitig betrachtet werden, gleichen sich die Fehlzuordnungen in die positive oder negative Richtung im besten Fall aus. Deshalb werden die Sentiments im nächsten Schritt so zusammengefasst, dass für jeden Text die Anzahl aller Wörter n_token, die Anzahl positiv erkannter Wörter n_pos und die Anzahl negativ erkannter Wörter n_neg ausgezählt wird. Im folgenden Beispiel wird dazu ein Trick angewendet: Der Wahrheitswert TRUE wird bei der Addition automatisch in 1 umgewandelt, sodass sich als Summe der Wahrheitswerte die Anzahl der in den Spalten sent_pos bzw. sent_neg mit TRUE gekennzeichneten Fälle ergibt. Mit na.rm=T werden die fehlenden Werte ignoriert. Daraus lässt sich für jedes Dokument der Anteil positiv erkannter Wörter p_pos und negativ erkannter Wörter p_neg berechnen:

texte_sentiment <- woerter_sentiment %>% group_by(doc_id) %>% summarize( n_token = n(), n_pos = sum(sent_pos, na.rm = T), n_neg = sum(sent_neg, na.rm = T), p_pos = n_pos / n_token, p_neg = n_neg / n_token ) %>% ungroup()

Schlussendlich entsteht ein Dataframe, in dem für jeden Text der Umfang positiver und negativer Wörter verzeichnet ist, was sich gut visualisieren lässt. Trägt man den Anteil positiver Wörter auf der X-Achse und die negativen Wörter entsprechend auf der Y-Achse ab, kann jedes Dokument als Punkt eingetragen werden:

texte_sentiment %>% ggplot(aes(x = p_pos, y = p_neg)) + geom_point()

Es zeigt sich dabei wieder, dass die Welt nicht schwarz und weiß ist (Abb. 9.2). Texte können eindeutig negativ (links oben) oder positiv (rechts unten) eingeordnet werden, aber eine Vielzahl an Dokumenten bleibt ambivalent (rechts oben) oder indifferent (links unten), weil gleichzeitig positive und negative Bewertungen vorgenommen werden bzw. nur wenige bewertende Wörter enthalten sind.

Abb. 9.2
figure 2

Sentiments eines Beispielkorpus. (Quelle: eigene Darstellung)

Der Mittelwert positiver Sentiments liegt mit 0,13 deutlich über dem Wert von 0,04 für das mittlere negative Sentiment (in der Grafik durch Linien gekennzeichnet). Ob das tatsächlich darauf hindeutet, dass die meisten der befragten Studierenden – das Korpus umfasst Reflexionstexte zum Thema Datenschutz – eine positive Einstellung ausdrücken, ist allerdings fraglich. Bei der Interpretation sollte besser vergleichend vorgegangen werden. Im Vergleich zu anderen Texten lassen sich über- oder unterdurchschnittlich positive oder negative Texte identifizieren. Auf diese Weise können nicht nur tendenziell positivere oder negativere, sondern eben auch unentschiedene oder mehrdeutige Texte für eine weitere Analyse identifiziert werden.

Das am Beispiel einer Sentimentanalyse verdeutlichte Prinzip lässt sich mit entsprechenden Wörterbüchern auf andere Anwendungsfälle übertragen. Häufig verwendet wird beispielsweise das LIWC-Diktionär (Linguistic Inquiry and Word Count), in dem psychologische Kategorien wie etwa Emotionen operationalisiert sind.Footnote 16 Die deutsche Version des LIWC ist für wissenschaftliche Analysen bei den Autoren erhältlich (Wolf et al. 2008). Auch für spezielle und aktuelle Fälle wie die Erkennung von Hate Speech werden fortlaufend Diktionäre entwickelt,Footnote 17 wobei entsprechende Daten häufig zunächst für die englische Sprache vorliegen und damit nicht ohne Übersetzung für deutschsprachige Analysen eingesetzt werden können. Es lassen sich aber auch eigene Wörterbücher entwickeln – um aus größeren Textkorpora relevante Texte auszuwählen, reichen mitunter einfache Stichwortlisten.

3 Syntax und Semantik

In den vorangegangenen Abschnitten wurden als Analyseeinheiten immer nur einzelne Wörter und Wortkombinationen betrachtet. Sprache besteht allerdings nicht aus isolierten Wörtern, die Wörter stehen zueinander in Beziehung und diese Beziehungen vermitteln Informationen, die für ein Verständnis von Texten nötig sind. Löst man sich bei der automatisierten Textanalyse von einzelnen Wörtern und betrachtet diese im Kontext von anderen Wörtern, kommen Syntax und Semantik in Spiel. Syntax beschreibt die Regeln, nach denen Wörter und Sätze zusammengebaut werden, während sich die Semantik damit beschäftigt, was diese Wörter und Sätze bedeuten (Bußmann 1990, S. 672, 766). Unter dem Stichwort Natural Language Processing (NLP) werden Verfahren der automatisierten Textanalyse zusammengefasst, die syntaktische und semantische Strukturen berücksichtigen. Zwar stoßen automatisierte Verfahren zum Verarbeiten menschlicher Sprache immer auch an Grenzen, die im Folgenden angesprochenen Methoden gehören aber mittlerweile zum Standardrepertoire der Computational Methods.

3.1 Natural Language Processing

Ein erster Schritt, um über den Bag-of-Words-Ansatz hinauszugehen, besteht darin, die Wortarten zu berücksichtigen. Beim sogenannten Part-of-Speech-Tagging (POS-Tagging) werden beispielsweise Artikel und Substantive unterschieden (einführend zum Beispiel Martinez 2012). Diese Information kann hilfreich sein, um nur bedeutungstragende Wortarten (Substantive, Verben, Adjektive) in eine Analyse einzuschließen, anstatt eine Liste von Stoppwörtern auszuschließen. Das Bestimmen der Wortarten ist allerdings nicht trivial, wie man sich an der Unterscheidung von Substantiven und Verben vor Augen führen kann. Auch wenn es etwa naheliegen mag, Substantive und Verben zum Beispiel anhand der Groß- und Kleinschreibung zu unterscheiden, reicht dieses Unterscheidungskriterium allein nicht aus. Verben werden im Deutschen am Satzanfang großgeschrieben, in der konzeptionell mündlichen Sprache von Online-Chats finden sich kleingeschriebene Substantive und in Sprachen wie dem Englischen kann ein kleingeschriebenes „walk“ sowohl den Spaziergang als auch spazierengehen bezeichnen. Deshalb werden im besten Fall automatisierte Klassifikationsverfahren eingesetzt, die über einfache Regelformulierungen hinausgehen (siehe Abschn. 8.2). Ein Spezialfall des POS-Taggings ist das Erkennen von Eigennamen durch Named-Entity-Recognition (NER). Dieses automatische Klassifikationsverfahren dient der Identifizierung von Personen, Orten oder Organisationen in Texten.

Wortarten ergeben sich teilweise aus den Beziehungen zwischen Wörtern. Im Deutschen stehen etwa Artikel immer vor den Substantiven, sie treten in der Regel nicht unabhängig voneinander auf. Führt man den Gedanken weiter, so lässt sich die gesamte syntaktische Struktur eines Satzes rekonstruieren. Dependenzparser (einführend zum Beispiel Nederhof und Satta 2010) bilden die Satzstruktur so in einem Baum ab, dass die Abhängigkeiten zwischen den Wörtern sichtbar werden (Abb. 9.3). Betrachtet man die Verbindungen von Adjektiven und Substantiven, so lassen sich Prädikationen wie „personalisierte Werbung“ finden. Im Deutschen bilden Verben den Mittelpunkt von Aussagen, Verbalkonstruktionen können zur Rekonstruktion von Handlungen und EreignissenFootnote 18 herangezogen werden, wie sie in den Teilsätzen „unsere Daten werden benutzt“ oder „die Dienste profitieren davon“ formuliert sind. Eine Alternative zum Dependenzparsing besteht darin, einen Satz so in seine Bestandteile zu zerlegen, dass einzelne voneinander abhängende Phrasen identifizierbar werden. Diese sogenannten Konstituenten (constituency parsing) helfen dabei, Nebensätze oder indirekte Rede zu identifizieren.

Abb. 9.3
figure 3

Dependenzparsing. Der Satz wurde mit spacyR geparsed und mit ggraph visualisiert. (Quelle: eigene Darstellung)

Wörter stehen nicht nur in syntaktischer, sondern auch in semantischer Relation zueinander. Das wird etwa bei Synonymen sichtbar: „Apfelsine“ und „Orange“ bezeichnen den gleichen Gegenstand, sie werden mit einem Bag-of-Words-Ansatz aber als unterschiedliche Wörter behandelt. In der automatisierten Sprachanalyse können zur Lösung dieses Problems Word Embeddings eingesetzt werden. Jedes Wort wird dabei durch einen Vektor von Eigenschaften repräsentiert (Turney und Pantel 2010). Beispielsweise sind Apfelsinen und Orangen beide essbar, Steine dagegen nicht. Diese Eigenschaft kann man indirekt aus dem sprachlichen Kontext erschließen. So sind die Kombinationen „Orangen essen“ oder „Apfelsinen essen“ erwartbar und unterscheiden sich von einem sprachlichen Kontext wie „Steine werfen“. Die Bedeutung eines Wortes ergibt sich also aus dessen Verwendung – diese Erkenntnis wird als Distributionshypothese bezeichnet: „You shall know a word by the company it keeps“ (Firth 1962, S. 11).

Analysiert man die Verwendung von Wörtern in großen Textkorpora, so lassen sich daraus Dimensionen gewinnen, auf denen sich Wörter verorten lassen – die sogenannten Word Embeddings. Für jedes Wort wird ein Vektor mit Eigenschaften gebildet. In der Textanalyse kann dann mit diesen in Zahlen ausgedrückten Dimensionen anstelle der Wörter weitergearbeitet werden. Werden Wörter durch Vektoren repräsentiert, lassen sich auch Ähnlichkeiten bestimmen. So sollten sich die Vektoren von „Apfel“ und „Orange“ ähnlicher sein als die Vektoren von „Apfel“ und „Stein“. Multilinguale Word Embeddings, bei denen zum Beispiel „book“ und „Buch“ durch ähnliche Vektoren erfasst sind, ermöglichen zudem sprachübergreifende Analysen. Auch Gegensätze lassen sich ermitteln, wenn zwei Wörter in vielen Dimensionen ähnlich, in einigen Dimensionen aber gegenteilig sind. Ein klassisches Beispiel dafür ist die Beziehung zwischen den Wörtern „König“ und „Königin“, die sich lediglich im Geschlecht unterscheiden (Pennington et al. 2014, S. 1532). Um weitere Beziehungen zwischen Begriffen, insbesondere über- und untergeordnete Begriffe (Hyperonyme und Hyponyme), zu berücksichtigen, können zudem strukturierte Ontologien eingesetzt werden, wie sie etwa von WordNetFootnote 19 entwickelt wurden (siehe auch Abschn. 3.7).

3.2 Textanalyse mit spaCy

Die meisten der genannten Techniken lassen sich vergleichsweise unkompliziert mit etablierten Packages für R oder Python umsetzen. Diese Packages parsen einen Text, das heißt, sie legen ihn in einem Datenformat ab, das die ursprüngliche Struktur des Textes abbildet und ggf. um zusätzliche Informationen wie Part-of-Speech-Tags ergänzt. Zahlreiche Funktionalitäten stellt beispielsweise die Open-Source-Software spaCy bereit.Footnote 20 SpaCy ist für Python entwickelt worden, lässt sich aber dank des spacyR-Package (Benoit und Matsuo 2020) gut in R nutzen.Footnote 21

Benötigt wird für spacyR eine Python-Distribution – installieren Sie sich zunächst die Python-Distribution Miniconda. Wenn Sie bereits eine Anaconda-Distribution (siehe Abschn. 5.2) auf Ihrem Computer eingerichtet haben, können Sie diesen Schritt überspringen. Anschließend installieren und laden Sie in R das Package spacyr. Über die Funktion spacy_install() wird automatisch eine virtuelle Conda-Umgebung mit Python und spaCy eingerichtet:Footnote 22

library(spacyr) spacy_install()

Beim Parsen greift SpaCy auf vortrainierte Modelle zurück (siehe Abschn. 8.1 zu den Grundlagen automatisierter Klassifikation). Ein deutsches Sprachmodell können Sie mit folgendem Befehl herunterladen:

spacy_download_langmodel("de")

Sind alle Komponenten heruntergeladen und installiert – diese Schritte müssen nur einmalig durchlaufen werden –, kann der Parser mit dem deutschen Sprachmodell initialisiert werden. SpaCy ist dann eingerichtet und einsatzbereit:

spacy_initialize(model = "de_core_news_sm")

Wenn Sie Texte mit der readtext()-Funktion einlesen, können diese anschließend an die Funktion spacy_parse() übergeben werden, um Wortarten oder Dependenzstrukturen zu bestimmen:

library(tidyverse) library(readtext) texte <- readtext("korpus", encoding = "UTF-8") txt_parsed <- spacy_parse(texte, dependency = TRUE)

Der Output enthält im Dataframe txt_parsed die tokenisierten und annotierten Texte (Tab. 9.11). Jedes einzelne Token innerhalb eines Satzes wurde in der Spalte token_id durchnummeriert, lemmatisiert und in der Spalte pos mit einer Wortart versehen. Die verwendeten Bezeichnungen stammen aus dem TIGER-Annotationsschema.Footnote 23 Die syntaktische Struktur der Sätze ist in den Spalten head_token_id und dep_rel erfasst. Erstere enthält die ID des syntaktisch übergeordneten Tokens, letztere eine Klassifikation der Beziehung. Im Beispiel wird etwa das Hilfsverb „werden“ (token_id = 3) als Wurzelelement (root) des Satzes identifiziert, davon hängt das Verb „benutzt“ (head_token_id = 3) ab. Das Wort „Daten“ wird in der Spalte deep_rel als Subjekt (sb) des Satzes gekennzeichnet.

Tab. 9.11 Ergebnis des Parsings mit SpaCy

Auch wenn ein linguistisches Grundwissen für die Arbeit mit diesen Daten hilfreich ist, lassen sich schnell einfache Analysen anschließen. Ermitteln Sie die häufigsten Wortarten, filtern Sie bedeutungstragende Wortarten heraus oder extrahieren Sie Phrasen rund um das Wort „Daten“!

Übungsfragen

  1. 1.

    Worin unterscheiden sich Textanalyse und Inhaltsanalyse?

  2. 2.

    Welche Vor- und Nachteile ergeben sich aus dem Bag-of-Words-Ansatz?

  3. 3.

    Suchen Sie sich zwei beliebige Sätze aus diesem Kapitel und bestimmen Sie die Anzahl der Types und der Token!

  4. 4.

    Welche Schritte werden bei der Aufbereitung von Texten typischerweise durchgeführt?

  5. 5.

    Was versteht man unter Tokenisierung?

  6. 6.

    Finden Sie heraus: Wie kann ein Text mit R in einzelne Sätze zerlegt werden?

  7. 7.

    Wie lassen sich PDF-Dateien mit R einlesen?

  8. 8.

    Was ist der Unterschied zwischen einem Unigram und einem Trigram?

  9. 9.

    Was sagt der Tf-idf-Wert aus und wofür kann er verwendet werden?

  10. 10.

    Wie kann die Kookkurrenz von Wörtern bestimmt werden?

  11. 11.

    Was versteht man unter POS-Tagging und unter NER?

  12. 12.

    Was ist ein Dependenzparser?

Weiterführende Literatur

  • Aggarwal, C.C. (2018). Machine learning for text. Cham: Springer.

  • Aggarwal, C.C., & Zhai, C. (Hrsg.) (2012). Mining text data. New York: Springer.

  • Lemke, M. & Wiedemann, G. (Hrsg.) (2016). Text Mining in den Sozialwissenschaften: Grundlagen und Anwendungen zwischen qualitativer und quantitativer Diskursanalyse. Wiesbaden: Springer.

  • Grimmer, J., Roberts, M. E. & Stewart, B. M. (2022). Text as data: A new framework for machine learning and the social sciences. Princeton: Princeton University Press.

  • Silge, J. & Robinson, D. (2017). Text mining with R. A tidy approach. Beijing: O’Reilly. http://tidytextmining.com

  • Wiedemann, G. (2016). Text Mining for Qualitative Data Analysis in the Social Sciences. A Study on Democratic Discourse in Germany. Wiesbaden: Springer.