Im Grunde kann eine Sentimentanalyse relativ simpel sein; im zu untersuchenden Text werden Signalwörter identifiziert, für welche in einer Bibliothek eine Klassifizierung in positiv oder negativ oder ein Score von z.B. -1 bis +1 hinterlegt. Die Summe der Wörter oder des Scores ergibt schließlich den Sentiment-Wert des Textes.
Nehmen wir die folgende beiden Sätze, abgespeichert in einem Dataframe:
> text <- c('Eine Tätigkeit wird dann als Hobby bezeichnet, wenn man für diese Tätigkeit eine besondere Präferenz hat und sie regelmäßig ausübt.',
'Traurigkeit kann etwa durch kaltes und regnerisches und Freude durch gutes Wetter hervorgerufen werden.')
> row <- c(1,2)
> Beispiel <- data.frame(row, text)
Wir sehen schon Wörter, welche für den Leser eher positiv bzw. negativ sind. Nun können wir ein eigenes Lexikon aufstellen, welches wir zur Klassifizierung benutzen:
> custom_dictionary <- bind_rows(tibble(word = c("hobby", "präferenz", "regelmäßig", "gutes", "freude"),
+ polarität = c("positiv"),
+ score = c(0.8,1,0.6,1,1)),
+ tibble(word = c("traurigkeit", "kaltes", "regnerisches"),
+ polarität = c("negativ"),
+ score = c(-1,-0.7,-0.7)))
> custom_dictionary
# A tibble: 8 x 3
word polarität score
<chr> <chr> <dbl>
1 hobby positiv 0.8
2 präferenz positiv 1
3 regelmäßig positiv 0.6
4 gutes positiv 1
5 freude positiv 1
6 traurigkeit negativ -1
7 kaltes negativ -0.7
8 regnerisches negativ -0.7
Eine Datenaufbereitung und der Abgleich mit der eigenen Bibliothek ergibt schließlich folgenden Dataframe:
> words <- Beispiel %>%
+ mutate(text = gsub("[0-9]", "", text, fixed = F)) %>% # ohne Nummern (denen hier keine Polarität zugesprochen wird)
+ mutate(text = gsub("[[:punct:]]", "", text, fixed = F)) %>% # ohne Satzzeichen
+ mutate(text = tolower(text)) %>% # Kleinschreibung
+ unnest_tokens(word, text) %>% # Zerlegung in die Einzelwörter
+ left_join(custom_dictionary, by="word") %>% # Abgleich mit den Wörtern der Bibliothek
+ na.omit() #%>% #ohne die neutralen Wörer, bei denen kein Wert hinterlegt ist
> words
row word polarität score
6 1 hobby positiv 0.8
15 1 präferenz positiv 1.0
19 1 regelmäßig positiv 0.6
21 2 traurigkeit negativ -1.0
25 2 kaltes negativ -0.7
27 2 regnerisches negativ -0.7
29 2 freude positiv 1.0
31 2 gutes positiv 1.0
Und schließlich können wir uns die Anzahl der positiven und negativen Begriffe als auch den jeweiligen Sentiment-Wert pro Zeile berechnen:
> words %>%
+ group_by(row) %>% # pro Zeile
+ count(polarität) %>%
+ spread(polarität, n, fill = 0)
# A tibble: 2 x 3
# Groups: row [2]
row negativ positiv
<dbl> <dbl> <dbl>
1 1 0 3
2 2 3 2
> words %>%
+ group_by(row) %>% # pro Zeile
+ summarise(sentiment = sum(score)) # wird die Summe der Scores ermittelt
# A tibble: 2 x 2
row sentiment
<dbl> <dbl>
1 1 2.4
2 2 -0.400
Natürlich kann das alles noch sehr viel komplexer werden. Zum Beispiel gibt es hier ein Wörterbuch und Hinweise zum Umgang mit Verneinungen von Dr. Christina Rau: Link
Photo by Andrea Piacquadio from Pexels