In diesem zweiten Kapitel steht nun die Analyse vor Wörtern und Texten im Mittelpunkt. Auf den ersten Blick erscheinen die Metriken, die hier vorgestellt werden, möglicherweise nicht als besonders relevant für sozialwissenschaftliche Fragestellung. Das liegt zum einen daran, das wir uns an dieser Stelle noch nicht mit abstrakten Konzepten wie Themen oder Sentiment beschäftigen, die in den folgenden Kapitel im Mittelpunkt stehen werden, sondern mit Aspekten wie der Frequenz von Begriffen und der Ähnlichkeit von Texten, die augenscheinlich vielleicht der Linguistik näher sind. Wort- und Textmetriken sind aber aus zwei Gründen von Bedeutung: erstens bilden sie die Grundlage der höherstufigen Verfahren, egal ob Lexikon-, Themen- oder Sentimentanalyse, und zu anderen lassen sich auch schon mit ihnen interessante sozialwissenschaftliche Fragestellungen bearbeiten.

Einige Beispiele:

Diese und ähnliche Fragen werden in den folgenden Kapiteln aufgegriffen – zunächst werden aber die Funktionen vorgestellt, welche die Arbeit mit Wörtern und Texten in Quanteda ermöglichen. Dazu ziehen wir neben den bereits bewährten Sherlock Holmes-Daten auch zwei weitere Korpora heran.

Installation und Laden der benötigten R-Bibliotheken, Laden des Korpus, Berechnen einer DFM

Zunächst werden wieder die notwendigen Bibliotheken geladen. Das Paket scales kommt hier neu dazu, um unkompliziert Variablen reskalieren zu können.

if(!require("quanteda")) {install.packages("quanteda"); library("quanteda")}
if(!require("tidyverse")) {install.packages("tidyverse"); library("tidyverse")}
if(!require("scales")) {install.packages("scales"); library("scales")}
if(!require("ggdendro")) {install.packages("ggdendro"); library("ggdendro")}
theme_set(theme_minimal())

Nun wird in einem zweiten Schritt das Sherlock-Korpus geladen, welches wir bereits im ersten Kapitel mittels readtext aus dem Rohtext erstellt und als RData-Datei gespeichert haben. In der RData-Datei ist nebem dem Korpus selbst auch eine mit summary erstellter Data Frame enthalten, welcher die Korpus-Metadaten enthält. Zum einen sparen wir uns so das Anlegen eines Korpus, zum anderen ist das RData-Format komprimiert, was sich bei Textdaten durchaus bei der Dateigröße bemerkbar macht.

Als nächstes berechnen wir dann auf Grundlage des Quanteda-Korpus-Objekts wieder eine DFM (vgl. Kapitel 1), da wir diese später noch benötigen.

load("daten/sherlock/sherlock.korpus.RData")
meine.dfm <- dfm(korpus, remove_numbers = TRUE, remove_punct = TRUE, remove_symbols = TRUE, remove = stopwords("english"))

Korkordanzen erstellen

Zu den einfachsten Funktionen von Quanteda gehört die Möglichkeit, Konkordanzen (auch KWIC genannt) zu erstellen, also die Textstelle eines Suchterms sowie dessen umgebenden Satzekontext zu extrahieren. Strenggenommen gehört diese Funktion nicht in den Bereich der Wort- und Textmetriken, wir behandeln sich aber hier, und nicht im ohnehin sehr umfangreichen ersten Kapitel, da wie auch bei den Wortmetriken bei Konkordanzen der Umgang mit Wörtern und ihr Kontext im Mittelpunkt steht.

Konkordanzen lassen sich in Quanteda für einzelen Wörter, aber auch für ganze Phrasen erzeugen. Oftmals ist der Export einer Konkodanz (etwa als CSV-Datei, die mit Excel geöffnet werden kann) neben der Darstellung innerhalb von R besonders nützlich. Dies geschieht hier mit der Funktion write_delim().

Anmerkung: Die Konkordanz kann mit dem kleinen Pfeil rechts oben gescrollt werden.

konkordanz <- kwic(korpus, "happy")
konkordanz

Konkordanzen bestehen aus den Metadaten (Textname und Position), dem linken Kontext, dem Suchterm, sowie dem rechten Kontext. Die erste Konkordanz enthält alle Vorkommnisse des Begriffs ‘data’ im Korpus.

konkordanz <- kwic(korpus, phrase("John|Mary [A-Z]+"), valuetype = "regex", case_insensitive = FALSE)
konkordanz
konkordanz <- kwic(korpus, c("log*", "emot*"), window = 10, case_insensitive = FALSE)
konkordanz
write_delim(konkordanz, path = "konkordanz.csv", delim = ";") # Datei ist Excel-kompatibel

Die zweite Konkordanz enthält Vorkommnisse der Namen ‘John’ und ‘Mary’ gefolgt von einem weiteren Wort in Großschreibung (i.d.R. der Nachname). Die dritte Konkordanz enthält schließlich die Wortfragmente ‘log’ und ‘emot’, also Wörter wie ‘logical’ und ‘emotional’, aber auch die Pluralform ‘emotions’. Strenggenommen handelt es sich hierbei nicht um Wortstämme, weil die Flexionsform bei unregelmäßigen Wörtern ganz vom Lemma abweicht (vgl. ‘go’ und ‘went’). In den meisten sozialwissenschaftlichen Anwendungsszenarien ist es aber bereits ausreichend, durch die Verwendung von Platzhaltern (*) verschieden Wortvarianten zu identifizieren. Hier bringt Quanteda eine Reihe nützlicher Eigenschaften mit, die in der Dokumentation von kwic() genau beschrieben werden.

Als nächstes berechnen wir die Häufigkeit und Dispersion von Tokens pro Erzählung, welche die Begriffe ‘dark’ und ‘light’ enthalten.

term1 <- kwic(korpus, "dark", valuetype = "regex", case_insensitive = FALSE) %>% 
  as.data.frame() %>% 
  count(docname, name = "Treffer") %>% 
  mutate(Prozentanteil = Treffer/(korpus.stats$Tokens/100), Suchterm = "dark") %>% 
  arrange(desc(Prozentanteil))
term2 <- kwic(korpus, "light", valuetype = "regex", case_insensitive = FALSE) %>% 
  as.data.frame() %>% 
  count(docname, name = "Treffer") %>% 
  mutate(Prozentanteil = Treffer/(korpus.stats$Tokens/100), Suchterm = "light") %>% 
  arrange(desc(Prozentanteil))
term1
term2

Wieder wenden wir zunächst die Funktion kwic() an, allerdings hier in Kombination mit mehreren Funktionen aus dem Paket dplyr (tidyverse). Diese Funktionen haben nichts mit Quanteda zu tun, sondern sind für die Umformung jeglicher Daten in R nützlich (wer mehr wissen möchte, sollte sich dieses Buch anschauen). Während zuvor einfach die resultierende Konkordanz ausgegeben wurde, wird das Ergebnis jetzt mit Hilfe der Funktionen group_by(), summarise(), mutate() und arrange() weiter verarbeitet. Dabei machen wir uns die Tatsache zunutze, dass in einem KWIC-Ergebnis bereits alle Informationen vorliegen, um die absolute und relative Frequenz eines Begriffs (hier ‘light’ und ‘dark’) in einer Reihe von Dokumenten zu berechnen. Den Prozentanteil haben wir dabei einfach mittels Dreisatz abgeleitet (mit Treffer/(korpus.stats$Tokens/100)).

Wortfrequenzen lassen sich allerdings wesentlich einfacher durch die Quanteda-eigenen Funktion textstat_frequency umsetzen, die wir folgend auch konsequent nutzen werden – auch dazu gleich noch etwas mehr.

Zunächst plotten wie die absolute und relativen Häufigkeit der beiden Begriffe.

terme.kombiniert <- bind_rows(term1, term2) %>% 
  mutate(docname = factor(docname, levels = levels(korpus.stats$Text)))
ggplot(terme.kombiniert, aes(docname, Treffer, group = Suchterm, col = Suchterm)) + 
  geom_line(size = 1) + 
  scale_colour_brewer(palette = "Set1") + 
  theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1)) + 
  ggtitle("Häufigkeit der Suchbegriffe \"dark\" und \"light\" pro Roman (absolut)") + 
  xlab("Roman") + ylab("Wörter (gesamt)")