Nachspielung "Automatisierte Inhaltsanalyse mit R - Grundlagen" - in oxoproxolytotisch
Eine kleine Serie zwischendurch:
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.
# 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)
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!
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
Kommentar veröffentlichen