Die Landtagswahl in Baden-Württemberg ist vorbei und die ersten Sondierungsgespräche starten. Aber für was stehen die Parteien eigentlich? Jedem Wähler würde ich den Wahlomat empfehlen. Dennoch ist so eine Wahl natürlich auch geeignet für eine Textanalyse mit R! Im Folgenden eine schnelle, simple Analyse ausgewählter Parteien:
Der Blick auf die häufigsten Wörter bestätigt erste Vermutungen, zeigt aber auch interessantes - "Darüber hinaus" als Spitzenreiter im CDU Programm zum Beispiel.
Auch der Blick auf die Sentimentwerte ist interessant. Im Verhältnis benutzen alle Parteien mehr positiv-konnotierte Begriffe als negative:
Hingegen ist der durchschnittliche Sentimentwert der Begriffe unterschiedlich; speziell die AFD fällt mit dem negativen Durchschnitt auf. Man könnte fast sagen, dass die Regierungsparteien Grüne und CDU durchwegs mehr positive Wörter benutzen, welche auch stärker positiv konnotiert sind; wäre da nicht die SPD, welche die im Durchschnitt positivsten Wörter am häufigsten benutzt.
Und hier noch der Code:
library(pdftools)
library(SnowballC)
library(dplyr)
library(tidytext)
library(tm)
library(stopwords)
library(ggplot2)
library(readr)
library(tibble)
library(viridis)
library(tidyr)
# Plot 1: die häufigsten Bigramme - SPD
text_SPD <- pdf_text("~/Documents/Blog/27_BaWü Wahl/SPD Programm.pdf") %>%
read_lines() %>%
as.data.frame() %>%
rownames_to_column(., var="line") %>%
`colnames<-`(c("line", "text"))
custom_stop_words_SPD <- bind_rows(tibble(word = c("baden", "württemberg", "men"), lexicon = c("custom")),
tibble(word = stopwords("de"), lexicon = c("stopwords")))
bigrams_SPD <- text_SPD %>%
unnest_tokens(bigram, text, token = "ngrams", n = 2) %>%
separate(bigram, c("word1", "word2"), sep = " ") %>%
filter(!word1 %in% custom_stop_words_SPD$word,
!word2 %in% custom_stop_words_SPD$word) %>%
drop_na(word1) %>%
drop_na(word2) %>%
unite(bigram, word1, word2, sep = " ")
bigrams_SPD<-bigrams_SPD[-grep("\\b\\d+\\b", bigrams_SPD$bigram),] #remove numbers
bigrams_SPD %>%
count(bigram, sort = TRUE) %>%
slice(1:15) %>%
mutate(bigram = reorder(bigram, n)) %>%
ggplot(aes(x = bigram, y = n, fill = bigram)) +
geom_col(show.legend = FALSE) +
coord_flip() +
scale_fill_viridis(discrete = TRUE, option="cividis") +
theme_minimal() +
labs(
x = NULL, y = NULL,
title = paste("SPD Programm"),
subtitle = ("die häufigsten Bigramme"),
caption = "Plot 1")
...
# Sentimentwerte
sentiment1_SPD <- text_SPD %>%
mutate(text = as.character(text)) %>%
unnest_tokens(word, text) %>%
anti_join(custom_stop_words_SPD, by = "word") %>%
left_join(SentiWS_df, by="word") %>%
drop_na() %>%
count(Polarität) %>%
spread(Polarität, n, fill=0) %>%
mutate(score = positive - negative) %>%
mutate(relation = positive/negative)
sentiment2_SPD <- text_SPD %>%
mutate(text = as.character(text)) %>%
unnest_tokens(word, text) %>%
anti_join(custom_stop_words_SPD, by = "word") %>%
left_join(SentiWS_df, by="word") %>%
drop_na() %>%
summarise(sentiment = mean(sentiment))
...
rbind(sentiment1_SPD %>% mutate(source = "SPD"),
sentiment1_CDU %>% mutate(source = "CDU"),
sentiment1_Gruene %>% mutate(source = "Gruene"),
sentiment1_FDP %>% mutate(source = "FDP"),
sentiment1_Linke %>% mutate(source = "Linke"),
sentiment1_Klimaliste %>% mutate(source = "Klimaliste"),
sentiment1_AFD %>% mutate(source="AFD")) %>%
mutate(source = reorder(source, relation)) %>%
ggplot(aes(x = source, y = relation, fill = relation)) +
geom_col(show.legend = FALSE) +
coord_flip() +
scale_fill_viridis(discrete = FALSE, option="cividis") +
theme_minimal() +
labs(
x = NULL, y = NULL,
title = paste("Sentimentwert der Wahlprogramme"),
subtitle = ("Verhältnis positiver zu negativer Wörter"),
caption = "Plot 8")
rbind(sentiment2_SPD %>% mutate(source = "SPD"),
sentiment2_CDU %>% mutate(source = "CDU"),
sentiment2_Gruene %>% mutate(source = "Gruene"),
sentiment2_FDP %>% mutate(source = "FDP"),
sentiment2_Linke %>% mutate(source = "Linke"),
sentiment2_Klimaliste %>% mutate(source = "Klimaliste"),
sentiment2_AFD %>% mutate(source="AFD")) %>%
mutate(source = reorder(source, sentiment)) %>%
ggplot(aes(x = source, y = sentiment, fill = sentiment)) +
geom_col(show.legend = FALSE) +
coord_flip() +
scale_fill_viridis(discrete = FALSE, option="cividis") +
theme_minimal() +
labs(
x = NULL, y = NULL,
title = paste("Sentimentwert der Wahlprogramme"),
subtitle = ("Durchschnittswert der Begriffe"),
caption = "Plot 9")
Notiz: in wissenschaftlichen Artikeln soll das Lexikon wiefolgt zitiert werden:R. Remus, U. Quasthoff & G. Heyer: SentiWS - a Publicly Available German-language Resource for Sentiment Analysis.In: Proceedings of the 7th International Language Ressources and Evaluation (LREC'10), 2010