Nachspielung "Automatisierte Inhaltsanalyse mit R - Grundlagen" - in oxoproxolytotisch

Eine kleine Serie zwischendurch:

Automatisierte Inhaltsanalyse mit R

Diesmal:

Grundlagen



Erläuterungen und Erklärungen finden sich hier:

Automatisierte Inhaltsanalyse mit R

Nachgespielt habe ich es mit dem folgenden Skript. Nicht unwichtige Anmerkungen sind dem beigefügt.

Skript

# Installation und Laden benötigter Pakete
# Warnungen und Fehler beachten!
# Ggf. manuell installieren
# Auf Ubuntu 19.04 musste ich libcurl über apt installieren:
# https://stackoverflow.com/questions/42115972/configuration-failed-because-libcurl-was-not-found
# Und lxml2-dev:
# sudo apt install libxml2
# Und auf Verdacht: sudo apt-get install r-cran-rcppeigen
# https://github.com/quanteda/quanteda/issues/1241
# Bei der Installation von pdftools (für readtext) als Requirement angegeben:
# sudo add-apt-repository -y ppa:cran/poppler
# sudo apt-get update
# sudo sudo apt-get install -y libpoppler-cpp-dev

if(!require("quanteda")) {install.packages("quanteda"); library("quanteda")}
if(!require("readtext")) {install.packages("readtext"); library("readtext")}
if(!require("tidyverse")) {install.packages("tidyverse"); library("tidyverse")}
if(!require("RColorBrewer")) {install.packages("RColorBrewer"); library("RColorBrewer")}
theme_set(theme_bw())

# Einlesen der Daten und Anlegen eines Korpus

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

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

# Basisstatistiken zu einem Korpus berechnen

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")
ggplot(korpus.stats, aes(Text, Sentences, group = 1)) + geom_line() + geom_point() + theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1)) + ggtitle("Sätze pro Roman")
ggplot(korpus.stats, aes(Tokens, Types, group = 1, label = Textnummer)) + geom_smooth(method = "lm", se = FALSE) + geom_text(check_overlap = T) + ggtitle("Typ-Token-Relation pro Roman")

# Mit Korpora arbeiten

str_sub(korpus[1], start = 1, end = 1000) # Anfang des ersten Romans wiedergeben

korpus.saetze <- corpus_reshape(korpus, to = "sentences")
korpus.saetze[1]

zufallssatz <- corpus_sample(korpus.saetze, size = 1)
zufallssatz[1]

docvars(korpus.saetze, "Zeichenanzahl") <- ntoken(korpus.saetze)
docvars(korpus.saetze, "LangerSatz") <- ntoken(korpus.saetze)>=25
korpus.saetze_lang <- corpus_subset(korpus.saetze, LangerSatz == TRUE)
korpus.saetze_lang[1:3]

# Tokenisierung

meine.tokens <- tokens(korpus)
head(meine.tokens$`A Scandal in Bohemia`)

meine.tokens <- tokens(korpus, ngrams = 2)
head(meine.tokens$`A Scandal in Bohemia`)

meine.tokens <- tokens(korpus, ngrams = 1:3)
head(meine.tokens$`A Scandal in Bohemia`)

meine.tokens <- tokens(korpus)
begriffe.behalten <- tokens_select(meine.tokens, c("holmes", "watson")) # Platzhalter mit padding = TRUE
head(begriffe.behalten$`A Scandal in Bohemia`)

begriffe.entfernen <- tokens_remove(meine.tokens, c("Sherlock", "in", "is", "the"))
head(begriffe.entfernen$`A Scandal in Bohemia`)

meine.tokens <- tokens(korpus, remove_numbers = TRUE, remove_punct = TRUE, remove_symbols = TRUE)
meine.tokens <- tokens_tolower(meine.tokens)
meine.tokens <- tokens_remove(meine.tokens, c(stopwords("english"), "sherlock", "holmes"))
head(meine.tokens$`A Scandal in Bohemia`)

# Dokument-Feature-Matrizen (DFMs) erstellen

meine.dfm <- dfm(korpus, remove_numbers = TRUE, remove_punct = TRUE, remove_symbols = TRUE, remove = stopwords("english"))
meine.dfm

ndoc(meine.dfm)

nfeat(meine.dfm)

head(docnames(meine.dfm)) # In der DFM enthaltene Dokumente

head(featnames(meine.dfm), 50) # Features in chronologischer Reihenfolge

head(meine.dfm, n = 12, nf = 10) # Features/Texte als Matrix

topfeatures(meine.dfm) # Features nach Frequenz

worthaeufigkeiten <- textstat_frequency(meine.dfm) # Worthäufigkeiten
head(worthaeufigkeiten)

# Mit DFMs arbeiten

head(dfm_sort(meine.dfm, decreasing = TRUE, margin = "both"), n = 12, nf = 10)

dfm_select(meine.dfm, pattern = "lov*")

meine.dfm.stemmed <- dfm_wordstem(meine.dfm)
topfeatures(meine.dfm.stemmed)

meine.dfm.proportional <- dfm_weight(meine.dfm, scheme = "prop")
topfeatures(meine.dfm) # absolute Frequenzen für das gesamte Korpus

topfeatures(meine.dfm.proportional) # ...ergibt wenig Sinn

topfeatures(meine.dfm.proportional[1,]) # ...ergibt mehr Sinn

meine.dfm.propmax <- dfm_weight(meine.dfm, scheme = "propmax")
topfeatures(meine.dfm.propmax[1,])

meine.dfm.tfidf <- dfm_tfidf(meine.dfm)
topfeatures(meine.dfm.tfidf)

meine.dfm.trim <- dfm_trim(meine.dfm, min_docfreq = 11)
head(meine.dfm.trim, n = 12, nf = 10)

meine.dfm.trim <- dfm_trim(meine.dfm, min_termfreq = 0.95, termfreq_type = "quantile")
head(meine.dfm.trim, n = 12, nf = 10)

# DFMs visualisieren

textplot_wordcloud(meine.dfm, max_words = 100, scale = c(5,1))

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



Output







Schlussbemerkung


Das Skript mit den Codezeilen ist hempelpempelüberprüft, damit auch auf Oxo-omx-Moxo-Funzialistikkung getestet. Ergebnis: funzt.



Selbst & Selber habe ich den Begleittext bisher erst überflogen. Ich lege mich nun ins Bett - falls es interessiert - und werde morgen das Verständnis nachholen. Soweit, so gut, Aloohaa!












Kommentare

Beliebte Posts aus diesem Blog

·

Es brennt.

Bye, bye Nord Stream 2!