1. Einleitung

Im letzten Tutorial haben wir das Einlesen von Textdokumenten, Dokumentenvariablen und das Erstellen eines Textkorpus besprochen. In diesem Tuorial besprechen wir zwei zentrale Aspekte der quantitativen Textanalyse: Tokens und Document-Feature-Matricen.

Damit wir dort beginnen wo das letzte Tutorium aufgehört hat, geht der folgende Code alle Schritte von letzter Woche im Schnelldurchlauf durch:

# Die notwendigen Pakete laden
library(tidyverse) 
library(quanteda)
library(quanteda.textplots)
library(quanteda.textstats)
library(readtext)
library(ggplot2)

# Texte einlesen
daten_bverfg <- readtext("/Users/PhMeyer/Seafile/Seafile/Meine Bibliothek/Lehre/Seminare Uni Hannover/12 SoSe 2021/Quantitative Textanalyse/data/bverfg_15-19", 
                         docvarsfrom = "filenames", docvarnames = c("date","docket_nr"))

# Meta-Daten erstellen und in der richtigen Form speichern
daten_bverfg$year <-  substr(daten_bverfg$date, 1,4) 
daten_bverfg$year <-  as.numeric(daten_bverfg$year) 

daten_bverfg$month <-  substr(daten_bverfg$date, 5,6) 
daten_bverfg$month <-  as.numeric(daten_bverfg$month) 

daten_bverfg$senat <- substr(daten_bverfg$docket_nr, 1,1) 
daten_bverfg$senat  <-  as.numeric(daten_bverfg$senat)

daten_bverfg$proceeding <- substr(daten_bverfg$docket_nr, 2,4) 

# Korpus erstellen
gerichts_korpus <- corpus(daten_bverfg,docid_field = "doc_id")

# Korpusdaten identifizieren
korpus_stats <- summary(gerichts_korpus, n = 2000)

# Korpusdaten zu unserem Entscheidungsdatensatz hinzufügen
daten_bverfg$types <- korpus_stats$Types
daten_bverfg$tokens <- korpus_stats$Tokens
daten_bverfg$sentences <- korpus_stats$Sentences

# Unnötige Elemente aus dem Environment löschen
rm(korpus_stats)

Die Funktion rm() haben wir bisher noch nicht besprochen. Ihre einzige Funktion ist das Entfernen von Werten, Funktionen oder Datensätzen aus dem Environment (bei RStudio das Fenster oben rechts). Wie immer: falls ihr mehr erfahren wollt, dann nutzt ?rm oder googelt die Funktion.

2. Tokens und Tokenisierung

Bei einem Satz, Absatz oder einem ganzen Textdokument besteht die Aufgabe der Tokenisierung darin, die Textsequenzen zu zerlegen und dabei Aspekte wie z. B. Satzzeichen oder Füllwörter zu entfernen. Wir können diese Sequenzen entweder in einzelne Wörter, in Wortpaare, in dreier Gruppen (n-grams) oder auch in ganze Sätze zerlegen.

Mit der Tokenisierung wird der Prozess beschrieben, bei dem wir Texte in von uns definierte Sequenzen von Wörtern aufspalten. Sequenzen mit mehr als einem Wort werden in der Textanalyse N-Gram genannt (N ist hier ganz klassisch der Platzhalter für eine Zahl). In quanteda können wir mit der tokens-Funktion einen Korpus tokenisieren. Die Funktion beinhaltet weitere Argumente um bestimmte nicht brauchbare Textaspekte (wie Interpunktion, Leerzeichen (whitespace) oder Füllwörter) zu entfernen.

Wenden wir die tokens-Funktion auf unseren Gerichtskorpus an und schauen uns danach die Tokens einer speziellen Entscheidung an:

entscheidungs_tokens <- tokens(gerichts_korpus)

head(entscheidungs_tokens[["20150108_2bvr241913.txt"]])
## [1] "BUNDESVERFASSUNGSGERICHT" "-"                       
## [3] "2"                        "BvR"                     
## [5] "2419"                     "/"

Das ist alles noch wenig aussagekräftig sind. Das können wir natürlich ändern... aber dazu später mehr.

Per default splittet die tokens-Funktion die Texte in einzelne Wörter auf. In den meisten Fällen brauchen wir jedoch mehr als ein Wort um eine aussagekräftige Analyse zu realisieren. Über die Funktion tokens_ngrams lassen sich Texte in N-Grams aufspalten. In den folgenden zwei Beispiele werden wir 1) Bigramme produzieren (zwei Wörter) und 2) alle Sequenzen von einem, zwei oder drei Begriffen extrahieren.

entscheidungs_tokens_ngrams <- tokens_ngrams(entscheidungs_tokens, n = 2)
head(entscheidungs_tokens_ngrams[["20150108_2bvr241913.txt"]])
## [1] "BUNDESVERFASSUNGSGERICHT_-" "-_2"                       
## [3] "2_BvR"                      "BvR_2419"                  
## [5] "2419_/"                     "/_13"
entscheidungs_tokens_ngrams <- tokens_ngrams(entscheidungs_tokens, n = 1:3)
head(entscheidungs_tokens[["20150108_2bvr241913.txt"]])
## [1] "BUNDESVERFASSUNGSGERICHT" "-"                       
## [3] "2"                        "BvR"                     
## [5] "2419"                     "/"

Bei der Tokenisierung können wir aber auch bestimmte Begriffe entfernen:

entscheidungs_tokens <- tokens_remove(entscheidungs_tokens, c("BUNDESVERFASSUNGSGERICHT", "BvR", "BvF", "Karlsruhe", "Richter"))
head(entscheidungs_tokens[["20150108_2bvr241913.txt"]])
## [1] "-"    "2"    "2419" "/"    "13"   "-"

Wir haben jetzt einzelne Wörter nach der Tokenisierung entfernt. Deutlich einfacher und auch üblicher ist es aber, bestimmte Wörter, Satzzeichen, Zahlen und Sonderzeichen während der Tokinisierung zu entfernen. Das Entfernen dieser Elemente ist ein zentraler Bestandteil einer jeden quantitativen Textanalyse. Durch dieses sogenannte preprocessing entfernen wir unnötige oder sinnlose Textelemente, ermitteln die Worthäufigkeit und brechen so die Syntax auf. Dadurch erstellen wir einen sogenannten "Bag of Words".

Im folgenden Code entfernen wir alle Zahlen (remove_numbers = TRUE), Sonderzeichen (remove_symbols = TRUE), Leerzeichen (removeSeparators = TRUE) und die Interpunktion (remove_punct = TRUE). Danach transformieren wir mittels tokens_tolower alle Großbuchstaben in Kleinbuchstaben. In einem letzten Schritt nutzen wir tokens_remove und entfernen die Wörter "bundesverfassungsgericht", "richter", "bvr","herrn","Entscheidung","art" (Art für Gesetzesartikel),"gg" (Grundgesetz), "karlsruhe" sowie alle weiteren gängigen deutschen Stopp-/Füllwörter (der, die, das, wer, wie, was...).

entscheidungs_tokens <- tokens(gerichts_korpus, remove_numbers = TRUE, remove_punct = TRUE, remove_symbols = TRUE, removeSeparators = TRUE)
entscheidungs_tokens <- tokens_tolower(entscheidungs_tokens)
entscheidungs_tokens <- tokens_remove(entscheidungs_tokens, stopwords("german"))
entscheidungs_tokens <- tokens_remove(entscheidungs_tokens, c("bundesverfassungsgericht", "richter", "bvr","herrn","Entscheidung","art","gg", "karlsruhe", "dass", "beschluss", "rn","satz","sei"))

head(entscheidungs_tokens[["20150108_2bvr241913.txt"]])
## [1] "verfahren"             "verfassungsbeschwerde" "s"                    
## [4] "bevollmächtigter"      "rechtsanwalt"          "gerald"

Obwohl Tokens für einige Methoden wichtig sind, werden wir in den meisten Fällen mit Dokument-Feature-Matrizen arbeiten. Die Tokenisierung wird implizit angewandt, sobald wir eine Dokument-Feature-Matrize (DFM, s.u.) erstellen.

3. Dokument-Feature-Matrizen

Das Standardformat für die Darstellung eines Bag-of-Words ist eine Dokument-Feature-Matrix (DFM). DFMs werden praktisch in jedem Textanalyseprojekt verwendet. Meist ist das Erstellen einer DFM der zweite Schritt, gleich nach dem Anlegen eines Korpus. DFMs sind Matrizen, deren Zeilen die Texte und deren Spalten die Worthäufigkeiten enhalten. Wir verwenden die dfm-Funktion von quanteda um eine DFM von unserem Gerichtskorpus zu erstellen. Dabei verwenden wir die selben Argumente, welche wir bereits bei der tokens-Funktion genutzt haben:

court_stopswords <- c("bundesverfassungsgericht", "richter", "bvr","herrn","Entscheidung"
                      ,"art","gg", "karlsruhe", "dass", "beschluss", "rn","satz","sei"
                      , "bverfge","verfassungsbeschwerde", "beschwerdeführer","beschwerdeführerin") # hier legen wir eine list von wörter an, welche wir von vornherein entfernt haben wollen

entscheidungs_tokens <- tokens(gerichts_korpus, remove_punct=T
                               , remove_symbols = TRUE, removeSeparators = TRUE) %>%
  tokens_remove(pattern = c(court_stopswords,stopwords("german"))) %>%
  tokens_tolower()


entscheidungs_dfm <- dfm(entscheidungs_tokens)
entscheidungs_dfm
## Document-feature matrix of: 1,616 documents, 99,104 features (99.37% sparse) and 6 docvars.
##                          features
## docs                       2 2419 13 verfahren s bevollmächtigter rechtsanwalt
##   20150108_2bvr241913.txt 11    1  8         1 1                1            1
##   20150112_2bvq005314.txt  7    0  0         1 1                0            0
##   20150113_1bvr047214.txt  1    0  3         1 1                0            0
##   20150113_1bvr332314.txt  5    0  1         2 2                0            0
##   20150113_2bve000113.txt 12    0  5         3 0                1            0
##   20150113_2bvr239514.txt 19    0  2         4 1                0            0
##                          features
## docs                      gerald goecke hamburger
##   20150108_2bvr241913.txt      1      1         1
##   20150112_2bvq005314.txt      0      0         0
##   20150113_1bvr047214.txt      0      0         0
##   20150113_1bvr332314.txt      0      0         0
##   20150113_2bve000113.txt      0      0         0
##   20150113_2bvr239514.txt      0      0         0
## [ reached max_ndoc ... 1,610 more documents, reached max_nfeat ... 99,094 more features ]

Bei DFMs funktioniert einiges analog zu einem Textkorpus. Wir können die Funktionen ndoc oder nfeat anwenden:

ndoc(entscheidungs_dfm)
## [1] 1616
nfeat(entscheidungs_dfm)
## [1] 99104

Wir können die Namen der Dokumente und Features auslesen (hier nur die ersten (head) bzw. die letzten (tail) zehn Dokumente):

head(docnames(entscheidungs_dfm)) # Dokumentennamen 
## [1] "20150108_2bvr241913.txt" "20150112_2bvq005314.txt"
## [3] "20150113_1bvr047214.txt" "20150113_1bvr332314.txt"
## [5] "20150113_2bve000113.txt" "20150113_2bvr239514.txt"
tail(featnames(entscheidungs_dfm)) # Features 
## [1] "argentiniens" "comercial"    "nación"       "ley"          "26.994"      
## [6] "übergriffs"

Wollen wir einen Überblick über unsere DFM haben, dann können wir eine Tabelle erstellen. Hierbei wird uns auch direkt die sparsity unserer DFM angezeigt. Die sparsity beschreibt den Anteil der Nullen in einer DFM (Eine DFM misst die Haufigkeit eines Worts in den Korpusdokumenten). Anders gesagt, eine hohe sparsity bedeutet, dass die Texte viele genuine Wörter benützen, sodass dass viele der in den Texten vorkommenden Wörter nur in einigen wenigen Texten gleichzeitig vorkommen. Einfach ausgedrück: Bei einem Korpus von drei Texten kommt das Wort "Ball"" kommt nur in Text 1 vor, aber nicht in Text 2 und Text 3. In der DFM würden so für das Wort "Ball" als eine 1 (das Vorkommen in Text 1) und zwei Mal die 0 (aufgrund der Nichtexistenz des Wortes in den Texten 2 & 3) angezeigt.

entscheidungs_dfm # hier sehen wir, dass unsere DFM 1,616 Dokumente und 92,572 Features (i.d.R. Wörter, aber meist auch Sonderzeichen die quanteda nicht erkannt hat) hat und 99.4% sparse ist
## Document-feature matrix of: 1,616 documents, 99,104 features (99.37% sparse) and 6 docvars.
##                          features
## docs                       2 2419 13 verfahren s bevollmächtigter rechtsanwalt
##   20150108_2bvr241913.txt 11    1  8         1 1                1            1
##   20150112_2bvq005314.txt  7    0  0         1 1                0            0
##   20150113_1bvr047214.txt  1    0  3         1 1                0            0
##   20150113_1bvr332314.txt  5    0  1         2 2                0            0
##   20150113_2bve000113.txt 12    0  5         3 0                1            0
##   20150113_2bvr239514.txt 19    0  2         4 1                0            0
##                          features
## docs                      gerald goecke hamburger
##   20150108_2bvr241913.txt      1      1         1
##   20150112_2bvq005314.txt      0      0         0
##   20150113_1bvr047214.txt      0      0         0
##   20150113_1bvr332314.txt      0      0         0
##   20150113_2bve000113.txt      0      0         0
##   20150113_2bvr239514.txt      0      0         0
## [ reached max_ndoc ... 1,610 more documents, reached max_nfeat ... 99,094 more features ]
# Für unsere Tabelle können wir z.B. nur 8 Dokumente und 20 Features auswählen und anzeigen lassen: 

head(entscheidungs_dfm, n = 8, nf = 20) 
## Document-feature matrix of: 8 documents, 99,104 features (99.45% sparse) and 6 docvars.
##                          features
## docs                       2 2419 13 verfahren s bevollmächtigter rechtsanwalt
##   20150108_2bvr241913.txt 11    1  8         1 1                1            1
##   20150112_2bvq005314.txt  7    0  0         1 1                0            0
##   20150113_1bvr047214.txt  1    0  3         1 1                0            0
##   20150113_1bvr332314.txt  5    0  1         2 2                0            0
##   20150113_2bve000113.txt 12    0  5         3 0                1            0
##   20150113_2bvr239514.txt 19    0  2         4 1                0            0
##                          features
## docs                      gerald goecke hamburger
##   20150108_2bvr241913.txt      1      1         1
##   20150112_2bvq005314.txt      0      0         0
##   20150113_1bvr047214.txt      0      0         0
##   20150113_1bvr332314.txt      0      0         0
##   20150113_2bve000113.txt      0      0         0
##   20150113_2bvr239514.txt      0      0         0
## [ reached max_ndoc ... 2 more documents, reached max_nfeat ... 99,094 more features ]

Viele der 92,572 Features in der DFM sind nicht sehr informativ. Für Bag-of-Words-Analysen ist es vorteilhaft, diese Wörter zu entfernen. Das wird in den meisten Fällen die die Ergebnisse verbessern.

Wir können die Funktion dfm_trim verwenden um viele der uninformativen Features zu entfernen. Im Beispiel unten entfernen wir alle Terme die eine Häufigkeit (d. h. der Summenwert der Spalte in der DFM) von unter 30% haben. Wir entfernen also alle Wörter die in weniger als 30% aller Texte auftauchen.

entscheidungs_dfm  <- dfm_trim(entscheidungs_dfm, min_termfreq = 30) # mit "max_termfreq" könnten wir auch eine Obergrenze festlegen, aber das findet ihr am besten mit ?dfm_trim selber heraus
entscheidungs_dfm
## Document-feature matrix of: 1,616 documents, 8,318 features (94.24% sparse) and 6 docvars.
##                          features
## docs                       2 13 verfahren s bevollmächtigter rechtsanwalt 75
##   20150108_2bvr241913.txt 11  8         1 1                1            1  1
##   20150112_2bvq005314.txt  7  0         1 1                0            0  0
##   20150113_1bvr047214.txt  1  3         1 1                0            0  0
##   20150113_1bvr332314.txt  5  1         2 2                0            0  0
##   20150113_2bve000113.txt 12  5         3 0                1            0  0
##   20150113_2bvr239514.txt 19  2         4 1                0            0  0
##                          features
## docs                      kiel a landgerichts
##   20150108_2bvr241913.txt    8 2            2
##   20150112_2bvq005314.txt    0 0            0
##   20150113_1bvr047214.txt    0 1            0
##   20150113_1bvr332314.txt    0 0            0
##   20150113_2bve000113.txt    0 0            0
##   20150113_2bvr239514.txt    0 0            1
## [ reached max_ndoc ... 1,610 more documents, reached max_nfeat ... 8,308 more features ]

quanteda beinhaltet noch einige weitere Funktionen: topfeatures zählt Features in der gesamten DFM und gibt uns die Top-10 Features. textstat_frequency gibt uns die Worthäufigkeiten und ordnet die Features danach wie oft sie vorkommen (grundsätzlich ist textstat_frequency zu bevorzugen).

topfeatures(entscheidungs_dfm)
##       1       2     abs     vgl       3       4       s       f       5 bverfgg 
##   50731   38838   38071   20429   20428   10313   10001    9807    7701    6873
frequency <- textstat_frequency(entscheidungs_dfm)
head(frequency)
##   feature frequency rank docfreq group
## 1       1     50731    1    1610   all
## 2       2     38838    2    1615   all
## 3     abs     38071    3    1520   all
## 4     vgl     20429    4    1436   all
## 5       3     20428    5    1553   all
## 6       4     10313    6    1441   all

Wie wir sehen, sind Texte von Verfassungsgerichten vielleicht nicht das beste Anschauungsmaterial ;) (sie benötigen noch viel mehr Aufarbeitung und vor allem viel mehr Stoppwort-Entferung (z.b. die juristischen Abkürzungen)).

3.1 Weitere Anwendungen mit DFMs

Mit dfm_sort können wir DFMs nach Dokument- und Feature-Frequenzen sortieren:

head(dfm_sort(entscheidungs_dfm, decreasing = TRUE, margin = "both"), n = 12, nf = 10) 
## Document-feature matrix of: 12 documents, 8,318 features (64.78% sparse) and 6 docvars.
##                          features
## docs                        1   2 abs vgl   3   4   s   f   5 bverfgg
##   20170117_2bvb000113.txt 515 488 363 321 198 117 273  87 102      29
##   20190730_2bvr168514.txt 730 445 826 288 286 201 240 162 141      15
##   20180919_2bvf000115.txt 645 531 502 345 309 122 336 169 103       4
##   20160420_1bvr096609.txt 652 406 561 237 188 135  29 131 117       6
##   20161206_1bvr282111.txt 420 167 216 136 189  53  65 113  21       2
##   20171107_2bve000211.txt 255 154 107 164 103  73  45  86  55      12
## [ reached max_ndoc ... 6 more documents, reached max_nfeat ... 8,308 more features ]

Mit dfm_select lassen sich Wörter gezielt auswählen:

dfm_select(entscheidungs_dfm, pattern = "euro*") # * gibt an, dass wir alle Wörter mit euro als Anfangssequenz suchen
## Document-feature matrix of: 1,616 documents, 10 features (94.04% sparse) and 6 docvars.
##                          features
## docs                      europa euro europäischen europäische
##   20150108_2bvr241913.txt      1    0            0           0
##   20150112_2bvq005314.txt      0    0            0           0
##   20150113_1bvr047214.txt      0    0            0           0
##   20150113_1bvr332314.txt      0    1            0           0
##   20150113_2bve000113.txt      2    0            3           0
##   20150113_2bvr239514.txt      0    0            0           0
##                          features
## docs                      europarechtlichen europäisches europäischer european
##   20150108_2bvr241913.txt                 0            0            0        0
##   20150112_2bvq005314.txt                 0            0            0        0
##   20150113_1bvr047214.txt                 0            0            0        0
##   20150113_1bvr332314.txt                 0            0            0        0
##   20150113_2bve000113.txt                 0            0            0        0
##   20150113_2bvr239514.txt                 0            0            0        0
##                          features
## docs                      eurosystem eurosystems
##   20150108_2bvr241913.txt          0           0
##   20150112_2bvq005314.txt          0           0
##   20150113_1bvr047214.txt          0           0
##   20150113_1bvr332314.txt          0           0
##   20150113_2bve000113.txt          0           0
##   20150113_2bvr239514.txt          0           0
## [ reached max_ndoc ... 1,610 more documents ]
dfm_select(entscheidungs_dfm, pattern = "bund*") 
## Document-feature matrix of: 1,616 documents, 59 features (95.37% sparse) and 6 docvars.
##                          features
## docs                      bundesverfassungsgerichts bundesgerichtshof
##   20150108_2bvr241913.txt                         2                 1
##   20150112_2bvq005314.txt                         1                 0
##   20150113_1bvr047214.txt                         1                 0
##   20150113_1bvr332314.txt                         1                 0
##   20150113_2bve000113.txt                         3                 0
##   20150113_2bvr239514.txt                         2                 0
##                          features
## docs                      bundestages bund bundes bundestag bundesvorsitzenden
##   20150108_2bvr241913.txt           0    0      0         0                  0
##   20150112_2bvq005314.txt           0    0      0         0                  0
##   20150113_1bvr047214.txt           0    0      0         0                  0
##   20150113_1bvr332314.txt           0    0      0         0                  0
##   20150113_2bve000113.txt           2    1      1         3                  5
##   20150113_2bvr239514.txt           0    0      0         0                  0
##                          features
## docs                      bundesrat bundesregierung bundeskanzlerin
##   20150108_2bvr241913.txt         0               0               0
##   20150112_2bvq005314.txt         0               0               0
##   20150113_1bvr047214.txt         0               0               0
##   20150113_1bvr332314.txt         0               0               0
##   20150113_2bve000113.txt         1               1               1
##   20150113_2bvr239514.txt         0               0               0
## [ reached max_ndoc ... 1,610 more documents, reached max_nfeat ... 49 more features ]

Die Funktion dfm_wordstem reduziert alle Wörter auf ihre Wortstämme:

dfm_wordstem(entscheidungs_dfm, language = "german")
## Document-feature matrix of: 1,616 documents, 5,644 features (92.59% sparse) and 6 docvars.
##                          features
## docs                       2 13 verfahr s bevollmachtigt rechtsanwalt 75 kiel a
##   20150108_2bvr241913.txt 11  8       1 1              1            1  1    8 2
##   20150112_2bvq005314.txt  7  0       1 1              0            0  0    0 0
##   20150113_1bvr047214.txt  1  3       1 1              1            0  0    0 1
##   20150113_1bvr332314.txt  5  1       2 2              0            2  0    0 0
##   20150113_2bve000113.txt 12  5       3 0              1            0  0    0 0
##   20150113_2bvr239514.txt 19  2       4 1              0            0  0    0 0
##                          features
## docs                      landgericht
##   20150108_2bvr241913.txt           3
##   20150112_2bvq005314.txt           0
##   20150113_1bvr047214.txt           0
##   20150113_1bvr332314.txt           0
##   20150113_2bve000113.txt           0
##   20150113_2bvr239514.txt           3
## [ reached max_ndoc ... 1,610 more documents, reached max_nfeat ... 5,634 more features ]

Das Stemming ist im Allgemeinen eine tolle Möglichkeit zur weiteren Informationsreduktion. Für die deutsche Sprache ist es jedoch weniger wirkungsvoll, hier bieten sich andere Verfahren wie zum Beispiel lemmatization an.

Wir können DFMs auch nach relativen Worthäufigkeiten gewichten. Die TF-IDF (term frequency - inverse document frequency) zum Beispiel ist ein statistisches Maß, das bewertet, wie relevant ein Wort für ein Dokument in einer Sammlung von Dokumenten ist. Das geschieht durch die Multiplikation zweier Metriken: 1) wie oft ein Wort in einem Dokument vorkommt und 2) die inverse Dokumenthäufigkeit des Wortes über alle Dokumente hinweg.

entscheidungs_dfm_weighted <- dfm_tfidf(entscheidungs_dfm)
topfeatures(entscheidungs_dfm_weighted)
##   antragsgegnerin      europäischen                nr       gesetzgeber 
##          2932.732          2203.311          2192.305          2072.679 
##               sgb            urteil beschwerdeführers             seien 
##          1994.748          1643.206          1607.167          1591.095 
##              2011              2017 
##          1539.390          1505.244

Wie ihr seht, erzeugt die Gewichtung aussagekräftigere Resultate

3.2. Visualisierungen

Natürlich lassen sich DFMs auch visualisieren. Am wohl bekanntesten sind word clouds, die ihr ja bereits kennengelernt habt:

textplot_wordcloud(entscheidungs_dfm, max_words = 100, scale = c(5,1))

Natürlich ist auch hier ein Vergleich von Dokumenten interessanter. Im folgenden Beispiel nehmen wir die ersten vier Entscheidungstexte. Die Wortgröße zeigt nicht die absolute Häufigkeit in den Dokumenten an, sondern den gewichteten TF-IDF-Wert.

textplot_wordcloud(entscheidungs_dfm[1:4,], color = brewer.pal(4, "Set1"), comparison = T)

Nachdem ihr jetzt die Grundlagen der QTA, also Corpus, Tokens und DFM kennengelernt habt, werden wir ab der nächsten Woche mit der eigentlichen Textanalyse.