Tänases praktikumis

Eelmisel korral

  • Logistiliste mudelite headuse näitajad
  • Logistilise regressiooni eelduste kontroll
  • Mudeli valideerimine
  • Segamudelid

Sel korral

  • Tingimuslikud otsustuspuud
  • Otsustuspuude visualiseerimine

Regressioon vs. otsustuspuud

Regressioonimudelite puhul on võimalik hinnata ühe seletava tunnuse taseme/ühiku muutuse mõju uuritava tunnuse varieerumisele. Selles mõttes on regressioon lähim meetod kontrollitud katse tegemisele, kui tegelikult on kasutada ainult vaatlusandmed. Regressioonimudelid on parameetrilised mudelid, mis tähendab, et uute vaatluste väärtuste ennustamiseks piisab kindlate parameetrite hinnangute teadmisest. Näiteks lineaarses regressioonis, kus on 1 seletav tunnus, piisab vabaliikmest ja seletava tunnuse koefitsiendist selleks, et ennustada kõiki võimalikke väärtusi. Seda aga juhul, kui andmed vastavad kindlale jaotusele ning uuritavat tunnust saab ka päriselt ennustada lineaarse funktsiooni kaudu. Kui tegelikult ei ole uuritav tunnus kirjeldatav seletavate tunnuste lineaarse (st sirgjoonelise) kombinatsiooni kaudu, ei ennusta meie mudel tegelikult uuritava tunnuse väärtuseid populatsioonis kuigi hästi.

Puudused:

  • eeldused lineaarsuse, jaotuste, vaatluste sõltumatuse jms kohta,
  • interaktsioonide lisamisel tulemusi raskem interpreteerida,
  • tundlikud erindite suhtes,
  • tundlikud puuduvate väärtuste suhtes,
  • võivad ülesobitada, tulemusi peaks valideerima.




Otsustuspuud on mitteparameetriliste algoritmide klass. Mitteparameetrilised mudelid ei sobita andmetele kindlat funktsiooni, vaid jõuavad sobiva funktsioonini andmete enda kaudu. Mitteparameetrilised mudelid on seega paindlikumad ning suudavad paremini arvestada korraga erinevate tunnuste mõjuga erinevates tingimustes. Seepärast sobivad need paremini kirjeldama komplekssemaid uurimisküsimusi, mille puhul praktikas ei pruugi nt lihtne lineaarne ennustusmudel hästi töötada. Mitteparameetrilised mudelid õpivad andmetest, seega mida rohkem on vaatlusandmeid, seda tugevam on mitteparameetrilise mudeli ennustusvõime.

Otsustuspuud

  • ei eelda andmetelt mingeid jaotusi;
  • saavad hakkama ebaühtlase andmete jaotumisega;
  • sobivad hästi, kui on palju seletavaid tunnuseid, nendevahelisi interaktsioone ja korrelatsioone;
  • tulemused on intuitiivselt tõlgendatavad;
  • sobivad nii kategoriaalsetele (kahe või enama tasemega) kui ka arvulistele uuritavatele tunnustele;
  • masinõppemeetod: jõuavad ise optimaalse mudelini (ebaolulised tunnused jäävad väljundist välja).

Otsustuspuud

Otsustuspuu (decision tree) algoritm põhineb vaatluste binaarsel rekursiivsel ositamisel (binary recursive partitioning). See tähendab, et

  • kõikidest seletavatest tunnustest valitakse see, mis kõige selgemini uuritava tunnuse varieerumist seletab, ja jagatakse esimeses sõlmes (root node ehk nn juursõlm) vaatlused selle põhjalt kaheks (tunnuse põhjal sarnased vaatlused grupeeritakse);
  • seejärel valitakse kummaski tekkinud grupis/sõlmes omakorda tunnused, mis seal kõige selgemini uuritava tunnuse varieerumist seletavad, ja jagatakse vaatlused veel kord kaheks. Selline binaarne jagamine annab puu “oksad”;
  • samasugune rekursiivne ehk enesest lähtuv ositamine gruppides jätkub, kuni ükski tunnus ei ole enam uuritava tunnuse seletamisel oluline. “Rekursiivne” tähendabki siin seda, et ühe grupi sisse moodustub üha uusi, spetsiifilisemaid gruppe;
  • ositamise lõpptulemusena saadakse optimaalsed klassid või jaotused, mis ennustavad uuritava tunnuse väärtusi vastavalt eelmistele jagunemistele. Need on puu “lehed” (terminal/leaf node). Puu lehtedes on niisiis andmestiku tegelikud vaatlused/read, milles uuritava tunnuse tegelikud väärtused võivad varieeruda, ent lehe klassiks ennustatakse kategoriaalse uuritava tunnuse puhul kõige sagedamat/tõenäolisemat uuritava tunnuse väärtust selles vaatluste grupis ning arvulise uuritava tunnuse puhul tunnuse keskväärtust. Lehtede põhjal on nõnda võimalik ennustada uuritava tunnuse klasse ka teiste valimite jaoks.

Otsustuspuu tööpõhimõtet ja ka nimetust motiveerib niisiis kujutlus puu kasvatamisest altpoolt ülespoole.

Rekursiooni olemust näitlikustatakse sageli Sierpinski kolmnurga kaudu, kus üht kolmnurka saab jagada lõputult väiksemateks kolmnurkadeks. Sierpinski kolmnurk: http://eldar.mathstat.uoguelph.ca/dashlock/ftax/Gallery/Siepinski1D960.gif.

CART

Otsustuspuude algoritmides on üht-teist erinevat, nt selles osas, mida kasutatakse vaatluste jagamise kriteerumina.
Tuntuim algoritm on ilmselt CART (Classification and Regression Tree). CART-mudelid jagunevad

  • regressioonipuudeks (regression tree)
    • uuritav tunnus on arvuline;
    • jagunemise aluseks olevad seletavad tunnused ja konkreetsed jagunemiskohad valitakse nn minimaalse ruutvigade summa järgi sum(y-f)2, kus y on uuritava tunnuse tegelik väärtus mingil andmestiku real ja f selle ennustatud väärtus;
  • klassifitseerimispuudeks (classification tree)
    • uuritav tunnus on kategoriaalne;
    • jagunemiste määramiseks minimeeritakse nn Gini indeksit, mis näitab kui “puhas” mingi leht on ehk kui erinevad tegelikud väärtused mingi ühe ennustatud klassi alla grupeeritakse. Jagunemiste määramise aluseks on valem sum(pk * (1-pk)), kus k on uuritava tunnuse üks mingi ennustatav tase/klass ning pk nende tegelike vaatluste osakaal, mis on klassist k ning on mingis puu lehes ka määratud klassi k.

Regressioonipuu Klassifitseerimispuu

Vt https://www.statmethods.net/advstats/cart.html.

Probleeme klassikaliste otsustuspuu algoritmidega:

  • Võivad kergesti ülesobitada ja jaguneda nii kaua, kuni puu vastab igale andmestiku nüansile. See tähendab aga ka, et need mudelid pole enam hästi üldistatavad mõne teise valimi jaoks. Selle vältimiseks peaks puid “trimmima” (ingl pruning).
    • Eeltrimmimise puhul tuleb enne puu kasvatamist teha mõned otsused, nt otsustada, et on mingi kindel arv lehti, mis puul võib lõpuks olla, või et igas lehes peab olema kindel hulk vaatlusi. Samuti võib otsustada, et lõpetame puu kasvatamise, kui mingi tingimus on saavutatud, nt kui kõik vaatlused igas lehes on samast klassist.
    • Järeltrimmimise puhul vaadatakse, kas mingid alamjagunemised puus annavad kokkuvõttes paremaid tulemusi, kui see, kui asendada need lihtsalt lehega, kus on arvulise uuritava tunnuse puhul tunnuse keskväärtus või kategoriaalse uuritava tunnuse puhul selle sagedasem tase/klass.
  • Kalduvad sõlmedes eelistama tunnuseid, mis viiksid võimalikult suure puuni, st arvulisi tunnuseid ja selliseid kategoriaalseid tunnuseid, millel on rohkem tasemeid, sest need annavad justkui rohkem infot.

Tingimuslik otsustuspuu

Meie vaatame lähemalt natuke uuemat tingimusliku otsustuspuu algoritmi (conditional inference tree), mis kasutab sõlmedes ositamise alusena p-väärtusi (mitte nt mõnd informatsioonikriteeriumit, nagu Gini-indeks). Seletavate tunnuste valik ei ole kallutatud ja puud ei ole ülesobitamise hirmus vaja trimmida. Edaspidi viitame otsustuspuu nimetusega just tingimuslikule otsustuspuule.

R-is on puumudelite tegemiseks erinevate algoritmidega paketid rpart, tree, maptree, party, partykit jt.

Kasutame siin paketti partykit ja selle funktsiooni ctree() (loe dokumentatsiooni siit või siit). partykit on paketi party edasiarendus koos lisavõimalustega visualiseerimiseks.

# Installi ja laadi pakett

# install.packages("partykit")
library(partykit)

Näide 1: kategoriaalne uuritav tunnus

Võtame sama andmestiku isik1suur.RData, millel tegime logistilise regressiooni mudelit ning mudeldame nüüd andmestikku otsustuspuude kaudu.

load("isik1suur.RData")

# library(partykit)

isik1suur$Sone <- gsub("['#()\\*\\.`]", "", isik1suur$Sone)
isik1suur$Sonepikkus <- nchar(isik1suur$Sone) 

# Teeme puumudeli
puu1 <- ctree(Pron ~ Lopp + Aeg + Sonepikkus + Ref_kaugus_num + Verbiklass + Murre, data = isik1suur)

# Visualiseerime mudelit
plot(puu1)

Võime lihtsama tõlgendamise eesmärgil siin puud siiski veidi trimmida. Sellega vähendame mudeli täpsust, aga ka ülesobitamise võimalust. Lisame funktsiooni argumendi minbucket = 200, millega ütleme, et igas lehes peab olema vähemalt 200 vaatlust. Ütleme ka argumendiga alpha = 0.01, et 1. tüüpi vea tegemise võimalus sõlmedes (tunnuse alusel jagatakse andmeid edasi, ehkki tegelikult on seletava ja uuritava tunnuse vaheline seos juhuslik) võiks olla ainult 1%, ehk olulisusnivoo α = 0,05 asemel kasutame nivood α = 0,01.

puu2 <- ctree(Pron ~ Lopp + Aeg + Sonepikkus + Ref_kaugus_num + Verbiklass + Murre, data = isik1suur, control = ctree_control(minbucket = 200, alpha = 0.01))
plot(puu2)

  • Näeme, et kõige esimese jagunemise jaoks valitakse tunnus Lopp, mis jagab vaatlused kahte klassi selle põhjal, kas tegusõnal on pöördelõpp (“jah”) või mitte (“ei”). Enamasti on esimese jagunemise jaoks valitud tunnus üks uuritava tunnusega kõige tugevamalt seotud tunnustest, samas mitte tingimata ise see ainuke kõige tugevamini seotud tunnus.
  • Järgmise jagunemise jaoks on grupis “ei” valitud tunnus Murre (idamurre ja saarte murre eristuvad kesk-, ranna- ja Võru murdest) ning grupis “jah” tunnus Ref_kaugus_num (eristuvad vaatlused, millest eelmine viide 1. isikule on kuni 8 sõna kaugusel (k.a.), ja vaatlused, millest eelmine viide 1. isikule on enam kui 8 sõna kaugusel). Viimases grupis enam rohkem jagunemisi ei ole ning vaatlustele, mille puhul tegusõnal on pöördelõpp ning eelmine viide 1. isikule on enam kui 8 sõna kaugusel (Node 23), ennustatakse asesõna esinemise tõenäosuseks ~0.6 ja mitte-esinemise tõenäosuseks ~0.4. Siia vaatluste gruppi kuulub 652 vaatlust (n = 652). Kuna asesõna esinemise tõenäosus on suurem kui mitte-esinemise tõenäosus, on nendele vaatlustele ennustatud Pron klass “jah”.
  • Teistes gruppides jätkub jagunemine nii kaua, kuni edaspidine vaatluste ositamine ei anna enam statistiliselt teineteisest oluliselt erinevaid rühmi.
  • Kõige all ongi esitatud puu “lehed”, mis vaikimisi kuvavad uuritava tunnuse klasside/tasemete esinemise tõenäosused.

Kokku on puul 23 sõlme (lehed kaasa arvatud). Nende info on mudelis listide kujul.

# Kõik 23 jagunemist
str(puu2, max.level = 1)
## List of 23
##  $ 1 :Classes 'constparty', 'party'  hidden list of 6
##  $ 2 :Classes 'constparty', 'party'  hidden list of 6
##  $ 3 :Classes 'constparty', 'party'  hidden list of 6
##  $ 4 :Classes 'constparty', 'party'  hidden list of 6
##  $ 5 :Classes 'constparty', 'party'  hidden list of 6
##  $ 6 :Classes 'constparty', 'party'  hidden list of 6
##  $ 7 :Classes 'constparty', 'party'  hidden list of 6
##  $ 8 :Classes 'constparty', 'party'  hidden list of 6
##  $ 9 :Classes 'constparty', 'party'  hidden list of 6
##  $ 10:Classes 'constparty', 'party'  hidden list of 6
##  $ 11:Classes 'constparty', 'party'  hidden list of 6
##  $ 12:Classes 'constparty', 'party'  hidden list of 6
##  $ 13:Classes 'constparty', 'party'  hidden list of 6
##  $ 14:Classes 'constparty', 'party'  hidden list of 6
##  $ 15:Classes 'constparty', 'party'  hidden list of 6
##  $ 16:Classes 'constparty', 'party'  hidden list of 6
##  $ 17:Classes 'constparty', 'party'  hidden list of 6
##  $ 18:Classes 'constparty', 'party'  hidden list of 6
##  $ 19:Classes 'constparty', 'party'  hidden list of 6
##  $ 20:Classes 'constparty', 'party'  hidden list of 6
##  $ 21:Classes 'constparty', 'party'  hidden list of 6
##  $ 22:Classes 'constparty', 'party'  hidden list of 6
##  $ 23:Classes 'constparty', 'party'  hidden list of 6
##  - attr(*, "class")= chr [1:2] "constparty" "party"

# 1. sõlme info: Lopp = "ei" ja Lopp = "jah"
puu2[[1]]
## 
## Model formula:
## Pron ~ Lopp + Aeg + Sonepikkus + Ref_kaugus_num + Verbiklass + 
##     Murre
## 
## Fitted party:
## [1] root
## |   [2] Lopp in ei
## |   |   [3] Murre in IDA, SAARTE
## |   |   |   [4] Sonepikkus <= 4
## |   |   |   |   [5] Aeg in ipf: jah (n = 268, err = 21.6%)
## |   |   |   |   [6] Aeg in pr: jah (n = 244, err = 8.6%)
## |   |   |   [7] Sonepikkus > 4: jah (n = 379, err = 29.8%)
## |   |   [8] Murre in KESK, RANNA, VORU
## |   |   |   [9] Aeg in ipf
## |   |   |   |   [10] Ref_kaugus_num <= 4: ei (n = 257, err = 43.2%)
## |   |   |   |   [11] Ref_kaugus_num > 4: jah (n = 253, err = 46.2%)
## |   |   |   [12] Aeg in pr: jah (n = 226, err = 30.1%)
## |   [13] Lopp in jah
## |   |   [14] Ref_kaugus_num <= 8
## |   |   |   [15] Verbiklass in kognitiivne, kommunikatiivne: jah (n = 220, err = 40.5%)
## |   |   |   [16] Verbiklass in muu
## |   |   |   |   [17] Sonepikkus <= 4
## |   |   |   |   |   [18] Aeg in ipf: ei (n = 302, err = 40.1%)
## |   |   |   |   |   [19] Aeg in pr: jah (n = 272, err = 46.0%)
## |   |   |   |   [20] Sonepikkus > 4
## |   |   |   |   |   [21] Murre in IDA, SAARTE, VORU: ei (n = 376, err = 34.6%)
## |   |   |   |   |   [22] Murre in KESK, RANNA: ei (n = 617, err = 24.1%)
## |   |   [23] Ref_kaugus_num > 8: jah (n = 652, err = 40.0%)
## 
## Number of inner nodes:    11
## Number of terminal nodes: 12

# 5. sõlme info: vasakult 1. lõpuleht
puu2[[5]]
## 
## Model formula:
## Pron ~ Lopp + Aeg + Sonepikkus + Ref_kaugus_num + Verbiklass + 
##     Murre
## 
## Fitted party:
## [5] root: jah (n = 268, err = 21.6%) 
## 
## Number of inner nodes:    0
## Number of terminal nodes: 1

Iga sõlme/jagunemise kohta näeme niisiis selle numbrit, edasisi jagunemisi (kui on), lõpusõlmedesse/lehtedesse ennustatud klasse (vastavalt sellele, milline uuritava tunnuse tase esineb kõige suurema tõenäosusega), vaatluste arvu lõpusõlmedes/klassides (n) ning ennustatud klassi veaprotsenti (err) ehk nende vaatluste osakaalu, mis jäävad vähemusse. Ehk kui nt 18. sõlme (lõpulehe) ennustatud klass on “ei” ning err = 40.1%, on järelikult sellesse lehte jagatud vaatluste hulgas “jah” osakaal 0.401 ja “ei” osakaal seega 0.599.

Kui vaatame nüüd uuesti üldpilti, siis näeme, et pöördelõputa tegusõnade hulgas (Lopp = "ei") on asesõna esinemise tõenäosus keskmiselt suurem kui pöördelõpuga tegusõnade hulgas (Lopp = "jah"), ent asesõna esinemist mõjutavad kummaski rühmas veel mitmed muud tegurid, mis esinemise tõenäosust tõstavad või langetavad.

Vaatame lähemalt näiteks 1) konteksti, kus asesõna esinemise tõenäosus on kõige suurem (Node 6), ning 2) konteksti, kus see on kõige väiksem (Node 22).

1) Asesõna esinemise tõenäosus on kõige suurem (üle 0.9) kontekstis, kus

  • tegusõnal puudub pöördelõpp,
  • informant on kas idamurde või saarte murde kõneleja,
  • tegusõna pikkus on kuni 4 tähemärki,
  • tegusõna on olevikus.
puu2[[6]]
## 
## Model formula:
## Pron ~ Lopp + Aeg + Sonepikkus + Ref_kaugus_num + Verbiklass + 
##     Murre
## 
## Fitted party:
## [6] root: jah (n = 244, err = 8.6%) 
## 
## Number of inner nodes:    0
## Number of terminal nodes: 1

Vaatame, kas andmestikus nendele tunnustele vastavate vaatluste arv klapib.

nrow(isik1suur[isik1suur$Lopp == "ei" & 
                 (isik1suur$Murre == "IDA" | isik1suur$Murre == "SAARTE") &
                 isik1suur$Sonepikkus <= 4 & 
                 isik1suur$Aeg == "pr",])
## [1] 244

2) Asesõna esinemise tõenäosus on kõige väiksem (veidi üle 0.2) kontekstis, kus

  • tegusõnal puudub pöördelõpp,
  • eelmine viide 1. isikule on kuni 8 sõna kaugusel,
  • tegusõna semantiline klass ei ole “kognitiivne” ega “kommunikatiivne”,
  • tegusõna pikkus on rohkem kui 4 tähemärki,
  • informant on kesk- või rannamurde kõneleja (seda on jooniselt natuke halvemini näha).
puu2[[22]]
## 
## Model formula:
## Pron ~ Lopp + Aeg + Sonepikkus + Ref_kaugus_num + Verbiklass + 
##     Murre
## 
## Fitted party:
## [22] root: ei (n = 617, err = 24.1%) 
## 
## Number of inner nodes:    0
## Number of terminal nodes: 1

Vaatame, kas andmestikus nendele tunnustele vastavate vaatluste arv klapib.

nrow(isik1suur[isik1suur$Lopp == "jah" & 
                 isik1suur$Ref_kaugus_num <= 8 &
                 isik1suur$Verbiklass == "muu" & 
                 isik1suur$Sonepikkus > 4 &
                 (isik1suur$Murre == "KESK" | isik1suur$Murre == "RANNA"),])
## [1] 617

Igas sõlmes võistleb jagunemise tekitamiseks omavahel mitu seletavat tunnust, mille hulgast valitakse p-väärtuse alusel ainult 1. Seda, mis tunnused veel sõlmedes kandideerisid, saab vaadata käsuga sctest.constparty().

# Kõikide sõlmede jagunemised
# sctest.constparty(puu2)

# 1. sõlme jagunemine
sctest.constparty(puu2)[1]
## $`1`
##                   Lopp          Aeg   Sonepikkus Ref_kaugus_num   Verbiklass
## statistic 2.263574e+02 6.638670e+01 1.601136e+02   7.563515e+01 1.606800e+02
## p.value   2.227934e-50 2.223562e-15 6.411838e-36   2.047399e-17 7.707956e-35
##                  Murre
## statistic 1.705855e+02
## p.value   4.698528e-35

Selline info võib olla informatiivne siis, kui sõlme valitud seletav tunnus oli ainult õige natuke parem kui mõni teine tunnus, mida jagunemiseks ei valitud. Esimese sõlme jagunemises näeme, et kõik tunnused on uuritava tunnusega statistiliselt oluliselt seotud, ent pöördelõpu p-väärtus oli mitu korda väiksem kui teiste tunnuste p-väärtused, seega valiti see esimese jagunemise aluseks. Mida allapoole puus aga liigume, seda väiksemaks jääb jagunemiseks sobivate tunnuste valik.
Seda, mis statistikut tunnustevahelise seose hindamiseks kasutatakse, sõltub sellest, mis tüüpi (arvuline/kategoriaalne) on seletav tunnus ja mis tüüpi on uuritav tunnus. Loe soovi korral rohkem nt siit.

Oluliste seoste puudumine

Vaatame veel, mis saab siis, kui ühelgi seletaval tunnusel ei ole uuritava tunnuse seletamisel olulist rolli.

load("kysimustik_2020.RData")

puu3 <- ctree(lemmikloom ~ ., data = kysimustik)
plot(puu3)

Sel juhul saame lihtsalt uuritava tunnuse klasside esinemise tõenäosused nende andmestikus esinemise suhteliste sageduste järgi.

Näide 2: arvuline uuritav tunnus

Ehkki otsustuspuude kasutamine on tavalisem klassifitseerimisprobleemide puhul, saab seda edukalt kasutada ka regressiooniülesannetes, st mingi arvulise uuritava tunnuse keskväärtuse ennustamise jaoks.

Uurime näiteks puumudelitega uuesti kõigepealt seda, kas sõna äratundmiseks kuluv aeg sõltub sõna pikkusest ja sagedusest.

Reaktsiooniaeg

# library(partykit)
ldt <- read.csv("ldt.csv")
puu4 <- ctree(Mean_RT ~ Length + Freq, data = ldt)
plot(puu4)

Regressioonipuu visuaalne väljund (vaikimisi karpdiagramm) annab iga lõpliku sõlme kohta uuritava tunnuse ennustatud kvartiiljaotuse selles sõlmes.

Näeme, et reaktsiooniaega mõjutab eeskätt sõna pikkus: kui sõna on pikem kui 10 tähemärki, siis on reaktsiooniaeg pikem kui siis, kui sõna pikkus on kuni 10 tähemärki. Lühemate sõnade puhul jällegi tekib erinevus lühikeste (<= 7 tm) ja keskmise pikkusega (>7 tm) sõnade vahel. Nendes gruppides omakorda hakkab rolli mängima sõna sagedus: mõlemal juhul on sagedamate sõnade äratundmiseks kuluv aeg lühem.

Mudelist saame kätte ka iga vaatluste grupi ennustatud keskväärtuse.

str(puu4, max.level = 1)
## List of 9
##  $ 1:Classes 'constparty', 'party'  hidden list of 6
##  $ 2:Classes 'constparty', 'party'  hidden list of 6
##  $ 3:Classes 'constparty', 'party'  hidden list of 6
##  $ 4:Classes 'constparty', 'party'  hidden list of 6
##  $ 5:Classes 'constparty', 'party'  hidden list of 6
##  $ 6:Classes 'constparty', 'party'  hidden list of 6
##  $ 7:Classes 'constparty', 'party'  hidden list of 6
##  $ 8:Classes 'constparty', 'party'  hidden list of 6
##  $ 9:Classes 'constparty', 'party'  hidden list of 6
##  - attr(*, "class")= chr [1:2] "constparty" "party"

# 9. sõlme info
puu4[[9]]
## 
## Model formula:
## Mean_RT ~ Length + Freq
## 
## Fitted party:
## [9] root: 989.824 (n = 18, err = 665437.8) 
## 
## Number of inner nodes:    0
## Number of terminal nodes: 1

Arvuliste uuritavate tunnustega näitab iga lehe n endiselt sellesse rühma kuuluvate vaatluste arvu, ent err sedapuhku jääkide ruutude summat, mis mäletatavasti oli seotud üksikute vaatluste erinevusega grupi keskmisest.

# 10 tähemärgist pikemate sõnade reaktsiooniajad
(pikad_RT <- ldt[ldt$Length > 10,]$Mean_RT)
##  [1] 1125.42  948.33  816.94  931.13 1054.77  931.04  620.79  978.81  942.86
## [10] 1314.33  768.41  915.96 1089.00  904.47 1216.81  923.74  875.27 1458.75

# 10 tähemärgist pikemate sõnade keskmine reaktsiooniaeg
(kesk <- mean(pikad_RT))
## [1] 989.8239

# Jääkide ruutude summa
sum((pikad_RT-kesk)^2)
## [1] 665437.8

Mida suurem on jääkide ruutude summa, seda erinevamad vaatlused sellesse lehte kuuluvad. Näiteks joonise järgi peaks olema sõlmes 8 jääkide ruutude summa väiksem, kuna karpdiagrammi kuju viitab sellele, et vaatlused on koondunud tihedamalt keskväärtuse ümber.

puu4[[8]]
## 
## Model formula:
## Mean_RT ~ Length + Freq
## 
## Fitted party:
## [8] root: 746.839 (n = 16, err = 61399.5) 
## 
## Number of inner nodes:    0
## Number of terminal nodes: 1

Häältesaak

Vaatame nüüd uuesti ka 2019. a valimiste andmeid.

load("kandidaadid.RData")
puu5 <- ctree(haali_kokku ~ sugu + haridus + sodiaak, data = kandidaadid, subset = haridus != "Algharidus")
plot(puu5)

Kuna häältesaak on tugevalt madalamate väärtuste poole kaldu, siis on parem ka puumudelis kasutada logaritmitud uuritavat tunnust, et vähendada erandlikult palju hääli saanud kandidaatide mõju.

puu6 <- ctree(log(haali_kokku) ~ sugu + haridus + sodiaak, data = kandidaadid, subset = haridus != "Algharidus")
plot(puu6)

Näeme, et kõrgharidusega kandidaatide seas statistiliselt olulist erinevust mees- ja naiskandidaatide häältesaagis ei olnud, aga kesk- ja põhiharidusega kandidaatide seas said naised keskmiselt pisut vähem hääli. Näeme siiski ka, et see erinevus ei ole väga suur. Kandidaadi tähtkuju häältesaagi puhul mingit rolli ei mängi.

puu6
## 
## Model formula:
## log(haali_kokku) ~ sugu + haridus + sodiaak
## 
## Fitted party:
## [1] root
## |   [2] haridus in Keskharidus (sh keskeriharidus), Põhiharidus
## |   |   [3] sugu in mees: 4.507 (n = 203, err = 487.2)
## |   |   [4] sugu in naine: 3.777 (n = 76, err = 152.4)
## |   [5] haridus in Kõrgharidus: 5.246 (n = 819, err = 1845.1)
## 
## Number of inner nodes:    2
## Number of terminal nodes: 3

Teeme mõned seletavad tunnused juurde ja proovime neid ka mudelisse panna.

# Kas kandidaat kasutab meili?
kandidaadid$kasutab_meili <- as.factor(ifelse(grepl("@", kandidaadid$kontaktandmed), "jah", "ei"))

# Kui pikk on kandidaadi nimi
kandidaadid$nime_pikkus <- nchar(kandidaadid$nimi)

# Kui vana kandidaat on?
kandidaadid$vanus <- 2019 -as.numeric(substr(kandidaadid$sunniaeg, 1,4))

puu7 <- ctree(log(haali_kokku) ~ sugu + haridus + sodiaak + kasutab_meili + nime_pikkus + vanus, data = kandidaadid, subset = haridus != "Algharidus")
plot(puu7)

Ühelgi lisatud tunnusel ei ole kandidaadi saadud häälesaagiga olulist seost.

Visualiseerimine

Pakett partykit pakub rida võimalusi otsustuspuude visualiseerimiseks. Vaatame neist mõningaid. Põhilised elemendid, mida graafikul saame modifitseerida, on

  • inner_panel: puu sõlmed, kust jagatakse vaatlused mingi tunnuse alusel kaheks;
  • terminal_panel: puu lehed ehk mudeli lõpusõlmed, kus on klassid, tõenäosused jms.

Neid elemente saavad omakorda muuta erinevad node-funktsioonid, nt

  • node_inner(): üldine sisemiste sõlmede modifitseerimise funktsioon
  • node_terminal(): üldine lõpusõlmede modifitseerimise funktsioon
  • node_barplot(): tulpdiagrammesitus kategoriaalse uuritava tunnuse klassidele
  • node_boxplot(): karpdiagrammesitus arvulisele uuritavale tunnusele
  • jne (vt lähemalt siit)
# Teeme visualiseerimise näitlikustamiseks 
# ühe veidi rohkem trimmitud puu, kus 
# alpha = 0.01 ja 
# minimaalne vaatluste arv klassides on 500.
puu8 <- ctree(Pron ~ Lopp + Aeg + Sonepikkus + Ref_kaugus_num + Verbiklass + Murre, 
              data = isik1suur, 
              control = ctree_control(alpha = 0.01, 
                                      minbucket = 500))

plot(puu8)

# Kuva puu lehed ilma tulpdiagrammita
# Tee tekst graafikul väiksemaks ja helehalliks
# Kuva sisemised sõlmed ilma numbri ja p-väärtuseta
plot(puu8, 
     type = "simple", 
     gp = gpar(fontsize = 9, 
               col = "darkslategrey"), 
     inner_panel = node_inner(obj = puu8, 
                              id = FALSE, 
                              pval = FALSE))



# Tee tekst graafikul väiksemaks ja helehalliks
# Kuva sisemised sõlmed ilma numbri ja p-väärtuseta
# Kuva lõpulehed tulpdiagrammina, kus
# tulbad on üksteise kõrval ja vastupidises järjekorras
# ning värvitud oranžiks ja halliks.
plot(puu8, 
     gp = gpar(fontsize = 8, 
               col = "darkslategrey"), 
     inner_panel = node_inner(obj = puu8, 
                              id = FALSE, 
                              pval = FALSE), 
     terminal_panel = node_barplot(obj = puu8, 
                                   beside = TRUE, 
                                   reverse = TRUE, 
                                   fill = c("orange2", 
                                            "grey35")))

Lisaks partykit-paketi enda võimalustele on üsna värskelt välja tulnud ka pakett ggparty, mis on tehtud ggplot2 laiendusena partykit paketi objektide visualiseerimiseks. Kui rohkem huvi, tasub selle kohta uurida nt siit.

Kordamisküsimused

1. Millised alljärgnevatest tunnusetüüpidest saavad olla otsustuspuu uuritavaks tunnuseks?

  1. Arvuline tunnus
  2. Kahe tasemega kategoriaalne tunnus
  3. Enam kui kahe tasemega kategoriaalne tunnus

2. Milline väide on õige?

  1. Mida erinevamaid väärtusi puu lehtedesse ennustatakse, seda parem otsustuspuu mudel.
  2. Puu trimmimine teeb mudeli konkreetsetele andmetele sobivamaks.
  3. Arvulise uuritava tunnuse puhul ennustatakse puu lehtedes uuritava tunnuse keskväärtust.
  4. Kategoriaalse uuritava tunnuse puhul ennustatakse puu lehtedes tunnuse sagedaimat/tõenäolisemat klassi.



Terviseamet on oma kodulehel avaldanud koroonaviiruse testide avaandmed. Andmestik sisaldab anonüümitud testide tulemusi ja natuke testitava demograafilist infot.

Andmestiku saad kätte siit lingilt, ent kuna andmed muutuvad iga päev, siis testi kontrollitavuse huvides kasutame andmestikku seisuga 07.04.2020.

Loeme andmestiku R-i.

dat <- read.csv("opendata_covid19_test_results_0704.csv", encoding = "UTF-8", na.strings = "")

summary(dat)
##                                                                 id       
##  00033ef8ddfeaed79696a7b2a93102e8ba9cf745e2e8d152b9e01601e28eee7a:    1  
##  000e3be6434c70b858d1496ed473828992f1f65a6fe393a8521f0f510fc19f32:    1  
##  000e5223e2c1051dbd189c67f3aee0f672cb4d71894a1b88bf97252e944713b5:    1  
##  0010f825d67b07df9ff74ca4dc9f548d645fc2df943bff95209c528d572fbddc:    1  
##  0012b2e30fef7d69bbd953d88b174611c0bdc461d27da1e8278f98b5ead0425c:    1  
##  0014794c504ec70da3c6be4fe0f50297b303fda50aad0110554dec5a9a9e3bdf:    1  
##  (Other)                                                         :21860  
##  Gender       AgeGroup         Country                   County     ResultValue
##  M: 7864   45-49  : 2028   Eesti   :21584   Harju maakond   :9615   N:20758    
##  N:14002   55-59  : 1856   Tundmatu:  175   Saare maakond   :2366   P: 1108    
##            30-34  : 1819   Välismaa:  107   Tartu maakond   :1785              
##            35-39  : 1790                    Ida-Viru maakond:1668              
##            40-44  : 1780                    Pärnu maakond   :1458              
##            (Other):12518                    (Other)         :4690              
##            NA's   :   75                    NA's            : 284              
##     StatisticsDate                ResultTime              AnalysisInsertTime
##  2020-04-02: 2508   2020-03-18 00:00:00:  265   2020-03-21 20:31:13:    4   
##  2020-03-31: 1977   2020-03-15 00:00:00:  227   2020-03-21 20:37:24:    4   
##  2020-04-03: 1534   2020-03-20 00:00:00:  198   2020-03-21 20:37:40:    4   
##  2020-03-24: 1403   2020-04-03 00:00:00:  176   2020-03-21 23:03:46:    4   
##  2020-04-01: 1374   2020-03-19 00:00:00:  167   2020-03-21 23:03:48:    4   
##  2020-03-27: 1253   2020-03-13 00:00:00:  166   2020-03-21 20:30:29:    3   
##  (Other)   :11817   (Other)            :20667   (Other)            :21843

# Jätame välja vaatlused, mille kohta ei ole täielikku infot
dat <- droplevels(dat[complete.cases(dat),])

# Lühendame maakonna nimesid
dat$County_abbr <- factor(substr(dat$County, 1, 3))

Tee andmete põhjal puumudel, milles seletad testi tulemust (ResultValue: P (positive) või N (negative)) selle järgi, mis soost (Gender), millisest vanusegrupist (AgeGroup) ja millisest maakonnast (County_abbr) on testitav. Sea olulisusnivooks alpha = 0.01.

3. Millise tunnuse valib mudel esimese jagunemise jaoks?

  1. Gender
  2. AgeGroup
  3. County_abbr
  4. Ei vali ühtegi, sest mudelis ei ole statistiliselt olulisi seletavaid tunnuseid.

4. Kuidas mõjutab mudeli järgi testitava sugu testi tulemust?

  1. Sool ei ole mingit mõju.
  2. Mees saab tõenäolisemalt positiivse testi kui naine.
  3. Naine saab tõenäolisemalt positiivse testi kui mees.
  4. Mees saab tõenäolisemalt positiivse testi kui naine, juhul kui ta on Saaremaalt.
  5. Naine saab tõenäolisemalt positiivse testi kui mees, juhul kui ta on Saaremaalt.
  6. Mees saab tõenäolisemalt positiivse testi kui naine, juhul kui ta ei ole Saaremaalt.
  7. Naine saab tõenäolisemalt positiivse testi kui mees, juhul kui ta ei ole Saaremaalt.

5. Millises demograafilises grupis on haigestumise tõenäosus kõige suurem?

  1. Harjumaa inimesed vanuses 35-49 ja 75-85+
  2. Saaremaa inimesed vanuses 55-59 ja 70-85+
  3. Võrumaa mehed vanuses 75-79 ja 85+
  4. Saaremaa ja Võrumaa naised vanuses 65-85+

Järgmisel korral

  • Otsustuspuude headuse näitajad
  • Juhumetsad (random forests)