count-words01

textmining
tidymodels
count
germeval
string
Published

November 16, 2023

Aufgabe

Zählen sie die Wörter eines Textes. Verwenden Sie verschiedene Verfahren. Untersuchen Sie die Rechenzeit, die die jeweiligen Verfahren benötigen.

Nutzen Sie die GermEval-2018-Daten. Die Daten sind unter CC-BY-4.0 lizensiert. Author: Wiegand, Michael (Spoken Language Systems, Saarland University (2010-2018), Leibniz Institute for the German Language (since 2019)), Die Daten sind auch über das R-Paket PradaData zu beziehen.

library(tidyverse)
d_train <- read_csv("https://raw.githubusercontent.com/sebastiansauer/pradadata/master/data-raw/germeval_train.csv")
d_test <- read_csv("https://raw.githubusercontent.com/sebastiansauer/pradadata/master/data-raw/germeval_test.csv")

Hinweise:











Lösung

Setup

options(paged.print = FALSE,
        pillar.print_max = 15, 
        pillar.print_min = 10)
library(tidyverse)
library(tictoc)
#library(tokenizers)
#library(qdap)

Teststring:

test_text <-
  tibble(id = 1:4,
         text = c("Abbau ist jetzt", "Test heute", "Abbruch morgen", "Abmachung lore ipsum"),
         valence = c(-1, 0, -1, +1))

test_text
id text valence
1 Abbau ist jetzt -1
2 Test heute 0
3 Abbruch morgen -1
4 Abmachung lore ipsum 1

Daten importieren:

data(germeval_train, package = "pradadata")

Wörter zählen im Test-Datensatz

stringr::str_count

test_text$text |> 
  map_int(str_count, "\\w+")
[1] 3 2 2 3

Oder so:

test_text$text |> 
  map_int(str_count, boundary("word"))
[1] 3 2 2 3

Die Funktion map ist nicht nötig:

str_count(test_text$text, boundary("word"))
[1] 3 2 2 3

Als neue Spalte in der Tabelle:

test_text |> 
  mutate(n_words = str_count(text, boundary("word")))
id text valence n_words
1 Abbau ist jetzt -1 3
2 Test heute 0 2
3 Abbruch morgen -1 2
4 Abmachung lore ipsum 1 3

tokenizers::count_words

tokenizers::count_words(test_text$text)
[1] 3 2 2 3
test_text |> 
  mutate(n_words = tokenizers::count_words(text))
id text valence n_words
1 Abbau ist jetzt -1 3
2 Test heute 0 2
3 Abbruch morgen -1 2
4 Abmachung lore ipsum 1 3

qdap:wc

qdap::wc(test_text$text)
[1] 3 2 2 3

Germeval-Datensatz

stringr::str_count

tic()
method1 <- germeval_train$text |> 
  map_int(str_count, "\\w+")
toc()
0.206 sec elapsed
method1 |> str()
 int [1:5009] 15 19 11 21 15 44 34 8 13 14 ...
print(method1, max = 20)
 [1] 15 19 11 21 15 44 34  8 13 14 14 28 39 22 43 28 19 23 25 13
 [ reached getOption("max.print") -- omitted 4989 entries ]

Oder so:

tic()
method2 <- germeval_train$text |> 
  map_int(str_count, boundary("word"))
toc()
0.163 sec elapsed
head(method2)
[1] 15 19 10 21 15 44

Die Funktion map ist nicht nötig:

tic()
method3 <- str_count(germeval_train$text, boundary("word"))
toc()
0.021 sec elapsed
method3 |> head()
[1] 15 19 10 21 15 44

Dann geht es auch viel schneller.

Als neue Spalte in der Tabelle:

tic()
method4 <- 
germeval_train |> 
  mutate(n_words = str_count(text, boundary("word")))
toc()
0.027 sec elapsed
str(method4)
'data.frame':   5009 obs. of  5 variables:
 $ id     : int  1 2 3 4 5 6 7 8 9 10 ...
 $ text   : chr  "@corinnamilborn Liebe Corinna, wir würden dich gerne als Moderatorin für uns gewinnen! Wärst du begeisterbar?" "@Martin28a Sie haben ja auch Recht. Unser Tweet war etwas missverständlich. Dass das BVerfG Sachleistungen nich"| __truncated__ "@ahrens_theo fröhlicher gruß aus der schönsten stadt der welt theo ⚓️" "@dushanwegner Amis hätten alles und jeden gewählt...nur Hillary wollten sie nicht und eine Fortsetzung von Obam"| __truncated__ ...
 $ c1     : chr  "OTHER" "OTHER" "OTHER" "OTHER" ...
 $ c2     : chr  "OTHER" "OTHER" "OTHER" "OTHER" ...
 $ n_words: int  15 19 10 21 15 44 34 8 13 14 ...
 - attr(*, ".internal.selfref")=<externalptr> 
method4 |> head()
id text c1 c2 n_words
1 (corinnamilborn?) Liebe Corinna, wir würden dich gerne als Moderatorin für uns gewinnen! Wärst du begeisterbar? OTHER OTHER 15
2 (Martin28a?) Sie haben ja auch Recht. Unser Tweet war etwas missverständlich. Dass das BVerfG Sachleistungen nicht ausschließt, kritisieren wir. OTHER OTHER 19
3 (ahrens_theo?) fröhlicher gruß aus der schönsten stadt der welt theo ⚓️ OTHER OTHER 10
4 (dushanwegner?) Amis hätten alles und jeden gewählt…nur Hillary wollten sie nicht und eine Fortsetzung von Obama-Politik erst recht nicht..! OTHER OTHER 21
5 (spdde?) kein verläßlicher Verhandlungspartner. Nachkarteln nach den Sondierzngsgesprächen - schickt diese Stümper #SPD in die Versenkung. OFFENSE INSULT 15
6 (Dirki_M?) Ja, aber wo widersprechen die Zahlen denn denen, die im von uns verlinkten Artikel stehen? In unserem Tweet geht es rein um subs. Geschützte. 2017 ist der gesamte Familiennachzug im Vergleich zu 2016 - die Zahlen, die Hr. Brandner bemüht - übrigens leicht rückläufig gewesen. OTHER OTHER 44

tokenizers::count_words

tic()
method5 <- tokenizers::count_words(germeval_train$text)
toc()
0.019 sec elapsed
head(method5)
[1] 15 19 10 21 15 44
tic()
method6 <-
germeval_train |> 
  mutate(n_words = tokenizers::count_words(text))
toc()
0.021 sec elapsed
method6 |> head()
id text c1 c2 n_words
1 (corinnamilborn?) Liebe Corinna, wir würden dich gerne als Moderatorin für uns gewinnen! Wärst du begeisterbar? OTHER OTHER 15
2 (Martin28a?) Sie haben ja auch Recht. Unser Tweet war etwas missverständlich. Dass das BVerfG Sachleistungen nicht ausschließt, kritisieren wir. OTHER OTHER 19
3 (ahrens_theo?) fröhlicher gruß aus der schönsten stadt der welt theo ⚓️ OTHER OTHER 10
4 (dushanwegner?) Amis hätten alles und jeden gewählt…nur Hillary wollten sie nicht und eine Fortsetzung von Obama-Politik erst recht nicht..! OTHER OTHER 21
5 (spdde?) kein verläßlicher Verhandlungspartner. Nachkarteln nach den Sondierzngsgesprächen - schickt diese Stümper #SPD in die Versenkung. OFFENSE INSULT 15
6 (Dirki_M?) Ja, aber wo widersprechen die Zahlen denn denen, die im von uns verlinkten Artikel stehen? In unserem Tweet geht es rein um subs. Geschützte. 2017 ist der gesamte Familiennachzug im Vergleich zu 2016 - die Zahlen, die Hr. Brandner bemüht - übrigens leicht rückläufig gewesen. OTHER OTHER 44

qdap::wc

tic()
method7 <- qdap::wc(germeval_train$text)
toc()
0.99 sec elapsed
method7 |> head()
[1] 15 20 10 19 15 42

Deutlich langsamer als mit tokenizers.


Categories:

  • textmining
  • tidymodels
  • count
  • germeval
  • string