inhaltsanalyse-mit-r.de

Dieses erste Kapitel liefert einen Überblick über zahlreiche Funktionen des Pakets quanteda, die gleichzeitig die Grundlage der automatisierten Inhaltsanalyse mit R bilden. Über quanteda hinaus werden im Verlauf dieser neunteiligen Einführung noch eine Reihe weiterer R-Bibliotheken verwendet, etwa für das Berechnen von Themenmodellen (Kapitel 5) und das überwachte maschinelle Lernen (Kapitel 6). In praktisch jeder Einheit relevant sind dabei die Pakete des tidyverse (vor allem ggplot, dplyr und stringr), durch die zahlreiche Funktionen wie Plotten, Textverarbeitung und Datenmanagement gegenüber den R-Basisfunktionen stark verbessert werden. Pakete für einzelne Teilbereiche, die erst später eine Rolle spielen werden, sind u.a. topicmodels und stm (Themenmodelle), RTextTools (überwachtes maschinelles Lernen), und spacyr (POS-Tagging und Named-Entity-Erkennung).

Die Basis der Analyse in diesem ersten Kapitel sind die beliebten Geschichten von Sherlock Holmes. Das Sherlock Holmes-Korpus besteht aus zwölf Erzählungen, die in dem 1892 erschienenem Band The Adventures of Sherlock Holmes zusammengefasst sind, und die man gemeinfrei unter anderem durch das Internet Archive herunterladen kann. Die für diese Einführung verwendete Fassung wurde zunächst dem Internet Archive entnommen und dann in zwölf Einzeldateien aufgeteilt. Natürlich können die vorgestellten Methoden auf die anderen hier behandelten Korpora angewandt werden – das Beispiel dient nur dazu, sich langsam an quanteda und die Grundlagen der computergestützen Inhaltsanalyse zu gewöhnen.

Sämtliche in dieser Einführung verwendeter Codebeispiele, Korpora und Lexika können hier heruntergeladen werden.

Installation und Laden der benötigten R-Bibliotheken

Zunächst werden die notwendigen Bibliotheken installiert (sofern noch nicht vorhanden) und anschließend geladen. Zudem wird vorbereitend die Theme-Einstellung für das Paket ggplot gesetzt (dies sorgt für hübschere Plots). Diesen Schritt wiederholen wir zu Beginn jedes Kapitels, daher wird auf ihn später nicht mehr weiter eingegangen. In einigen Kapiteln werden noch weiteren Pakete gelanden, etwa für eine erweiterte Farbpalette (RColorBrewer), Wortwolken (wordclouds) oder um URLs zu parsen (urltools).

# Installation und Laden der Bibliotheken
if(!require("quanteda")) install.packages("quanteda")
if(!require("readtext")) install.packages("readtext")
if(!require("tidyverse")) install.packages("tidyverse")
if(!require("RColorBrewer")) install.packages("RColorBrewer")
theme_set(theme_bw())

Einlesen der Daten und Anlegen eines Korpus

Nachdem alle notwendigen Pakete geladen wurden, können wir nun die Daten einlesen und daraus ein quanteda-Korpus erstellen. Für das Einlesen der Plaintext-Dateien wird die Funktion readtext aus dem gleichnamigen Paket verwendet, durch die sich eine Reihe von Dateiformaten erfolgreich importieren lassen (u.a. TXT, PDF und Word). Grundsätzlich sich Plaintext–Daten (i.d.R. mit der Endung “.txt”) und Daten in Tabellenform (etwa im Format CSV oder auch als Excel–Datei) für readtext ohne größere Probleme lesbar, allerdings muss man beim Einlesen erklären, wie genau die einzelnen Datensätze von einander getrennt sind (bei Plaintext–Dateien wo nicht 1 Datei == 1 Text, was etwa bei Exporten aus Lexis Nexis der Fall sein kann), bzw. welche Felder die Primär– und welche Metadaten beinhalten (bei Tabellen).

In diesem Fall entspricht jede Datei einem Text, wodurch der Import sehr umkompliziert ausfällt. Wir entfernen die Endung “.txt” aus dem Dokumentnamen, um diese später in Plot–Beschriftungen verwenden zu können. Schließlich wird die Variable korpus aufgerufen, was uns die wichtigen Eckdaten Dokumentanzahl und Docvars (Metadaten zu den Texten im Korpus) zurückliefert.

daten.sherlock <- readtext("daten/sherlock/romane/[0-9]*.txt") # Dateiname beginnt mit Zahl und endet mit .txt
daten.sherlock$doc_id <- str_sub(daten.sherlock$doc_id, start = 4, end = -5) # Dateiendung weglassen

korpus <- corpus(daten.sherlock, docid_field = "doc_id") # Korpus anlegen
docvars(korpus, "Textnummer") <- sprintf("%02d", 1:ndoc(korpus)) # Variable Textnummer generieren
korpus
## Corpus consisting of 12 documents and 1 docvar.

In den folgenden Abschnitten werden häufig bereits vorbereitete Korpora geladen, d.h. der Befehl corpus wird hier nicht mehr explizit ausgeführt. Er ist aber im Vorfeld ausgeführt worden, um aus Textdatein auf der Festplatte oder Twitter-Daten in einem R-Data Frame ein quanteda-Korpus zu erstellen.

Die Funktionen ndoc, ntoken, ntype und nsentence geben die Anzahl der Dokumente, Tokens, Types und Sätze aus. Diese Statistiken können bequem gemeinsam mit Metadaten auf Dokumentebene durch die Funktion summary erstellt werden. Bei den meisten Korpora, die hier verwendet werden, liegt ein solcher Data Frame mit Statistiken zu jedem Text bereits bei. Notwendig ist dies allerdings nicht. Will man auf Korpus–Metadaten zurückgreifen oder diese verändern, kann man dies jederzeit über den Befehl docvars tun.

korpus.stats <- summary(korpus, n = 1000000)
korpus.stats$Text <- reorder(korpus.stats$Text, 1:ndoc(korpus), order = T)
korpus.stats

Das Funktionsargument n = 1000000 wird hier nur deshalb verwendet, weil die Funktion summary ansonsten nur maximal 100 Texte zusammenfasst. In diesem Fall reicht das zwar aus, aber bei größeren Datensätzen ist das eher unpraktisch. Technisch gesehen heißt diese Funktion summary.corpus und ist eine an Korpus-Objekte angepasste Variante der Basisfunktion summary, die auch sonst in R verwendet wird. Der Befehl reorder wird verwendet, um die Texte nach ihrer Reihenfolge in The Adentures of Sherlock Holmes zu sortieren, statt alphabetisch nach Titel.

Basisstatistiken zu einem Korpus berechnen

Der Inhalt der Variable korpus.stats kann natürlich auch geplottet werden, um einen anschaulichen Eindruck von der Korpusbeschaffenheit zu geben. Die folgenden Zeilen liefern die Anzahl der Tokens (laufende Wörter), die Anzahl der Types (einmalige Wörter), und Sätze pro Roman zurück (vgl. dazu diese Einführung). Schließlich wird noch das Verhältnis von Typen zu Tokens (oder die sog. Typ-Token-Relation) geplottet.

Grundlage solcher Plots sind praktisch immer Data Frame-Objekte (also Tabellen), die Informationen über Korpora, Texte, Wörter, Themen usw. enthalten, welche sich visuell darstellen lassen. Im Rest dieser Einführung gehe ich nicht im Detail darauf ein, wie die jeweiligen Plots genau konstruiert werden, allerdings lassen sich die meisten Daten auch (etwas weniger ansprechend) mit der R-internen Funktion plot() darstellen. Eine hilfreiche deutschsprachige Einführung in das Plotten mit ggplot2 findet sich hier. Viele der hier vorgestellten Plots stammen zudem direkt aus quanteda (beginnend mit textplot_).

ggplot(korpus.stats, aes(Text, Tokens, group = 1)) + geom_line() + geom_point() + theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1)) + ggtitle("Tokens pro Roman")

ggplot(korpus.stats, aes(Text, Types, group = 1)) + geom_line() + geom_point() + theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1)) + ggtitle("Types pro Roman")