germeval-senti01

tidymodels
textmining
prediction
sentiment
germeval
string
Published

November 16, 2023

Aufgabe

Führen Sie eine Sentiment-Analyse als Teils eines Tidymodels-Rezept durch. Modellieren Sie dann mit einem einfachen linearen Modell die abhängige Variable.

Verwenden Sie diesen Datensatz:

# Analyse-Daten:
data("germeval_train", package = "pradadata")
data("germeval_test", package = "pradadata")
# Sentiment-Daten
data("sentiws", package = "pradadata")

Die AV ist c1.

Hinweise:











Lösung

Setup

library(tidyverse)
library(syuzhet)  # get_sentiment
library(tidymodels)
library(tictoc)

Daten

c2 brauchen wir hier nicht:

d_train <-
  germeval_train |> 
  select(-c2) |> 
  as_tibble()

Rezept

Rezept definieren:

rec <-
  recipe(c1 ~ ., data = d_train) |> 
  update_role(id, new_role = "id")  |> 
  #update_role(c2, new_role = "ignore") |> 
  update_role(text, new_role = "ignore") |> 
  step_mutate(n_emo = get_sentiment(text,  # aus `syuzhet`
                                    method = "custom",
                                    lexicon = sentiws))  |> 
  step_rm(text)  # Datensatz verschlanken

step_mutate ergänzt für die erzeugte (mutierte) Variable automatisch eine Rolle im Rezept, nimmt sie also als Prädiktor auf.

Mal schauen:

rec
tidy(rec)
# A tibble: 2 × 6
  number operation type   trained skip  id          
   <int> <chr>     <chr>  <lgl>   <lgl> <chr>       
1      1 step      mutate FALSE   FALSE mutate_XC8s1
2      2 step      rm     FALSE   FALSE rm_g6jF6    

Preppen und backen:

tic()
rec_prepped <- prep(rec)
toc()
12.92 sec elapsed
rec_prepped
rec_baked <- bake(rec_prepped, new_data = NULL)
head(rec_baked)
# A tibble: 6 × 3
     id c1       n_emo
  <int> <fct>    <dbl>
1     1 OTHER    0.004
2     2 OTHER   -0.347
3     3 OTHER    0    
4     4 OTHER    0    
5     5 OFFENSE  0    
6     6 OTHER   -0.346

Model

mod <-
  logistic_reg()

Workflow

wf <- workflow() |> 
  add_recipe(rec) |> 
  add_model(mod)

Fit

tic()
fit1 <-
  fit(wf,
      data = d_train)
toc()
12.64 sec elapsed
fit1
══ Workflow [trained] ══════════════════════════════════════════════════════════
Preprocessor: Recipe
Model: logistic_reg()

── Preprocessor ────────────────────────────────────────────────────────────────
2 Recipe Steps

• step_mutate()
• step_rm()

── Model ───────────────────────────────────────────────────────────────────────

Call:  stats::glm(formula = ..y ~ ., family = stats::binomial, data = data)

Coefficients:
(Intercept)        n_emo  
     0.6819       0.4802  

Degrees of Freedom: 5008 Total (i.e. Null);  5007 Residual
Null Deviance:      6402 
Residual Deviance: 6392     AIC: 6396

Test-Set-Güte

Vorhersagen im Test-Set:

tic()
preds <-
  predict(fit1, new_data = germeval_test)
toc()
7.397 sec elapsed

Und die Vorhersagen zum Test-Set hinzufügen, damit man TRUTH und ESTIMATE vergleichen kann:

d_test <-
  germeval_test |> 
  bind_cols(preds) |> 
  mutate(c1 = as.factor(c1))
metrics(d_test,
        truth = c1,
        estimate = .pred_class)
# A tibble: 2 × 3
  .metric  .estimator .estimate
  <chr>    <chr>          <dbl>
1 accuracy binary         0.660
2 kap      binary         0    

Baseline

Ein einfaches Referenzmodell ist, einfach die häufigste Kategorie vorherzusagen:

d_train |> 
  count(c1)
# A tibble: 2 × 2
  c1          n
  <chr>   <int>
1 OFFENSE  1688
2 OTHER    3321

Categories:

  • tidymodels
  • textmining
  • prediction
  • sentimentanalysis
  • germeval
  • string