Peatükk 6 Mitmikud, regulaaravaldised ja märksõnad
Selles peatükis vaatame, kuidas saab tidyverse ja tidytext pakettide abil töötada sõnamitmikega, kasutada regulaaravaldisi otsingutes ning leida märksõnu, mis iseloomustavad mõnd teksti või tekstidegruppi.
Kui me käivitasime just R-i, siis alustame jälle pakettide käivitamisest.
Samuti vajame me taaskord andmestikku. Veenduge, et töökataloog on määratud õigesse kohta.
## Parsed with column specification:
## cols(
## year = col_double(),
## rank = col_double(),
## votes = col_double(),
## artist = col_character(),
## song = col_character(),
## filename = col_character(),
## source = col_double(),
## lyrics = col_character(),
## language = col_character()
## )
6.1 Bigrammid
Eelmises peatükis kasutasime unnest_tokens() funktsiooni, et lahutada tabelis olevaid tekste sõnapikkusteks üksusteks. Nagu teised funktsioonis R-is on ka unnest_tokens() mõneti paindlik ja sellega saab teha veidi teistsuguseid asju, muutes selle parameetreid. Kasutame küsimärki ? käsu ees, et saada liig selle abifailile. Käsu käivitamine avab abiteksti paremal all ja näitab seda failide asemel. Failide ja abiteksti vahel saab liikuda selle akna menüüs (siis vastavalt Help ja Files sälgud).
Abikäsk näitab käsu sisu, näiteid ja parameetreid, mida saab selles muuta.
unnest_tokens(tbl, output, input, token = "words", format = c("text",
"man", "latex", "html", "xml"), to_lower = TRUE, drop = TRUE,
collapse = NULL, ...)
Esimene neist parameetritest on see, millele annab sisendi %>% toru käsk tidyverse töötluses. Antud juhul siis tbl, mis on sisendtabel. Enamasti ongi vaikimisi esimene sisend just andmestik, millega töötatakse. Parameetreid võib määrata järjekorra järgi, või andes ette parameetri nime. Näiteks unnest_tokens(word,text) on sama kui unnest_tokens(output=word, input=text) juhul kui alustabel tbl on söödetud käsu eestpoolt ja toruga.
Funktsioonil on aga veel parameetreid. Kõik parameetrid, millel on antud abifailis võrdusmärgiga = vaste, on parameetrid, millel on olemas vaikimisi väärtus. Ehk, kui me ise just teisiti ei määra, kasutab programm käsu vaikeväärtust. Vaikimisi võtab programm sõna ühikuks token = “words”. Samuti määrab ta vaikimisi, et to_lower = TRUE, misläbi muudetakse kõik suurtähed väiketähtedeks ja drop = TRUE, misläbi eemaldatakse sõnade leidmise aluseks olnud tulp. Kõikide parameetrite seletus on antud abifailis veidi allpool.
Vaadates lähemalt token parameetrit näeme, et sellel on hulga variante: “words” (vaikimisi), “characters”, “character_shingles”, “ngrams”, “skip_ngrams”, “sentences”, “lines,”paragraphs, “regex”, “tweets”, “ptb”. Meil ei ole neid kõiki praegu vaja, aga võime proovida varianti ngrams ehk mitmikud.
Meenutuseks, et eelmises õppetükis tegime sellise tabeli. Me võime seal eraldi märkida, et token = “words”, aga me võime selle ka ära jätta, kuna “words” on seal antud juhul vaikeväärtus.
## # A tibble: 157,632 x 9
## year rank votes artist song filename source language word
## <dbl> <dbl> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 1994 1 NA Ummamuu… Kõnõtr… lyrics-ummamuud… 1 et välän
## 2 1994 1 NA Ummamuu… Kõnõtr… lyrics-ummamuud… 1 et külmetas
## 3 1994 1 NA Ummamuu… Kõnõtr… lyrics-ummamuud… 1 et ja
## 4 1994 1 NA Ummamuu… Kõnõtr… lyrics-ummamuud… 1 et taivast
## 5 1994 1 NA Ummamuu… Kõnõtr… lyrics-ummamuud… 1 et satas
## 6 1994 1 NA Ummamuu… Kõnõtr… lyrics-ummamuud… 1 et lummõ
## 7 1994 1 NA Ummamuu… Kõnõtr… lyrics-ummamuud… 1 et ütle
## 8 1994 1 NA Ummamuu… Kõnõtr… lyrics-ummamuud… 1 et mullõ
## 9 1994 1 NA Ummamuu… Kõnõtr… lyrics-ummamuud… 1 et uma
## 10 1994 1 NA Ummamuu… Kõnõtr… lyrics-ummamuud… 1 et telefoni…
## # … with 157,622 more rows
Samas nägime abifailist, et seda võib ka muuta. Asetame siis selleks “ngrams”. Kui väärtuseks on määratud “ngrams”, siis me peame omakorda määrama selles lisaparameetreid. Nimelt soovib käsk teada, kui suuri mitmikuid me soovime. Määratleme minimaalse suuruse n_min = 2 ja maksimaalse suuruse n = 2. Sellisel juhul teeb unnest_tokens() sõnade tabeli asemel bigrammide tabeli.
## # A tibble: 156,810 x 9
## year rank votes artist song filename source language bigram
## <dbl> <dbl> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 1994 1 NA Ummamuu… Kõnõt… lyrics-ummamuu… 1 et välän külm…
## 2 1994 1 NA Ummamuu… Kõnõt… lyrics-ummamuu… 1 et külmetas ja
## 3 1994 1 NA Ummamuu… Kõnõt… lyrics-ummamuu… 1 et ja taivast
## 4 1994 1 NA Ummamuu… Kõnõt… lyrics-ummamuu… 1 et taivast sa…
## 5 1994 1 NA Ummamuu… Kõnõt… lyrics-ummamuu… 1 et satas lummõ
## 6 1994 1 NA Ummamuu… Kõnõt… lyrics-ummamuu… 1 et lummõ ütle
## 7 1994 1 NA Ummamuu… Kõnõt… lyrics-ummamuu… 1 et ütle mullõ
## 8 1994 1 NA Ummamuu… Kõnõt… lyrics-ummamuu… 1 et mullõ uma
## 9 1994 1 NA Ummamuu… Kõnõt… lyrics-ummamuu… 1 et uma telefo…
## 10 1994 1 NA Ummamuu… Kõnõt… lyrics-ummamuu… 1 et telefoninu…
## # … with 156,800 more rows
Proovime mängida parameetritega. Näiteks võime käsu sees määratleda ka et mitmike pikkus peaks olema ühest kolmeni. Sellisel juhul näitab käsk kõiki võimalikke mitmike suurusega ühest kolmeni, ehk nii sõnu, bigramme kui trigramme.
## # A tibble: 470,074 x 9
## year rank votes artist song filename source language bigram
## <dbl> <dbl> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 1994 1 NA Ummamuu… Kõnõt… lyrics-ummamuu… 1 et välän
## 2 1994 1 NA Ummamuu… Kõnõt… lyrics-ummamuu… 1 et välän külm…
## 3 1994 1 NA Ummamuu… Kõnõt… lyrics-ummamuu… 1 et välän külm…
## 4 1994 1 NA Ummamuu… Kõnõt… lyrics-ummamuu… 1 et külmetas
## 5 1994 1 NA Ummamuu… Kõnõt… lyrics-ummamuu… 1 et külmetas ja
## 6 1994 1 NA Ummamuu… Kõnõt… lyrics-ummamuu… 1 et külmetas j…
## 7 1994 1 NA Ummamuu… Kõnõt… lyrics-ummamuu… 1 et ja
## 8 1994 1 NA Ummamuu… Kõnõt… lyrics-ummamuu… 1 et ja taivast
## 9 1994 1 NA Ummamuu… Kõnõt… lyrics-ummamuu… 1 et ja taivast…
## 10 1994 1 NA Ummamuu… Kõnõt… lyrics-ummamuu… 1 et taivast
## # … with 470,064 more rows
Võtame siis ette bigrammid. Et meil on tabelit korduvalt vaja ning selle tekitamine võtab hetk aega, salvestame selle tulemuse jälle muutujasse.
Samamoodi kui sõnadest, saame me teha ka bigrammidest sagedustabeli. Levinud fraasid on ikka samad kui keeles ikka ‘ei saa’, ‘ei ole’, ‘ei tea’, ‘ma ei’, ‘ma olen’, ‘mul on’.
## # A tibble: 76,888 x 2
## bigram n
## <chr> <int>
## 1 ei saa 357
## 2 ma ei 356
## 3 see on 241
## 4 ei ole 204
## 5 <NA> 178
## 6 ei tea 165
## 7 na na 165
## 8 on see 160
## 9 ma olen 145
## 10 mul on 138
## # … with 76,878 more rows
Nagu sai näidatud varasemates peatükkides saame loendada mitu tunnust korraga. Seeläbi saame näiteks kokku lugeda fraasikordusi ühes laulus. Näiteks na na, oo oo ja ba da on väga populaarsed fraasid.
## # A tibble: 99,430 x 3
## bigram song n
## <chr> <chr> <int>
## 1 na na Tantsin valssi 68
## 2 na na Tantsin Valssi 68
## 3 vesi peale Vesi peale 56
## 4 oo oo Rannamaja 50
## 5 ba da Musi 48
## 6 jalas polnud Peegelpõrand 48
## 7 polnud pükse Peegelpõrand 48
## 8 armastus on Armastus On Armastus 47
## 9 pappi ei Pankrot 46
## 10 and i Pictures 43
## # … with 99,420 more rows
Samas näeme sellega ära, et meie andmestik on veidi ebamugav selle kohta pealt, et mõni laul on seal mitu korda. Ja samas või selle laulu nimi olla sama või erinev. Kui me nüüd loendame ainult fraasi ja laulunime järgi, siis võib mõni lugu saada seal mitmekordsed numbrid, kuna laul justkui oleks kaks korda nii pikk kui ta on. Teisest küljest, me saame ühest ‘Tantsin valssi’ loost kätte juba info na na kohta, me ei pea seda kaks korda nägema.
Kui me loendame laulu, artisti ja aasta kombinatsioone, siis tabel juba mõneti muutubki. Näiteks “jalas polnud” ja “polnud pükse” kaovad edetabelist ära, kuna Peegelpõranda laul oli tabelis kaks aastat, mistõttu olid sõnasagedused leotud topelt.
## # A tibble: 105,352 x 5
## bigram song artist year n
## <chr> <chr> <chr> <dbl> <int>
## 1 na na Tantsin valssi Tuberkuloited & Urmas Voolpriit 2001 68
## 2 na na Tantsin Valssi The Tuberkuloited 2000 68
## 3 vesi peale Vesi peale N-Euro 2000 56
## 4 oo oo Rannamaja Getter Jaani ja Koit Toome 2014 50
## 5 ba da Musi Push Up 2000 48
## 6 armastus on Armastus On Armastus Külalised 2008 47
## 7 pappi ei Pankrot Toe Tag 2005 46
## 8 and i Pictures Ewert And The Two Dragons 2014 43
## 9 ei saagi Pankrot Toe Tag 2005 42
## 10 võid nii Estonian business Suur Papa 2013 42
## # … with 105,342 more rows
6.2 Valimi parandamine
Me võime võtta nüüd selle arvesse ja püüda meie valimit varasemate teadmiste põhjal parandada. Nimelt, me teame, et mõnikord võib olla pealkiri sama, kuid erineda väike ja suurtähtedelt ning me teame, et mõned lood on tabelis mitu aastat ehk mitu korda.
Me saame aga oma tabelit muuta selle järgi. mutate() käsule saame anda sisendiks, et ta viiks tulbad väiketähtede kujule. Selleks on funktsioon tolower(). Ja me saame grupeerida ja filtreerida andmsetikku nii, et iga artisti ja laulu kombinatsiooni kohta jääb alles ainult esimene aasta.
edetabel %>%
mutate(artist=tolower(artist),song=tolower(song)) %>%
group_by(artist,song) %>%
filter(year==min(year))
## # A tibble: 947 x 9
## # Groups: artist, song [946]
## year rank votes artist song filename source lyrics language
## <dbl> <dbl> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 1994 1 NA ummamuu… kõnõtr… lyrics-umma… 1 ":,:Välän kü… et
## 2 1994 2 NA vennask… pille-… lyrics-venn… 1 "Taevas sine… et
## 3 1994 3 NA jam see 5 lyrics-jam-… 1 "See viis ha… et
## 4 1994 4 NA the tub… lillek… lyrics-the_… 1 "Tüdruk vaat… et
## 5 1994 5 NA the tub… põhjam… lyrics-the_… 1 "Kui käes on… et
## 6 1994 6 NA jam su jär… lyrics-jam-… 1 "Enne sind e… et
## 7 1994 7 NA 2 quick… olen l… lyrics-2_qu… 1 "1. PÕHJUST … et
## 8 1994 8 NA termina… torm lyrics-term… 1 "Olen tulnud… et
## 9 1994 9 NA 2 quick… sinu j… lyrics-2_qu… 1 "1. EKSISIN … et
## 10 1994 10 NA d-gän seib lyrics-d-ga… 1 "ELASID KOOS… et
## # … with 937 more rows
Niimoodi andmestikku muutes, saame kokku kokku 947 erinevat lugu eelmise 1000 asemel. Salvestame selle tabeli nime all firstsongs. Grupeeriv faktor tasub salvestades enamasti lahti siduda, kuna mõned funktsioonid nõuavad grupeerimata andmestikku või muutuvad väga aeglaseks siis, kui andmestik on tehtud paljudeks gruppideks.
firstsongs <- edetabel %>%
mutate(artist=tolower(artist),song=tolower(song)) %>%
group_by(artist,song) %>%
filter(year==min(year)) %>%
ungroup() # Kõige lõpus tasub grupid lahti siduda
Salvestatud puhastatud tabelit saame kasutada nüüd sisendina edasiseks analüüsiks. Leiame uuesti bigrammid tekstide seast ning salvestame need vana muutuja asemele.
bigrams <-firstsongs %>%
mutate(artist=tolower(artist),song=tolower(song)) %>%
group_by(artist,song) %>%
filter(year==min(year))%>%
ungroup() %>%
unnest_tokens(bigram, lyrics, token = "ngrams", n = 2, n_min = 2)
Samuti nagu varem võime nüüd loendada bigramme laulude kohta. Seekord aga ei pea vaatama, mis aastaga tegemist on ja paljud kordused on nüüd kadunud. On muidugi lugusid, millel artisti või laulu nimi erineb aasta-aastalt veidi rohkem kui ainult suurtähtede ja väiketähtede kaudu - näiteks seesama tantsin valssi, mille artist on muutunud. Aga paljuski saame me nii juba täpsema info. Et kõik sama loo erinevad variandid saaks eemaldatud, tuleb veel täpsemalt proovida artisti nimesid ühitada. Praegu piirdume suur- ja väiketähtedega.
## # A tibble: 98,793 x 4
## bigram song artist n
## <chr> <chr> <chr> <int>
## 1 na na tantsin valssi the tuberkuloited 68
## 2 na na tantsin valssi tuberkuloited & urmas voolpriit 68
## 3 vesi peale vesi peale n-euro 56
## 4 oo oo rannamaja getter jaani ja koit toome 50
## 5 ba da musi push up 48
## 6 armastus on armastus on armastus külalised 47
## 7 pappi ei pankrot toe tag 46
## 8 and i pictures ewert and the two dragons 43
## 9 ei saagi pankrot toe tag 42
## 10 võid nii estonian business suur papa 42
## # … with 98,783 more rows
6.3 Regulaaravaldised
Nagu varem sõnadega, võime me filtreerida seda tabelit ka fraasi kaupa. Näiteks ‘ei saa’ esinemised eri lauludes saame kätte niiviisi. Päris paljudes lauludes kordub fraas ‘ei saa’ mitmeid kordi. Tähele võib panna, et sellisel juhul on aga oluline, et fraas oleks täpselt selline nagu on kirjeldatud.
## # A tibble: 149 x 3
## bigram song n
## <chr> <chr> <int>
## 1 ei saa jagatud saladus 17
## 2 ei saa tahan elada 14
## 3 ei saa kesköödisko 9
## 4 ei saa teine kadriorg 9
## 5 ei saa sinise leegiga 8
## 6 ei saa kallis 7
## 7 ei saa lähedal 6
## 8 ei saa miks ainult mõni asi on nii hea 6
## 9 ei saa väike saatan 6
## 10 ei saa pankrot 5
## # … with 139 more rows
Me teame varem koostatud sõnaloendite põhjal, et sõna ‘ei’ on neis tekstides üldse sage. Kui me nüüd tahaks teada, millises kontekstis sõna ‘ei’ esineb, ei saa me ette kirjutada kõiki eri variante. Sellisel puhul on meil võimalik kasutada käske tekstiosade kattuvuseks ning regulaaravaldisi. Tidyverse pakettides on ka tekstidega töötamiseks eraldi osa stringr, kus on meid aitavad kaks funktsiooni str_detect(), mis kontrollib, kas tekstis sisaldub ettekirjutatud jupp ja str_extract(), mis eraldab kirjutatud jupi tekstist.
- str_detect(muutuja, “sõne”) - kontrolli, kas tekstis esineb selline järjend
- str_extract(muutuja, “sõne”) - leia selline järjend tekstis ning esita leitud järjend
Need funktsioonid võtavad sisendina vaikimisi regulaaravaldisi, mis avardab meie otsimisvõimekust oluliselt. Otsides ainult järjendit ‘ei saa’ leiame, et meie esialgne otsing ei leidnud varianti, ei saagi, mida kordub ühe loo sees isegi kõige rohkem. Nimelt läheb edetabeli tippu toe tag pankrott, kus fraas ‘ei saagi’ esineb suisa 42 korda. Kuivõrd ta on tähenduselt üsna sarnane, siis on seda meilgi ehk oluline teada.
## # A tibble: 177 x 3
## bigram song n
## <chr> <chr> <int>
## 1 ei saagi pankrot 42
## 2 ei saa jagatud saladus 17
## 3 ei saa tahan elada 14
## 4 ei saa kesköödisko 9
## 5 ei saa teine kadriorg 9
## 6 ei saa sinise leegiga 8
## 7 ei saa kallis 7
## 8 ei saa lähedal 6
## 9 ei saa miks ainult mõni asi on nii hea 6
## 10 ei saa väike saatan 6
## # … with 167 more rows
Me võime ka otsida kõiki sarnaseid fraase, mis algavad eitusega. Selleks otsime sõna ei, millele järgneb tühik ja siis ükskõik milline tähekombinatsioon. Ja saame, et neid eitavas vormides fraase on lugude seas veel. ei-ei, ei saa, ei hooli, ei pea, ei huvita ei lase, jne.
## # A tibble: 1,607 x 3
## bigram song n
## <chr> <chr> <int>
## 1 ei saagi pankrot 42
## 2 ei ei elupõletaja 36
## 3 ei saa jagatud saladus 17
## 4 ei hooli mälestused 16
## 5 ei pea ei pea iial 15
## 6 ei huvita elupõletaja 14
## 7 ei lase öö ei lase magada 14
## 8 ei saa tahan elada 14
## 9 ei ole võta aega 12
## 10 ei tagasi teine kadriorg 12
## # … with 1,597 more rows
Teine viis leida kõik fraasid, mis algavad sõnaga ei, on kasutada regulaaravaldiste teksti alguse tähist ^. Nii teab käsk, et ‘ei’ peab olema fraasi alguses.
## # A tibble: 1,553 x 3
## bigram song n
## <chr> <chr> <int>
## 1 ei saagi pankrot 42
## 2 ei ei elupõletaja 36
## 3 ei saa jagatud saladus 17
## 4 ei hooli mälestused 16
## 5 ei pea ei pea iial 15
## 6 ei huvita elupõletaja 14
## 7 ei lase öö ei lase magada 14
## 8 ei saa tahan elada 14
## 9 ei ole võta aega 12
## 10 ei tagasi teine kadriorg 12
## # … with 1,543 more rows
Tõtt-öelda bigrammidega piisab ka tühikust, kuna neis on tühik alati esimesest sõnast paremal.
## # A tibble: 1,610 x 3
## bigram song n
## <chr> <chr> <int>
## 1 ei saagi pankrot 42
## 2 ei ei elupõletaja 36
## 3 ei saa jagatud saladus 17
## 4 ei hooli mälestused 16
## 5 ei pea ei pea iial 15
## 6 ei huvita elupõletaja 14
## 7 ei lase öö ei lase magada 14
## 8 ei saa tahan elada 14
## 9 ei ole võta aega 12
## 10 ei tagasi teine kadriorg 12
## # … with 1,600 more rows
Võime proovida otsida ka näiteks sidesõnale ja järgnevaid sõnu.
## # A tibble: 2,624 x 3
## bigram song n
## <chr> <chr> <int>
## 1 ja ma lase mul olla mina 14
## 2 russkaja vodka russkaja vodka 14
## 3 ja loodame jää 13
## 4 ja me pankrot 13
## 5 vaja kedagi vihmapiisad päikest täis 13
## 6 ja kõik küsin endalt nõu 12
## 7 ja ma ma vaid palun 12
## 8 ja nooled pilgud ja nooled 12
## 9 ja pole pole sinu asi 12
## 10 ja silmad su hääl su suu ja silmad 12
## # … with 2,614 more rows
Me võime otsida sedasi ükskõik mida.
## # A tibble: 2,633 x 3
## bigram song n
## <chr> <chr> <int>
## 1 oma valu ehitaja 19
## 2 ma lähen sinu ees 18
## 3 ma tahan ma tahan sind. sa vajad mind 16
## 4 ma šokolaadist šokolaadist jänes 14
## 5 umma tshaka tsaka-tsaka 14
## 6 umma umma tsaka-tsaka 14
## 7 ma ei täna me ei skoori 13
## 8 ma lähen mõtetes mõrudais 13
## 9 ilma okasteta okkaline lill 12
## 10 kuuma kuuma maia 12
## # … with 2,623 more rows
## # A tibble: 48 x 3
## bigram song n
## <chr> <chr> <int>
## 1 mu põhjamaa põhjamaa neid 12
## 2 põhjamaa neid põhjamaa neid 12
## 3 ajamasin kaasa 1987 5
## 4 viib ajamasin 1987 5
## 5 õllele turjamaale vihma loits 4
## 6 turjamaale õlle vihma loits 4
## 7 varjama ei sinu jaoks 2
## 8 18 ajamasin jälle 18 1
## 9 ajama ju eestlased 1
## 10 ajama pean veel veel veel 1
## # … with 38 more rows
Proovige leida nüüd kõik fraasid, mis sisaldavad eestit ükskõik, mis kujul
Teine küsimus, kus regulaaravaldised kuluvad eriti ära, on kui me tahame teada saada teatud sõnavormide kohta. Näiteks meid huvitavad kõik armastusega seotud sõnad neis lauludes. Võime teha otsingu, mis hõlmaks ‘armastus’, ‘armastama’ ja selle vorme. Nii saame kätte kõik fraasid, kus on sellest mingil määral juttu.
## # A tibble: 223 x 3
## bigram song n
## <chr> <chr> <int>
## 1 armastus on armastus on armastus 47
## 2 on armastus armastus on armastus 14
## 3 armastus armastus armastus on armastus 13
## 4 tunde armastus armastus on armastus 10
## 5 yo armastus armastus on armastus 10
## 6 armastan ma kas tead 8
## 7 flow armastus armastus on armastus 7
## 8 armastanud kaua kaks meeste 6
## 9 polnud armastanud kaks meeste 6
## 10 armastuses ja väike valge vale 5
## # … with 213 more rows
Kui me aga tahame küsida sõna eri vormide kohta, võime me leidude vasted uude tabeli tulpa panna. str_extract() võtab tekstist välja täpselt sellise vormi, mis me leidsime.
bigrams %>%
count(bigram,song,sort=T) %>%
filter(str_detect(bigram,"armast[ua]")) %>%
mutate(vorm=str_extract(bigram,"armast[ua]"))
## # A tibble: 223 x 4
## bigram song n vorm
## <chr> <chr> <int> <chr>
## 1 armastus on armastus on armastus 47 armastu
## 2 on armastus armastus on armastus 14 armastu
## 3 armastus armastus armastus on armastus 13 armastu
## 4 tunde armastus armastus on armastus 10 armastu
## 5 yo armastus armastus on armastus 10 armastu
## 6 armastan ma kas tead 8 armasta
## 7 flow armastus armastus on armastus 7 armastu
## 8 armastanud kaua kaks meeste 6 armasta
## 9 polnud armastanud kaks meeste 6 armasta
## 10 armastuses ja väike valge vale 5 armastu
## # … with 213 more rows
Selleks, et saada tervet sõna, peame regulaaravaldist pikendama, et ta võtaks kaasa kõik tähestiku tähed, aga mitte tühikud.
bigrams %>%
count(bigram,song,sort=T) %>%
filter(str_detect(bigram,"armast[ua]")) %>%
mutate(vorm=str_extract(bigram,"armast[ua][a-zõäöü]+"))
## # A tibble: 223 x 4
## bigram song n vorm
## <chr> <chr> <int> <chr>
## 1 armastus on armastus on armastus 47 armastus
## 2 on armastus armastus on armastus 14 armastus
## 3 armastus armastus armastus on armastus 13 armastus
## 4 tunde armastus armastus on armastus 10 armastus
## 5 yo armastus armastus on armastus 10 armastus
## 6 armastan ma kas tead 8 armastan
## 7 flow armastus armastus on armastus 7 armastus
## 8 armastanud kaua kaks meeste 6 armastanud
## 9 polnud armastanud kaks meeste 6 armastanud
## 10 armastuses ja väike valge vale 5 armastuses
## # … with 213 more rows
Ja nüüd võime omakorda kokku lugeda, mis vormides need sõnad olid
bigrams %>%
count(bigram,song,sort=T) %>%
filter(str_detect(bigram,"armast[ua]")) %>%
mutate(vorm=str_extract(bigram,"armast[ua]([a-zõäöü]+)?")) %>%
count(vorm,sort=T)
## # A tibble: 21 x 2
## vorm n
## <chr> <int>
## 1 armastus 66
## 2 armastan 39
## 3 armastust 30
## 4 armastad 18
## 5 armastuse 16
## 6 armasta 14
## 7 armastada 8
## 8 armastab 6
## 9 armastades 2
## 10 armastama 2
## # … with 11 more rows
Samamoodi võime võtta näiteks välja kõik sõnad, mis järgnevad sõnale armastus, ükskõik, mis vormis. Lisame otsingule sõna alguse tähise, ning võtame välja kõik, mis järgneb tühikule. Nagu arvata oli on ikka kõige sagedasemad vormid muidu ka levinud sõnad. Samas pidagem meeles, et praegu me vaatasime, mitmes laulus need fraasid on. Me võime ka vaadata mitu korda fraase esineb kokku.
bigrams %>%
count(bigram,song,sort=T) %>%
filter(str_detect(bigram,"^armast[ua]")) %>%
mutate(vorm=str_extract(bigram," [a-zõäöü]+")) %>%
count(vorm,sort=T)
## # A tibble: 69 x 2
## vorm n
## <chr> <int>
## 1 " ja" 10
## 2 " sind" 6
## 3 " ma" 5
## 4 " on" 5
## 5 " mind" 4
## 6 " ei" 3
## 7 " kuid" 3
## 8 " nii" 3
## 9 " käib" 2
## 10 " kui" 2
## # … with 59 more rows
Tidyverse %>% märgiga kirjutatud koodis on selleks hea võimalus. Me võime lihtsalt mõne käsu välja kommenteerida # trellidega.
bigrams %>%
#count(bigram,song,sort=T) %>%
filter(str_detect(bigram,"^armast[ua]")) %>%
mutate(vorm=str_extract(bigram," [a-zõäöü]+")) %>%
count(vorm,sort=T)
## # A tibble: 69 x 2
## vorm n
## <chr> <int>
## 1 " on" 52
## 2 " ja" 16
## 3 " ma" 15
## 4 " armastus" 13
## 5 " sind" 9
## 6 " kaua" 6
## 7 " kuid" 5
## 8 " mind" 5
## 9 " tunda" 5
## 10 " kui" 4
## # … with 59 more rows
Proovige leida, mis vormides ‘eesti’ lauludes esineb.
6.4 Trigrammid
Sarnaselt bigrammidele saame unnest_tokens() parameetreid sättides võtta tekstidest välja ka trigrammid.
Võime neid samuti loendada.
## # A tibble: 99,130 x 2
## trigram n
## <chr> <int>
## 1 <NA> 177
## 2 na na na 142
## 3 ma ei saa 60
## 4 o o o 53
## 5 oh oh oh 51
## 6 oo oo oo 45
## 7 la la la 44
## 8 pappi ei saagi 42
## 9 me pappi ei 41
## 10 veel ja veel 41
## # … with 99,120 more rows
Ja võime ka nende kordusi loendada.
## # A tibble: 103,823 x 4
## # Groups: artist, song [946]
## artist song trigram n
## <chr> <chr> <chr> <int>
## 1 the tuberkuloited tantsin valssi na na na 64
## 2 tuberkuloited & urmas voolpriit tantsin valssi na na na 64
## 3 toe tag pankrot pappi ei saagi 42
## 4 toe tag pankrot me pappi ei 41
## 5 getter jaani ja koit toome rannamaja oo oo oo 40
## 6 kerli army of love love to love 40
## 7 cool d kas sa kuuled kas sa kuuled 30
## 8 suur papa estonian business nii faking teha 30
## 9 suur papa estonian business võid nii faking 30
## 10 vanilla ninja liar oh oh oh 28
## # … with 103,813 more rows
Kombineerides olemasolevaid käske võime nüüd näiteks otsida välja kõik fraasid, kus esineb sama sõna nii alguses kui lõpus. Me teame, et ^ märk tähistab rea algust ja et $ märk tähistab rea lõppu (vaata regulaaravaldiste juhendit moodle-is). Kui me nüüd võtame välja antud tabelist kõik esimesed ja viimased sõnad ja filtreerime välja ainult read, kus need on sama sõna, saamegi kätte oodatud tulemuse. Päris suur hulk fraase on sellist, kus on sees selline sõnakordus.
trigrams %>%
group_by(artist,song) %>%
count(trigram,sort=T) %>%
mutate(firstw=str_extract(trigram,"^[a-zõäöü]+"),lastw=str_extract(trigram,"[a-zõäöü]+$")) %>%
filter(firstw==lastw)
## # A tibble: 1,125 x 6
## # Groups: artist, song [445]
## artist song trigram n firstw lastw
## <chr> <chr> <chr> <int> <chr> <chr>
## 1 the tuberkuloited tantsin v… na na na 64 na na
## 2 tuberkuloited & urm… tantsin v… na na na 64 na na
## 3 getter jaani ja koi… rannamaja oo oo oo 40 oo oo
## 4 kerli army of l… love to love 40 love love
## 5 vanilla ninja liar oh oh oh 28 oh oh
## 6 dagö välismaa pool anna pool 26 pool pool
## 7 planeet satelliid… satelliidid satellii… 26 satelli… satelli…
## 8 dagö välismaa anna pool anna 24 anna anna
## 9 hu? elupõleta… ei ei ei 24 ei ei
## 10 n-euro vesi peale peale vesi peale 24 peale peale
## # … with 1,115 more rows
Keskmise sõna saaks kätte otsides sõnaäärseid tühikuid str_extract(trigram, " [a-zõäöü]+ "). Olles eraldanud sõna eraldi tulpa, võime sama tulpa käsitleda ka tekstina järgmisteks operatsioonideks. Kasutades olemasolevat informatsiooni, leia kõik fraasid, kus kõik kolm sõna on täpselt samad.
6.5 Märksõnade leidmine
Siiani oleme püüdnud leida tekstist meid huvitavaid sõnu eemaldades ebahuvitavad stopsõnad või otsides konkreetseid fraase, mis meile silma jäävad. Tekstitöötluses on üpris palju eri meetodeid ka selleks, et püüda välja arvutada huvitavad sõnad või fraasid mõne teksti kohta. Antconc-is sai seda teha märksõnaotsingu alusel - mida suurem keyness väärtus märksõnal oli, seda rohkem ta oli eriline sellele tekstile.
Üks viis selliseid märksõnu leida, mis on ka tidytext paketti sisse kirjutatud on tf-idf, see tähendab term frequency - inverse document frequency. Loe täpsemat sisu siit https://en.wikipedia.org/wiki/Tf-idf. Selle valemi aluseks on vaist, et kui sõna on sage ühes dokumendis, aga seda teistes tekstides tihti ei leidu, võiks seda pidada seda teksti eristavaks teistest ehk selle teksti märksõnaks. Selle arvutamiseks loetakse kokku kui palju on üht sõna konkreetses tekstis või tekstide kogumis ning korrutatakse läbi arvuga, mis iseloomustab kui paljudes tekstides seda on. Erinevaid variante sellest valemist on mitmeid ja see, milline neist on sobivaim konkreetse küsimuse lahendamiseks võib sõltuda korpuse suurusest, iseloomust või küsimusest endast. Üldjoontes annavad enamik neist mõistlikke tulemusi.
Niisiis, sõna, mis on üldiselt korpuses haruldane, aga sage selles tekstis on sõna, võiks olla selle teksti jaoks eristavaks märksõnaks. Sõnad, mida on palju kõikides tekstides ei erista seda teksti teistest. Samas sõnad, mis on eriti sagedased ühes tekstis võivad siiski osutuda märksõnadeks isegi kui neid on paljudes muudes tekstideski. Teisest küljest sõnad on üldiselt haruldased ning esinevad selles tekstis ainult paar korda, võivad nad juba hästi eristada seda teksti teistest. Tulemus sõltub täpsest valemist, mida on hetkel rakendatud.
Tidytext paketis on selle hõlpsaks leidmiseks olemas oma käsk bind_tf_idf(). See käsk liidab andmestikule tf-idf märksõnalisuse määrad. bind_tf_idf() võtab sisendiks sõna, grupeeriva tulba ning sõna sageduse igas grupis ning võrdleb seda sõna esinemisega teistes gruppides. Käsk teeb arvutustöö kõikide sõnade kohta ning liidab tulemused andmestikuga. Mida suurem on tf-idf, seda märgilisem on see sõna selle grupi jaoks.
Niisiis, saame käsu abiga hõlpsasti tuvastada teatud gruppi eristavad sõnad. Näiteks arvutame alustuseks artiste eristavad sõnad. Arvutame artiste teistest eristavad sõnad. Kuna me oleme seni kasutanud peatükis ainult fraase, siis arvutame kõigepealt laulusõnad.
Leidmaks tf-idf märksõnu, loendame sõnu artistide kaupa ning siis juhendame, bind_tf_idf() funktsiooni, et ta kasutaks seda informatsiooni oma mõõdikute välja arvutamiseks. Lõpuks järjestame sõnad tf_idf alusel, kus suurem väärtus näitam suuremat eristusjõudu.
tf_idf <- laulusonad %>%
group_by(artist) %>%
count(word) %>%
bind_tf_idf(word, artist,n) %>%
arrange(desc(tf_idf))
Vaatame tabelit esialgu ise lähemalt.
Tabelis näeme, et eristavad sõnad on väga tihti needsamad, mis olid väga sagedased teatud artistidele. See on parasjagu nii, kuna need olid ühtlasi sõnad, mida teised artistid kasutasid väga vähe. Näiteks satelliidid, Maiu ja piimaauto on üldiselt lauludes harva kasutatavad sõnad.
Põnevamaks muutub see määr kui püüda vaadata mõne konkreetse artisti eristavaid märksõnu.Smilersi puhul on levinud sõnad ja, ma, ei ikkagi tipus, kuna neid kasutatakse nende lugudes läbivalt väga palju. Haruldasemad sõnad ilmnevad hiljem, aga on siiski kohal teises kümendis
laulusonad %>%
group_by(artist) %>%
count(word) %>%
bind_tf_idf(word, artist,n) %>%
arrange(desc(tf_idf)) %>%
filter(artist=="Smilers") %>%
filter(row_number()<21)
## # A tibble: 20 x 6
## # Groups: artist [1]
## artist word n tf idf tf_idf
## <chr> <chr> <int> <dbl> <dbl> <dbl>
## 1 Smilers ja 290 0.0426 0.544 0.0232
## 2 Smilers ma 196 0.0288 0.676 0.0195
## 3 Smilers ei 179 0.0263 0.605 0.0159
## 4 Smilers oooo 24 0.00352 4.24 0.0150
## 5 Smilers on 234 0.0344 0.363 0.0125
## 6 Smilers sa 94 0.0138 0.862 0.0119
## 7 Smilers et 95 0.0140 0.783 0.0109
## 8 Smilers shalala 12 0.00176 5.85 0.0103
## 9 Smilers kao 15 0.00220 4.24 0.00935
## 10 Smilers kui 99 0.0145 0.643 0.00934
## 11 Smilers segamini 12 0.00176 5.16 0.00909
## 12 Smilers kummagi 10 0.00147 5.85 0.00859
## 13 Smilers mingil 10 0.00147 5.85 0.00859
## 14 Smilers mojito 10 0.00147 5.85 0.00859
## 15 Smilers mind 63 0.00925 0.918 0.00849
## 16 Smilers ainult 31 0.00455 1.86 0.00848
## 17 Smilers mida 39 0.00573 1.47 0.00842
## 18 Smilers kuhugi 16 0.00235 3.55 0.00834
## 19 Smilers põleda 11 0.00162 5.16 0.00833
## 20 Smilers seisan 19 0.00279 2.96 0.00826
Artistil, millel on lugusid korpuses vähem, on ka rohkem esil mõne üksiku loo märksõnad. Näiteks Nublul on korpuses kaks lugu ning sõnad, mis kordusid neis lugudes tihti, on selgelt esil. Nt ou, mina, ka.
laulusonad %>%
group_by(artist) %>%
count(word) %>%
bind_tf_idf(word, artist,n) %>%
arrange(desc(tf_idf)) %>%
filter(artist=="Nublu")
## # A tibble: 312 x 6
## # Groups: artist [1]
## artist word n tf idf tf_idf
## <chr> <chr> <int> <dbl> <dbl> <dbl>
## 1 Nublu ou 22 0.0280 4.47 0.125
## 2 Nublu mina 29 0.0369 2.14 0.0790
## 3 Nublu ka 39 0.0497 1.34 0.0666
## 4 Nublu pa 10 0.0127 4.47 0.0569
## 5 Nublu parap 6 0.00764 5.85 0.0447
## 6 Nublu peale 12 0.0153 2.21 0.0339
## 7 Nublu nagu 18 0.0229 1.46 0.0334
## 8 Nublu bonnie 4 0.00510 5.85 0.0298
## 9 Nublu cappuccino 4 0.00510 5.85 0.0298
## 10 Nublu clyde 4 0.00510 5.85 0.0298
## # … with 302 more rows
Mõnikord ei kasutatudki palju erinevaid sõnu. Näiteks artistil Koer saab need sõnad peaaegu kahe käe sõrmedel kokku lugeda ja ainult seetõttu, et ühe sõna iga täht on ka eraldi välja öeldud. Siiski on näha, et ‘on’ on neil kõige vähem eristavam sõna.
laulusonad %>%
group_by(artist) %>%
count(word) %>%
bind_tf_idf(word, artist,n) %>%
arrange(desc(tf_idf)) %>%
filter(artist=="Koer")
## # A tibble: 11 x 6
## # Groups: artist [1]
## artist word n tf idf tf_idf
## <chr> <chr> <int> <dbl> <dbl> <dbl>
## 1 Koer maiu 16 0.205 5.85 1.20
## 2 Koer piimaauto 16 0.205 5.85 1.20
## 3 Koer u 4 0.0513 3.45 0.177
## 4 Koer m 4 0.0513 3.29 0.169
## 5 Koer o 4 0.0513 3.29 0.169
## 6 Koer i 6 0.0769 1.55 0.119
## 7 Koer a 6 0.0769 1.52 0.117
## 8 Koer p 2 0.0256 4.47 0.115
## 9 Koer n 2 0.0256 3.91 0.100
## 10 Koer t 2 0.0256 2.96 0.0759
## 11 Koer on 16 0.205 0.363 0.0745
Keskmise laulude hulgaga artistidel tulevad samuti märksõnad üksikutest lauludest esile. Nt Kuldsel Triol hopp, johanna, vodka, laika jne on kõik sõnad, mis on korpuses üldiselt väga haruldased, aga nende lugude seas piisavalt sagedased. See, millised sõnad selle valemiga esile tulevad sõltub niisiis nii korpuse iseloomust kui ka tekstide enda suurusest ja kujust. Selleks, et nendest seostest paremini aru saada, tasub katsetada erinevate tekstide puhul, et mis märksõnad peale jäävad. Mõnikord võib lisada neile lisafiltreid - näiteks jätta üldse kõrvale sõnad, mis on väga haruldased või väga tihti kasutatud.
laulusonad %>%
group_by(artist) %>%
count(word) %>%
bind_tf_idf(word, artist,n) %>%
arrange(desc(tf_idf)) %>%
filter(artist=="Kuldne Trio")
## # A tibble: 266 x 6
## # Groups: artist [1]
## artist word n tf idf tf_idf
## <chr> <chr> <int> <dbl> <dbl> <dbl>
## 1 Kuldne Trio hopp 30 0.0459 5.85 0.269
## 2 Kuldne Trio johanna 30 0.0459 5.85 0.269
## 3 Kuldne Trio vodka 30 0.0459 5.85 0.269
## 4 Kuldne Trio laika 16 0.0245 5.16 0.126
## 5 Kuldne Trio russkaja 14 0.0214 5.85 0.125
## 6 Kuldne Trio tantsi 15 0.0230 4.06 0.0933
## 7 Kuldne Trio rossija 8 0.0123 5.85 0.0717
## 8 Kuldne Trio kotka 4 0.00613 5.85 0.0358
## 9 Kuldne Trio varblasest 4 0.00613 5.85 0.0358
## 10 Kuldne Trio kuni 10 0.0153 2.33 0.0356
## # … with 256 more rows
Proovi ise! Vali välja üks artist ning leia selle artisti kõige eristavamad sõnad.
Proovi ise! Vali välja ka üks laul ning proovi leida eristavad sõnad selle laulu kohta.
6.6 Sõnastik
- unnest_tokens() - segmenteeri tekst ühikute kaupa
- unnest_tokens(word, lyrics, token = “ngrams”, n = 1, n_min = 1) - segmenteeri tekst sõnedeks
- unnest_tokens(bigram, lyrics, token = “ngrams”, n = 2, n_min = 2) - segmenteeri tekst bigrammideks
- unnest_tokens(trigram, lyrics, token = “ngrams”, n = 3, n_min = 3) - segmenteeri tekst trigrammideks
- str_detect(muutuja, “sõne”) - kontrolli, kas tekstis on selline järjend. võib kasutada regulaaravaldisi
- str_extract(muutuja, “sõne”) - võta välja tekstist sellele järjendile vastavad osad. võib kasutada regulaaravaldisi
- bind_tf_idf() - liidab andmestikule tf-idf märksõnalisuse määrad
6.7 Harjutusülesanded
Leia populaarseimad bigrammid 1990ndatel aastatel.
Leia kõik trigrammid, mis algavad sõnaga “ma”
Leia kõige rohkem ühe loo sees korduvad trigrammid.
Millised märksõnad eristavad aastat 2000 teistest aastatest?
Millised märksõnad eristavad eristavad Smilersi edukaimat laulu teistest Smilersi lauludest?