6 Szótárak és érzelemelemzés

6.1 Fogalmi alapok

A szentiment- vagy vélemény-, illetve érzelemelemzés a számítógépes nyelvészet részterülete, melynek célja az egyes szövegek tartalmából kinyerni azokat az információkat, amelyek értékelést fejeznek ki.22 A véleményelemzés a szövegeket három szinten osztályozza. A legáltalánosabb a dokumentumszintű osztályozás, amikor egy hosszabb szövegegység egészét vizsgáljuk, míg a mondatszintű osztályozásnál a vizsgálat alapegysége a mondat. A legrészletesebb adatokat akkor nyerjük, amikor az elemzést target-szinten végezzük, azaz meghatározzuk azt is, hogy egy-egy érzelem a szövegen belül mire vonatkozik. Mindhárom szinten azonos a feladat: egyrészt meg kell állapítani, hogy az adott egységben van-e értékelés, vélemény vagy érzelem, és ha igen, akkor pedig meg kell határozni, hogy milyen azok érzelmi tartalma.

A pozitív-negatív-semleges skálán mozgó szentimentelemzés mellett az elmúlt két évtizedben jelentős lépések történtek a szövegek emóciótartalmának automatikus vizsgálatára is. A módszer hasonló a szentimentelemzéshez, tartalmilag azonban más skálán mozog. Az emócióelemzés esetén ugyanis nem csak azt kell meghatározni, hogy egy kifejezés pozitív vagy negatív töltettel rendelkezik, hanem azt is, hogy milyen érzelmet (öröm, bánat, undor stb.) hordoz. A szótár alapú szentiment- vagy emócióelemzés alapja az az egyszerű ötlet, hogy ha tudjuk, hogy egyes szavak milyen érzelmeket, érzéseket hordoznak, akkor ezeket a szavakat egy szövegben megszámolva képet kaphatunk az adott dokumentum érzelmi tartalmáról. Mivel a szótár alapú elemzés az adott kategórián belüli kulcsszavak gyakoriságán alapul, ezért van, aki nem tekinti statisztikai elemzésnek (lásd például Young and Soroka (2012)).

A tágabb kvantitatív szövegelemzési kontextusban az osztályozáson (classification) belül a felügyelt módszerekhez hasonlóan itt is ismert kategóriákkal dolgozunk, azaz előre meghatározzuk, hogy egy-egy adott szó pozitív vagy negatív tértékű, vagy továbbmenve, milyen érzelmet hordoz, csak egyszerűbb módszertannal (Grimmer and Stewart 2013). A kulcsszavakra építés miatt a módszer a kvalitatív és a kvantitatív kutatási vonalak találkozásának is tekinthető, hiszen egy-egy szónak az érzelmi töltete nem mindig ítélhető meg objektíven. Mint minden módszer esetében, itt is kiemelten fontos ellenőrni, hogy a használt szótár kategóriák és kulcsszavak fedik-e a valóságot. Más szavakkal: validálás, validálás, validálás.

A módszer előnyei:

  • Tökéletesen megbízható: a számításoknak nincs probabilisztikus (azaz valószínűségre épülő) eleme, mint például a Support Vector alapú osztályozásnak, illetve az emberi szövegkódolásnál előforduló problémákat is elkerüljük (például azt, hogy két kódoló, vagy ugyanazon kódoló két különböző időpontban nem azonosan értékeli ugyanazt a kifejezést).
  • Általa képesek vagyunk mérni a szöveg látens dimenzióit.
  • Széles körben alkalmazható, egyszerűen számolható. A politikatudományon és a számítógépes nyelvészeten belül nagyon sok kész szótár elérhető, amelyek különböző módszerekkel készültek és különböző területet fednek le (például populizmus, pártprogramok policy tartalma, érzelmek, gazdasági tartalom).
  • Relatíve könnyen adaptálható egyik nyelvi környezetből a másikba, bár szótárfordítások esetén külön hangsúlyt kell fektetni a validálásra.23

A módszer lehetséges hátrányai:

  • A szótár hatékonysága és validitása azon múlik, hogy mennyire egyezik a szótár és a vizsgálni kívánt dokumentum területe. Nem mindegy például, hogy a szótárunkkal tőzsdei jelentések alapján a gazdasági bizonytalanságot vagy nézők filmekre adott értékeléseit szeretnénk-e vizsgálni. Léteznek általános szentimentszótárak, ezek hatékonysága azonban általában alulmúlja a terület-specifikus szótárakét.
  • A terület-specifikus szótár építése kvalitatív folyamat, éppen ezért idő- és emberi erőforrás igényes.
  • A szózsák alapú elemzéseknél a kontextus elvész. Gondoljunk például a tagadásra: a „nem vagyok boldog” kifejezés esetén egy általános szentiment szótár a tagadás miatt félreosztályozná a mondat érzelmi töltését, hiszen a boldog szó önmagában a pozitív kategóriába tartozik. Természetesen az automatikus tagadás kezelésére is vannak lehetőségek, de a kérdés komplexitása miatt ezek bemutatásától most eltekintünk.

A legnagyobb méretű általános szentimentszótár az angol nyelvű SentiWordNet (SWN), ami kb. 150 000 szót tartalmaz, amelyek mindegyike a három szentimentérték – pozitív, negatív, semleges – közül kapott egyet.24(Baccianella, Esuli, and Sebastiani 2010)

Az R-ben végzett szentimentelemzés során az angol nyelvű szövegekhez több beépített általános szentimentszótár is a rendelkezésünkre áll.25 A teljesség igénye nélkül említhetjük az AFINN,26 a bing27 és az nrc28 szótárakat. Az elemzés sikere több faktortól is függ. Fontos, hogy a korpuszban lévő dokumentumokat körültekintően tisztítsuk meg az elemzés elején (lásd a Korpuszépítés és előkészítés fejezetet). A következő lépésben meg kell bizonyosodnunk arról, hogy a kiválasztott szentiment szótár alkalmazható a korpuszunkra. Amennyiben nem találunk alkalmas szótárt, akkor a saját szótár validálására kell figyelni. A negyedik fejezetben leírtak itt is érvényesek, a dokumentum-kifejezés mátrixot érdemes valamilyen módon súlyozni.

6.2 Szótárak az R-ben

A szótár alapú elemzéshez a quanteda csomagot fogjuk használni, illetve a 3. fejezetben már megismert readr, stringr, dplyr tidyverse csomagokat.29

library(stringr)
library(dplyr)
library(tidyr)
library(ggplot2)
library(quanteda)
library(HunMineR)
library(plotly)

Mielőtt két esettanulmányt bemutatnánk, vizsgáljuk meg, hogyan néz ki egy szentimentszótár az R-ben. A szótárt kézzel úgy tudjuk elkészíteni, hogy egy listán belül létrehozzuk karaktervektorként a kategóriákat és a kulcsszavakat, és ezt a listát a quanteda dictionary függvényével eltároljuk.

szentiment_szotar <- dictionary(
  list(
    pozitiv = c("jó", "boldog", "öröm"),
    negativ = c("rossz", "szomorú", "lehangoló")
    )
  )

szentiment_szotar
#> Dictionary object with 2 key entries.
#> - [pozitiv]:
#>   - jó, boldog, öröm
#> - [negativ]:
#>   - rossz, szomorú, lehangoló

A quanteda, quanteda.corpora és tidytext R csomagok több széles körben használt szentiment szótárat tartalmaznak, így nem kell kézzel replikálni minden egyes szótárat, amit használni szeretnénk.

A szentiment elemzési munkafolyamat, amit ebben a részfejezetben bemutatunk, a következő lépésekből áll:

  1. dokumentumok betöltése,
  2. szöveg előkészítése,
  3. a korpusz létrehozása,
  4. dokumentum-kifejezés mátrix létrehozása,
  5. szótár betöltése,
  6. a dokumentum-kifejezés mátrix szűrése a szótárban lévő kulcsszavakkal,
  7. az eredmény vizualizálása, további felhasználása.

A fejezetben két különböző korpuszt fogunk elemezni: a 2006-os Magyar Nemzet címlapjainak egy 252 cikkből álló mintáját vizsgáljuk egy magyar szentiment szótárral.30 A második korpusz a Magyar Nemzeti Bank angol nyelvű sajtóközleményeiből áll, amin egy széles körben használt gazdasági szótár használatát mutatjuk be.31

6.3 A Magyar Nemzet elemzése

mn_minta <- HunMineR::data_magyar_nemzet_small

A HunMineR csomag segítségével beolvassuk a Magyar Nemzet adatbázis egy kisebb részét, ami az esetünkben a 2006-os címlapokon szereplő híreket jelenti. A summary() parancs, ahogy a neve is mutatja, gyors áttekintést nyújt a betöltött adatbázisról. Látjuk, hogy 2834 sorból (megfigyelés) és 3 oszlopból (változó) áll. Első ránézésre látszik, hogy a text változónk tartalmazza a szövegeket, és hogy azok tisztításra szorulnak.

glimpse(mn_minta)
#> Rows: 2,834
#> Columns: 3
#> $ doc_id   <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31…
#> $ text     <chr> "Hat fővárosi képviselő öt percnél is kevesebbet beszélt egy év alatt a közgyűlésben.\n\n\n\n\n\n\n\n\n\n\n", "Mo…
#> $ doc_date <date> 2006-01-02, 2006-01-02, 2006-01-02, 2006-01-02, 2006-01-02, 2006-01-02, 2006-01-02, 2006-01-02, 2006-01-02, 2006…

A glimpse függvény segítségével belepillanthatunk a használt korpuszba és láthatjuk, hogy az 3 oszlopból áll a dokumentum azonosítójából, amely csak egy sorszám, a dokumentum szövegéből, és a dokumentumhoz tartozó azonosítóból.

Az első szöveget megnézve látjuk, hogy a standard előkészítési lépések mellett a sortörést (\n) is ki kell törölnünk.

mn_minta$text[1]
#> [1] "Hat fővárosi képviselő öt percnél is kevesebbet beszélt egy év alatt a közgyűlésben.\n\n\n\n\n\n\n\n\n\n\n"

Habár a quanteda is lehetőséget ad néhány előkészítő lépésre, érdemes ezt olyan céleszközzel tenni, ami nagyobb rugalmasságot ad a kezünkbe. Mi erre a célra a stringr csomagot használjuk. Első lépésben kitöröljük a sortöréseket (\n), a központozást, a számokat és kisbetűsítünk minden szót. Előfordulhat, hogy (számunkra nehezen látható) extra szóközök maradnak a szövegben. Ezeket az str_squish()függvénnyel tüntetjük el. A szöveg eleji és végi extra szóközöket (leading vagy trailing white space) az str_trim() függvény vágja le.

mn_tiszta <- mn_minta %>%
  mutate(
    text = stringr::str_remove_all(string = text, pattern = "\n"),
    text = stringr::str_remove_all(string = text, pattern = "[:punct:]"),
    text = stringr::str_remove_all(string = text, pattern = "[:digit:]"),
    text = stringr::str_to_lower(text),
    text = stringr::str_trim(text),
    text = stringr::str_squish(text)
  )

A szöveg sokkal jobban néz ki, habár észrevehetjük, hogy maradhattak benne problémás részek, főleg a sortörés miatt, ami sajnos hol egyes szavak közepén van (a jobbik eset), vagy pedig pont szóhatáron, ez esetben a két szó sajnos összevonódik. Az egyszerűség kedvéért feltételezzük, hogy ez kellően ritkán fordul elő ahhoz, hogy ne befolyásolja az elemzésünk eredményét.

mn_tiszta$text[1]
#> [1] "hat fővárosi képviselő öt percnél is kevesebbet beszélt egy év alatt a közgyűlésben"

Miután kész a tisztá(bb) szövegünk, korpuszt hozunk létre a quanteda corpus() függvényével. A korpusz objektum a szöveg mellett egyéb dokumentum meta adatokat is tud tárolni (dátum, író, hely, stb.) Ezeket mi is hozzáadhatjuk (erre majd látunk példát), illetve amikor létrehozzuk a korpuszt a data frame-ünkből, automatikusan metaadatokként tárolódnak a változóink. Jelen esetben az egyetlen dokumentum változónk a szöveg mellett a dátum lesz. A korpusz dokumentum változóihoz a docvars() függvény segítségével tudunk hozzáférni.

mn_corpus <- corpus(mn_tiszta)

head(docvars(mn_corpus), 5)
#>     doc_date
#> 1 2006-01-02
#> 2 2006-01-02
#> 3 2006-01-02
#> 4 2006-01-02
#> 5 2006-01-02

A következő lépés a dokumentum-kifejezés mátrix létrehozása a dfm() függvénnyel. Először tokenekre bontjuk a szövegeket a tokens() paranccsal, és aztán ezt a tokenizált szózsákot kapja meg a dfm inputnak. A sor a végén a létrehozott mátrixunkat TF-IDF módszerrel súlyozzuk a dfm_tfidf() függvény használatával.

mn_dfm <- mn_corpus %>%
  tokens(what = "word") %>%
  dfm() %>%
  dfm_tfidf()

A cikkek szentimentjét egy magyar szótárral fogjuk becsülni, amit a Társadalomtudományi Kutatóközpont kutatói a Mesterséges Intelligencia Nemzeti Laboratórium projekt keretében készítettek.32 Két dimenziót tarlamaz (pozitív és negatív), 2614 pozitív és 2654 negatív kulcsszóval. Ez nem számít kirívóan nagynak a szótárak között, mivel az adott kategóriák minél teljesebb lefedése a cél.

poltext_szotar <- HunMineR::dictionary_poltext

poltext_szotar
#> Dictionary object with 2 key entries.
#> - [positive]:
#>   - abszolút, ad, adaptív, adekvát, adócsökkentés, adókedvezmény, adomány, adományoz, adóreform, adottság, adottságú, áfacsökkentés, agilis, agytröszt, áhított, ajándék, ajándékoz, ajánl, ajánlott, akadálytalan [ ... and 2,279 more ]
#> - [negative]:
#>   - aberrált, abnormális, abnormalitás, abszurd, abszurditás, ádáz, adócsalás, adócsaló, adós, adósság, áfacsalás, áfacsaló, affér, aggasztó, aggodalom, aggódik, aggódás, agresszió, agresszíven, agresszivitás [ ... and 2,568 more ]

Az egyes dokumentumok szentimentjét a dfm_lookup() becsüli, ahol az előző lépésben létrehozott súlyozott dfm az input és a magyar szentimentszótár a dictionary. Egy gyors pillantás az eredményre és látjuk hogy minden dokumentumhoz készült egy pozitív és egy negatív érték. A TF-IDF súlyozás miatt nem látunk egész számokat (a súlyozás nélkül a sima szófrekvenciát kapnánk).

mn_szentiment <- quanteda::dfm_lookup(mn_dfm, dictionary = poltext_szotar)

head(mn_szentiment, 5)
#> Document-feature matrix of: 5 documents, 2 features (40.00% sparse) and 1 docvar.
#>     features
#> docs positive negative
#>    1    0         0   
#>    2    0.838    12.50
#>    3    0         0   
#>    4   21.104     6.45
#>    5   11.036     8.13

Ahhoz, hogy fel tudjuk használni a kapott eredményt, érdemes dokumentumváltozóként eltárolni a korpuszban. Ezt a fent már használt docvars() függvény segítségével tudjuk megtenni, ahol a második argumentumként az új változó nevét adjuk meg.

docvars(mn_corpus, "pos") <- as.numeric(mn_szentiment[, 1])
docvars(mn_corpus, "neg") <- as.numeric(mn_szentiment[, 2])

head(docvars(mn_corpus), 5)
#>     doc_date    pos   neg
#> 1 2006-01-02  0.000  0.00
#> 2 2006-01-02  0.838 12.50
#> 3 2006-01-02  0.000  0.00
#> 4 2006-01-02 21.104  6.45
#> 5 2006-01-02 11.036  8.13

Végül a kapott korpuszt a kiszámolt szentimentértékekkel a quanteda-ban lévő convert() függvénnyel adattáblává alakítjuk. Aconvert() függvény dokumentációját érdemes elolvasni, mert ennek segítségével tudjuk a quanteda-ban elkészült objektumainkat átalakítani úgy, hogy azt más csomagok is tudják használni.

mn_df <- quanteda::convert(mn_corpus, to = "data.frame")

Mielőtt vizualizálnánk az eredményt érdemes a napi szintre aggregálni a szentimentértéket és egy nettó értéket kalkulálni (ld. 6.1. ábra).33

mn_df <- mn_df %>%
  group_by(doc_date) %>%
  summarise(
    daily_pos = sum(pos),
    daily_neg = sum(neg),
    net_daily = daily_pos - daily_neg
  )

Az így kapott plot y tengelyén az adott cikkek időpontját láthatjuk, míg az x tengelyén a szentiment értékeiket. Ebben több kiugrást is tapasztalhatunk. Természetesen messzemenő következtetéseket egy ilyen kis korpusz alapján nem vonhatunk le, de a kiugrásokhoz tartozó cikkek kvalitatív vizsgálatával megállapíthatjuk, hogy az áprilisi kiugrást a választásokhoz kötődő cikkek pozitív hangulata, míg az októberi negatív kilengést az öszödi beszéd nyilvánosságra kerüléséhez köthető cikkek negatív szentimentje okozza.

mncim_df <- ggplot(mn_df, aes(doc_date, net_daily)) + geom_line() + labs(y = "Szentiment",
    x = NULL, caption = "Adatforrás: https://cap.tk.hu/")

ggplotly(mncim_df)

Ábra 6.1: Magyar Nemzet címlap szentimentje

6.4 MNB sajtóközlemények

A második esettanulmányban a kontextuális szótárelemzést mutatjuk be egy angol nyelvű korpusz és specializált szótár segítségével. A korpusz az MNB kamatdöntéseit kísérő nemzetközi sajtóközleményei, a szótár pedig a Loughran and McDonald (2011) pénzügyi szentimentszótár.34

penzugy_szentiment <- HunMineR::dictionary_LoughranMcDonald
penzugy_szentiment
#> Dictionary object with 9 key entries.
#> - [NEGATIVE]:
#>   - abandon, abandoned, abandoning, abandonment, abandonments, abandons, abdicated, abdicates, abdicating, abdication, abdications, aberrant, aberration, aberrational, aberrations, abetting, abnormal, abnormalities, abnormality, abnormally [ ... and 2,335 more ]
#> - [POSITIVE]:
#>   - able, abundance, abundant, acclaimed, accomplish, accomplished, accomplishes, accomplishing, accomplishment, accomplishments, achieve, achieved, achievement, achievements, achieves, achieving, adequately, advancement, advancements, advances [ ... and 334 more ]
#> - [UNCERTAINTY]:
#>   - abeyance, abeyances, almost, alteration, alterations, ambiguities, ambiguity, ambiguous, anomalies, anomalous, anomalously, anomaly, anticipate, anticipated, anticipates, anticipating, anticipation, anticipations, apparent, apparently [ ... and 277 more ]
#> - [LITIGIOUS]:
#>   - abovementioned, abrogate, abrogated, abrogates, abrogating, abrogation, abrogations, absolve, absolved, absolves, absolving, accession, accessions, acquirees, acquirors, acquit, acquits, acquittal, acquittals, acquittance [ ... and 883 more ]
#> - [CONSTRAINING]:
#>   - abide, abiding, bound, bounded, commit, commitment, commitments, commits, committed, committing, compel, compelled, compelling, compels, comply, compulsion, compulsory, confine, confined, confinement [ ... and 164 more ]
#> - [SUPERFLUOUS]:
#>   - aegis, amorphous, anticipatory, appertaining, assimilate, assimilating, assimilation, bifurcated, bifurcation, cessions, cognizable, concomitant, correlative, deconsolidation, delineation, demonstrable, demonstrably, derecognized, derecognizes, derivatively [ ... and 36 more ]
#> [ reached max_nkey ... 3 more keys ]

A szentimentszótár 9 kategóriából áll. A legtöbb kulcsszó a negatív dimenzióhoz van (2355).

A munkamenet hasonló az előző példához:

  1. adat betöltés,
  2. szövegtisztítás,
  3. korpusz létrehozás,
  4. tokenizálás,
  5. kulcs kontextuális tokenek szűrése,
  6. dfm előállítás és szentiment számítás,
  7. az eredmény vizualizálása, további felhasználása.
mnb_pr <- HunMineR::data_mnb_pr

Adatbázisunk 180 megfigyelésből és 4 változóból áll. Az egyetlen lényeges dokumentum metaadat itt is a szövegek megjelenési ideje, de a glimpse függvénnyel itt is ellenőrizhetjük hogyan néz ki a korpusz felépítése és milyen metaadatokat tartalmaz pontosan.

glimpse(mnb_pr)
#> Rows: 180
#> Columns: 4
#> $ date <date> 2005-01-24, 2005-02-21, 2005-03-29, 2005-04-25, 2005-05-23, 2005-06-20, 2005-07-18, 2005-08-22, 2005-09-19, 2005-10-…
#> $ text <chr> "At its meeting on January the Monetary Council considered the latest economic and financial developments and decided…
#> $ id   <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32…
#> $ year <dbl> 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2006, 2006, 2006, 2006, 2006, 2006, 2006, 200…

Ez alapján pedig láthatjuk, hogy a korpusz a tényleges szövegek mellett tartalmaz még id sorszámot, pontos dátumot és évet is.

A szövegeket ugyanazokkal a standard eszközökkel kezeljük, mint a Magyar Nemzet esetében. Érdemes minden esetben ellenőrizni, hogy az R-kód, amit használunk, tényleg azt csinálja-e, amit szeretnénk. Ez hatványozottan igaz abban az esetben, amikor szövegekkel és reguláris kifejezésekkel dolgozunk.

mnb_tiszta <- mnb_pr %>%
  mutate(
    text = str_remove_all(string = text, pattern = "[:cntrl:]"),
    text = str_remove_all(string = text, pattern = "[:punct:]"),
    text = str_remove_all(string = text, pattern = "[:digit:]"),
    text = str_to_lower(text),
    text = str_trim(text),
    text = str_squish(text)
  )

Miután rendelkezésre állnak a tiszta dokumentumaink, egy karaktervektorba gyűjtjük azokat a kulcsszavakat, amelyek környékén szeretnénk megfigyelni a szentiment alakulását. A példa kedvéért mi az unemp*, growth, gdp, inflation* szótöveket és szavakat választottuk. A tokens_keep() megtartja a kulcsszavainkat és egy általunk megadott +/- n tokenes környezetüket (jelen esetben 10). A szentimentelemzést pedig már ezen a jóval kisebb mátrixon fogjuk lefuttatni. A phrase() segítségével több szóból álló kifejezéséket is vizsgálhatunk. Ilyen szókapcsolat például az „Európai Unió” is, ahol lényeges, hogy egyben kezeljük a két szót.

mnb_corpus <- corpus(mnb_tiszta)

gazdasag <- c("unemp*", "growth", "gdp", "inflation*", "inflation expectation*")

mnb_token <- tokens(mnb_corpus) %>%
  tokens_keep(pattern = phrase(gazdasag), window = 10)

A szentimentet most is egy súlyozott dfm-ből számoljuk. A kész eredményt hozzáadjuk a korpuszhoz, majd adattáblát hozunk létre belőle. A 7 kategóriából 5-öt használunk csak, amelyeknek jegybanki környezetben értelmezhető tartalma van.

mnb_szentiment <- tokens_lookup(mnb_token, dictionary = penzugy_szentiment) %>%
  dfm() %>%
  dfm_tfidf()

docvars(mnb_corpus, "negative") <- as.numeric(mnb_szentiment[, "negative"])
docvars(mnb_corpus, "positive") <- as.numeric(mnb_szentiment[, "positive"])
docvars(mnb_corpus, "uncertainty") <- as.numeric(mnb_szentiment[, "uncertainty"])
docvars(mnb_corpus, "constraining") <- as.numeric(mnb_szentiment[, "constraining"])
docvars(mnb_corpus, "superfluous") <- as.numeric(mnb_szentiment[, "superfluous"])

mnb_df <- convert(mnb_corpus, to = "data.frame")

A célunk, hogy szentiment kategóriánkénti bontásban mutassuk be az elemzésünk eredményét, de előtte egy kicsit alakítani kell az adattáblán, hogy a korábban már tárgyalt tidy formára hozzuk. A különböző szentiment értékeket tartalmazó oszlopokat fogjuk átrendezni úgy, hogy kreálunk egy „sent_type” változót, ahol a kategória nevet fogjuk eltárolni és egy „sent_score” változót, ahol a szentiment értéket. Ehhez a tidyr-ben található pivot_longer() föggvényt használjuk.

mnb_df <- mnb_df %>%
  tidyr::pivot_longer(
    cols = negative:superfluous,
    names_to = "sent_type",
    values_to = "sent_score"
  )

Az átalakítás után már könnyedén tudjuk kategóriákra bontva megjeleníteni az MNB közlemények különböző látens dimenzióit. Fontos emlékezni arra, hogy ez az eredmény a kulcsszavaink +/- 10 tokenes környezetében lévő szavak szentimentjét méri. Az így kapott ábránk a három alkalmazott szentiment kategória időbeli előfordulását mutatja be. Ami érdekes eredmény, hogy a felesleges „töltelék” (superfluous) szövegek szinte soha nem fordulnak elő a kulcsszavaink körül. A többi érték is nagyjából megfelel a várakozásainknak, habár a 2008-as gazdasági válság nem tűnik kiugró pontnak. Azonban a 2010 utáni európai válság már láthatóan megjelenik az idősorainkban (ld. 6.2. ábra).

Az általunk használt szótár alapvetően az Egyesült Államokban a tőzsdén kereskedő cégek publikus beszámolóiból készült, így elképzelhető, hogy egyes jegybanki környezetben sokat használt kifejezések nincsenek benne. A kapott eredmények validálása ezért is nagyon fontos, illetve érdemes azzal is tisztában lenni, hogy a szótáras módszer nem tökéletes (ahogy az emberi vagy más gépi kódolás sem).

mnsent_df <- ggplot(mnb_df, aes(date, sent_score)) +
  geom_line() +
  labs(
    y = NULL,
    x = NULL
  ) +
  facet_wrap(~sent_type, ncol = 1)+
  theme(panel.spacing = unit(2, "lines"))

ggplotly(mnsent_df)

Ábra 6.2: Magyar Nemzeti Bank közleményeinek szentimentje


  1. Bővebben lásd például: (Liu 2010)↩︎

  2. A lehetséges, területspecifikus szótáralkotási módszerekről részletesebben ezekben a tanulmányokban lehet olvasni: Laver and Garry (2000); Young and Soroka (2012); Loughran and McDonald (2011); Máté, Sebők, and Barczikay (2021)↩︎

  3. A szótár és dokumentációja elérhető az alábbi linken: https://github.com/aesuli/SentiWordNet↩︎

  4. A quanteda.dictionaries csomag leírása és a benne található szótárak az alábbi github linken érhetőek el: https://github.com/kbenoit/quanteda.dictionaries↩︎

  5. A szótár és dokumentációja elérhető itt: http://www2.imm.dtu.dk/pubdb/pubs/6010-full.html↩︎

  6. A szótár és dokumentációja elérhető itt: https://www.cs.uic.edu/~liub/FBS/sentiment-analysis.html↩︎

  7. A szótár és dokumentációja elérhető itt: http://saifmohammad.com/WebPages/NRC-Emotion-Lexicon.htm↩︎

  8. A szentimentelemzéshez gyakran használt csomag még a tidytext. A szerzők online is szabadon elérhető könyvük Silge and Robinson (2017) 2. fejezetében részletesen is bemutatják a tidytext munkafolyamatot: (https://www.tidytextmining.com/sentiment.html).↩︎

  9. A korpusz a Hungarian Compartive Agendas Project keretében készült és regisztáció után, kutatási célra elérhető az alábbi linken: https://cap.tk.hu/a-media-es-a-kozvelemeny-napirendje.↩︎

  10. A korpusz, a szótár és az elemzés teljes dokumentációja elérhető az alábbi github linken: https://github.com/poltextlab/central_bank_communication, a teljes elemzés (Máté, Sebők, and Barczikay 2021) elérhető: https://doi.org/10.1371/journal.pone.0245515↩︎

  11. ELKH TK MILAB: https://milab.tk.hu/hu A szótár és a hozzátartozó dokumentáció elérhető az alábbi github oldalon: https://github.com/poltextlab/sentiment_hun↩︎

  12. A csoportosított adatokkal való munka bővebb bemutatását lásd a Függelékben.↩︎

  13. A témával részletesen foglalkozó tanulmányban egy saját monetáris szentimentszótárat mutatunk be: Az implementáció és a hozzá tartozó R forráskód nyilvános: https://doi.org/10.6084/m9.figshare.13526156.v1↩︎