Die Kunst des Zählens {.smaller}

Initialisierung {.smaller}

library(polmineR)
for (pkg in c("data.table", "xts", "lubridate"))
  if (!pkg %in% rownames(installed.packages())) install.packages(pkg)

library(data.table)
library(xts)

Grundlagen des Zählens: Die count()-Methode {.smaller}

count("GERMAPARL", query = "Fluchtursachen")
count("GERMAPARL", query = "Fluchtursachen")[["count"]] / size("GERMAPARL")
count("GERMAPARL", query = c("Fluchtursachen", "Herkunftsländer"))

Nutzung der Ergebnisse eines Zählvorgangs {.smaller}

queries <- c(
  "Asylanten", "Asylbewerber", "Asylsuchende", "Aslyberechtigte",
  "Flüchtlinge", "Geflüchtete", "Migranten", "Schutzsuchende"
  )
dt <- count("GERMAPARL", query = queries)
df <- as.data.frame(dt)
df <- df[order(df$count, decreasing = TRUE),] # Sortierung
par(mar = c(8,4,2,2)) # Vergrößerung Rand unten => genug Platz für Beschriftung
barplot(height = df$count, names.arg = df$query, las = 2)

Häufigkeit von Begriffen zu Asyl und Flucht {.flexbox .vcenter}

par(mar = c(8,3,2,2)) # Vergrößerung Rand unten => genug Platz für Beschriftung
barplot(height = df$count, names.arg = df$query, las = 2)

count()-Methode und partition-Objekte {.smaller}

bt2015 <- partition("GERMAPARL", year = 2015)
count(bt2015, query = "Flüchtlinge")
partition("GERMAPARL", year = 2015) %>%
  count(query = "Flüchtlinge")

Beispiel: Variation des Sprachgebrauchs {.smaller}

queries <- c("Flüchtlinge", "Asylbewerber", "Asylsuchende", "Geflüchtete", "Migranten")

par(
  mar = c(8,5,2,2), # Anpassung Ränder => Beschriftung vollständig sichtbar
  mfrow = c(2,2) # Ausgabe verschiedener Balkendiagramme in ein Feld
)

for (pg in c("CDU/CSU", "GRUENE", "SPD", "LINKE")){
  dt <- partition("GERMAPARL", parliamentary_group = pg, year = 2016) %>%
    count(query = queries)
  barplot(
    height = dt$freq * 100000, names.arg = dt$query, # Beschriftung mit Suchbegriffen
    las = 2, # Drehung Beschriftung um 90 Grad für Lesbarkeit
    main = pg,
    xlab = "Frequenz der Begriffe (pro 100.000 Token)",
    ylim = c(0, 50) # einheitliche Skalierung y-Achse für Vergleichbarkeit
    )
}

Sprachliche Variation zwischen Parteien {.flexbox .vcenter}

queries <- c("Flüchtlinge", "Asylbewerber", "Asylsuchende", "Geflüchtete", "Migranten")

par(
  mar = c(6,5,2,2),
  mfrow = c(2,2), 
  cex = 0.6
)

for (pg in c("CDU/CSU", "GRUENE", "SPD", "LINKE")){
  p <- partition(
    "GERMAPARL",
    parliamentary_group = pg, year = 2016, interjection = FALSE
  )
  dt <- count(p, query = queries)
  barplot(
    height = dt$freq * 100000, names.arg = dt$query, las = 2, main = pg,
    ylim = c(0, 50)
  )
}

Nutzung von regulären Ausdrücken und CQP {.smaller}

count("GERMAPARL", query = "'Flüchtling.*'", cqp = TRUE) # mit CQP-Syntax
dt <- count("GERMAPARL", query = "'Flüchtling.*'", cqp = TRUE, breakdown = TRUE)

Treffer für regulären Ausdruck {.smaller}

DT::datatable(dt)

Zählung über positionale Attribute {.smaller}

count("GERMAPARL", query = "Flüchtling", p_attribute = "lemma")

Oder doch reguläre Ausdrücke? {.smaller}

terms("GERMAPARL", p_attribute = "word") %>% grep("Geflüchtet", ., value = TRUE)
terms("GERMAPARL", p_attribute = "lemma") %>% grep("Geflüchtet", ., value = TRUE)
count("GERMAPARL", query = '"Geflüchtete(|r|n)"', cqp = TRUE)

Sprachliche Variation: Matching von Flektionen {.smaller}

queries <- c(
  Flüchtlinge = '"Flüchtling(|e|s|en)"',
  Asylbewerber = '"Asylbewerber(|s|n|in|innen)"',
  Asylsuchende = '"Asylsuchende(|n|r)"',
  Geflüchtete = '"^Geflüchtete(|r|n)$"',
  Migranten = '"^Migrant(|en)$"'
  )
par(mar = c(6,5,2,2), mfrow = c(2,2),  cex = 0.6)
for (pg in c("CDU/CSU", "GRUENE", "SPD", "LINKE")){
  partition("GERMAPARL", parliamentary_group = pg, year = 2015:2016, interjection = FALSE) %>%
    count(query = unname(queries), cqp = TRUE, p_attribute = "word") -> dt
  barplot(
    height = dt$freq * 100000,
    names.arg = names(queries),
    las = 2, main = pg,
    ylim = c(0, 50)
  )
}

Sprachliche Variation, Zweiter Anlauf {.flexbox .vcenter}

queries <- c(
  Flüchtlinge = '"[fF]lüchtling(|e|s|en)"',
  Asylbewerber = '"Asylbewerber(|s|n|in|innen)"',
  Asylsuchende = '"Asylsuchende(|n|r)"',
  Geflüchtete = '"^Geflüchtete(|r|n)$"',
  Migranten = '"^Migrant(|en)$"'
  )

par(mar = c(6,5,2,2), mfrow = c(2,2),  cex = 0.6)

for (pg in c("CDU/CSU", "GRUENE", "SPD", "LINKE")){
  partition("GERMAPARL", parliamentary_group = pg, year = 2015:2016, interjection = FALSE) %>%
    count(query = unname(queries), cqp = TRUE, p_attribute = "word") -> dt
  barplot(
    height = dt$freq * 100000,
    names.arg = names(queries),
    las = 2, main = pg,
    ylim = c(0, 50)
  )
}

Zwischenfazit und "Learnings" {.smaller}

Häufigkeitsverteilungen {.smaller}

dt <- dispersion("GERMAPARL", query = "Flüchtlinge", s_attribute = "year")
head(dt) # wir betrachten nur den Anfang der Tabelle

Einfache Visualisierung der Häufigkeiten {.smaller}

par(mfrow = c(1,1))
dt <- dispersion("GERMAPARL", query = "Flüchtlinge", s_attribute = "year", freq = TRUE)
barplot(
  height = dt[["freq"]] * 100000,
  names.arg = dt[["year"]],
  las = 2, ylab = "Treffer pro 100.000 Worte"
  )

Flucht und Asyl im Bundestag, nach Jahren {.flexbox .vcenter}

barplot(
  height = dt[["freq"]] * 100000,
  names.arg = dt[["year"]],
  las = 2, ylab = "Treffer pro 100.000 Worte"
  )

Häufigkeitsverteilung über zwei Dimensionen {.smaller}

dt <- dispersion("GERMAPARL", query = '"[fF]lüchtling(|e|s|en)"', cqp = TRUE, s_attribute = c("year", "party"))
ts <- xts(x = dt[,c("CDU", "CSU", "FDP", "GRUENE", "SPD")],
          order.by = as.Date(sprintf("%s-01-01", dt[["year"]]))
          )
head(ts)

Visualisierung mit xts {.columns-2}

plot.xts(
  ts,
  multi.panel = TRUE,
  col = c("black",
          "black",
          "blue",
          "green",
          "red"),
  lwd = 2,
  yaxs = "r"
  )

Eine datumsgenaue Zeitreihe {.smaller}

par(mar = c(4,2,2,2))
dt <- dispersion("GERMAPARL", query = '"[fF]lüchtling(|e|s|en)"', cqp = TRUE, s_attribute = "date")
dt <- dt[!is.na(as.Date(dt[["date"]]))]
ts <- xts(x = dt[["count"]], order.by = as.Date(dt[["date"]]))
plot(ts)

Aggregation nach Woche - Monat - Quartal - Jahr {.smaller}

ts_week <- aggregate(ts, {a <- lubridate::ymd(paste(lubridate::year(index(ts)), 1, 1, sep = "-")); lubridate::week(a) <- lubridate::week(index(ts)); a})
ts_month <- aggregate(ts, as.Date(as.yearmon(index(ts))))
ts_qtr <- aggregate(ts, as.Date(as.yearqtr(index(ts))))
ts_year <- aggregate(ts, as.Date(sprintf("%s-01-01", gsub("^(\\d{4})-.*?$", "\\1", index(ts)))))
par(mfrow = c(2,2), mar = c(2,2,3,1))
plot(as.xts(ts_week), main = "Aggregation: Woche")
plot(as.xts(ts_month), main = "Aggregation: Monat");
plot(as.xts(ts_qtr), main = "Aggregation: Quartal")
plot(as.xts(ts_year), main = "Aggregation: Jahr")

Aggregation nach Woche - Monat - Quartal - Jahr {.flexbox .vcenter}

par(mfrow = c(2,2), mar = c(2,2,3,1))
plot(as.xts(ts_week), main = "Aggregation: Woche")
plot(as.xts(ts_month), main = "Aggregation: Monat");
plot(as.xts(ts_qtr), main = "Aggregation: Quartal")
plot(as.xts(ts_year), main = "Aggregation: Jahr")

Arbeit mit Zeitreihen: "Learnings" {.smaller}

Diktionärsbasierte Klassifikation I | Für Fortgeschrittene {.smaller}

Zählungen können nicht nur über Korpora und partition-Objekte durchgeführt werden, sondern auch über partition_bundle-Objekte. Dafür gibt es verschiedene Einsatzszenarien. Hier folgt ein Basis-Rezept für eine diktionärsbasierte Klassifikation. Der erste Schritt ist, ein partition_bundle mit den nach Daten und Tagesordnungspunkten unterteilten Partitionen eines Korpus aufzubereiten (hier nur für 2016).

bt2016 <- partition("GERMAPARL", year = 2016)
pb <- partition_bundle(bt2016, s_attribute = "date")
nested <- lapply(
  pb@objects,
  function(x) partition_bundle(x, s_attribute = "agenda_item", verbose = F)
)
debates <- flatten(nested)
names(debates) <- paste(
  blapply(debates, function(x) s_attributes(x, "date")),
  blapply(debates, function(x) name(x)), 
  sep = "_"
)

Diktionärsbasierte Klassifikation II {.smaller}

dict <- c("Asyl", "Flucht", "Flüchtlinge", "Geflüchtete")
dt <- count(debates, query = dict) %>% setorderv(cols = "TOTAL", order = -1L)
debates_mig <- debates[[ subset(dt, TOTAL >= 25)[["partition"]] ]]
debates_mig[[1]] %>% read() %>% highlight(yellow = dict)

Zählen aller Worte in Korpus / Partition {.smaller}

p <- partition("GERMAPARL", year = 2008, interjection = FALSE)
cnt <- count(p, p_attribute = "word")
sum(cnt[["count"]]) == size(p)
bt2008 <- partition("GERMAPARL", year = 2008, interjection = FALSE)
dt <- count(bt2008, p_attribute = c("word", "pos")) %>% subset(pos %in% c("NN", "ADJA")) %>%
  as.data.table() %>% setorderv(cols = "count", order = -1L) %>% head()

Gekonnt Zählen (nicht nur) für Algorithmen {.smaller}

Anhang {.smaller}

word <- get_token_stream("GERMAPARL", p_attribute = "word")
Encoding(word) <- registry_get_encoding("GERMAPARL")
lemma <- get_token_stream("GERMAPARL", p_attribute = "lemma")
Encoding(lemma) <- registry_get_encoding("GERMAPARL")

dt <- data.table(word = word, lemma = lemma)

token <- "Flüchtling"
q <- iconv(token, from = "UTF-8", to = "latin1")
dt2 <- dt[lemma == q]
dt2[, .N, by = .(word)]

Literatur



PolMine/UCSSR documentation built on June 13, 2022, 10:23 p.m.