Andmestikud endiselt:
ldt.csv
kandidaadid2019.RData
fonkorp2
(loeme otse DataDOIst, ei pea alla
laadima)Loeme sisse ldt.csv
andmestiku, kust eelmisel korral
vaatasime reaktsiooniaja seost sõna pikkusega. See mäletatavasti oli
statistiliselt oluline seos, mis kirjeldas umbes 35% reaktsiooniaja
varieerumisest.
ldt <- read.csv("data/ldt.csv")
# Jätame alles ainult read, kus Mean_RT < 1200 ms
ldt2 <- ldt[ldt$Mean_RT < 1200,]
Nüüd proovime, kas mudel läheb paremaks, kui me lisame sinna seletavaid tunnuseid. Üks sõnade äratundmiseks kuluvat reaktsiooniaega mõjutav tunnus võiks lisaks sõna pikkusele olla sõna sagedus: võiks oletada, sagedasemaid sõnu tunneme me ära kiiremini kui vähemsagedasi.
Enne mudelisse lisamist vaatame selle faktori jaotust.
Sagedus on tugevalt paremale kaldu, seda on juba histogrammilt näha. Proovime logaritmida.
Kuna siin on 0-sagedusega sõnu ja logaritm nullist on miinus lõpmatus,
## [1] -Inf
siis siin saab kasutada käsku log1p()
, mis liidab
algsele väärtusele ühe ja siis logaritmib, vältides nii -Inf (ehk miinus
lõpmatus) väärtuseid.
## [1] 0.0000000 0.6931472 1.0986123
## [1] 0.0000000 0.6931472 1.0986123
Testime normaaljaotust logaritmitud väärtustega:
##
## Shapiro-Wilk normality test
##
## data: log1p(ldt2$Freq)
## W = 0.9794, p-value = 0.1313
Logaritmimine aitas, nüüd on tunnus normaalajotusega.
Läheme edasi mudeliga. Mudelis lisatakse sõltumatud tunnused +-märgiga. Kui enne ühe seletava tunnusega mudeli valem oli y ~ x, siis nüüd on see y ~ x1 + x2.
##
## Call:
## lm(formula = Mean_RT ~ Length + log1p(Freq), data = ldt2)
##
## Residuals:
## Min 1Q Median 3Q Max
## -219.823 -58.871 -2.198 44.140 243.543
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 762.232 50.251 15.168 < 2e-16 ***
## Length 18.895 4.265 4.430 2.54e-05 ***
## log1p(Freq) -21.348 3.894 -5.483 3.51e-07 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 87.47 on 94 degrees of freedom
## Multiple R-squared: 0.5048, Adjusted R-squared: 0.4943
## F-statistic: 47.91 on 2 and 94 DF, p-value: 4.509e-15
Vaatame nüüd koefitsientide tabelit (Coefficients).
Me võime mudelit testida, arvutades välja prognoosi seletavate tunnuste keskmiste väärtuste korral ning võrrelda seda reaalse andmestiku keskmisega. Tegelikud keskmised väärtused on:
## Length Freq Mean_RT
## 8.092784 3452.103093 792.117938
paneme need valemisse
RT = 762 + 19 * pikkus - 21 *
log1p(sagedus)
## [1] 741.1698
Mudeli prognoose võime muidugi ka otse mudelist lugeda ja valemites
rakendada. Vaatame lm()
käsuga saadud objekti, et saada
natuke aimu, mis struktuuriga objekt see on:
Käsk str()
aitab ehk kõige paremini lm objekti lahti
muukida: tegemist on listilaadse objektiga, kus element “coefficients”
on vektor mudeli prognooside väärtustega. Kasutame nüüd neid
koefitsentide väärtusi, et arvutada mudeliprognoose. Nii saame arvutada,
mis võiks olla reaktsiooniaeg keskmise pikkusega keskmise sagedusega
sõna korral:
ldt2.mod1$coefficients["(Intercept)"] +
mean(ldt2$Length) * ldt2.mod1$coefficients["Length"] +
log1p(mean(ldt2$Freq)) * ldt2.mod1$coefficients["log1p(Freq)"]
## (Intercept)
## 741.2168
Joonistame mudeli põhjal regressioonijooned nii, et teise tunnuse väärtus oleks keskmine, mitte 0.
par(mfcol = c(1,2)) # Kuva järgmised joonised ühes reas, kahes tulbas
plot(Mean_RT ~ Length, data = ldt2,
xlab = "Sõna pikkus", ylab = "Keskmine reaktsioonikiirus",
main = "Sõna pikkuse mõju\nkeskmise sagedusega sõnadel")
lines(x = 3:14,
y = (ldt2.mod1$coefficients["(Intercept)"] +
3:14 * ldt2.mod1$coefficients["Length"] +
log1p(mean(ldt2$Freq)) * ldt2.mod1$coefficients["log1p(Freq)"]),
col = "red")
plot(Mean_RT ~ log1p(Freq), data = ldt2,
xlab = "Sõna sagedus", ylab = "Keskmine reaktsioonikiirus",
main = "Sõna sageduse mõju\nkeskmise pikkusega sõnadel",
axes=F)
lines(x = 0:12,
y = (ldt2.mod1$coefficients["(Intercept)"] +
mean(ldt2$Length) * ldt2.mod1$coefficients["Length"] +
0:12 * ldt2.mod1$coefficients["log1p(Freq)"]),
col = "red")
# Samuti arvestame sellega, et sagedus oli logaritmitud, aga joonisel tahaks päris väärtusi näha.
box(); axis(side = 2); axis(side = 1, at = 0:12, labels = round(exp(0:12)-1))
Sama ggplotiga:
library(ggplot2)
library(gridExtra) # pakett, millega saab erinevaid jooniseid paneelidena ühe joonise peale kokku panna
paneel1 <- ggplot(data = ldt2, aes(x = Length, y = Mean_RT)) +
geom_point(shape = 1) +
geom_abline(intercept = ldt2.mod1$coefficients["(Intercept)"] +
log1p(mean(ldt2$Freq)) * ldt2.mod1$coefficients["log1p(Freq)"],
slope = ldt2.mod1$coefficients["Length"],
color = "red") +
labs(x = "Sõna pikkus", y = "Keskmine reaktsioonikiirus",
title = "Sõna pikkuse mõju keskmise sagedusega sõnadel")
paneel2 <- ggplot(data = ldt2, aes(x = log1p(Freq), y = Mean_RT)) +
geom_point(shape = 1) +
geom_abline(intercept = ldt2.mod1$coefficients["(Intercept)"] +
mean(ldt2$Length) * ldt2.mod1$coefficients["Length"],
slope = ldt2.mod1$coefficients["log1p(Freq)"],
color = "red") +
scale_x_continuous(breaks = seq(0,12,1),
labels = round(exp(seq(0,12,1)))-1) + # Kuva tavalised sagedused
labs(x = "Sõna sagedus", y = "Keskmine reaktsioonikiirus",
title = "Sõna sageduse mõju keskmise pikkusega sõnadel")
grid.arrange(paneel1, paneel2, ncol=2)
Kui tahame sageduse skaalat joonisele lineaarsena (st x-telje intervallid on ühesuurused), siis tuleb regressioonijoon joonistada kõverana.
plot(Mean_RT ~Freq, data = ldt2,
xlab="Sõna sagedus", ylab="Keskmine reaktsioonikiirus", main="Sõna sagedus",
xlim=c(0, 5000))
lines(x = 0:5000, y = (ldt2.mod1$coefficients["(Intercept)"] +
mean(ldt2$Length) * ldt2.mod1$coefficients["Length"] +
log1p(0:5000) * ldt2.mod1$coefficients["log1p(Freq)"]),
col="red")
box(); axis(side=2); axis(side=1, at=0:12, labels = round(exp(0:12)-1))
Mudeleid saab visualiseerida ka ggploti laiendavate pakettide abil.
# install.packages("ggeffects")
library(ggeffects)
# plot(ggpredict(model = ldt2.mod1), facets = T, add.data = T) + labs(x = "") # see andis veateadet millegi pärast, paketis on vist midagi muutunud?
paneel1 = plot(ggpredict(model = ldt2.mod1), add.data = T)$Length
paneel2 = plot(ggpredict(model = ldt2.mod1), add.data = T)$Freq
grid.arrange(paneel1, paneel2, ncol=2)
# install.packages("sjPlot")
library(sjPlot)
plot_model(ldt2.mod1, type = "pred", grid = T) + labs(x = "") #[Maarja-Liisa, see annab veateadet]
Paketiga plotly
saab ggploti joonised teha
interaktiivseks, nii et RStuudios Viewer aknas või RMarkdownist
genereeritud html-dokumendis saab joonisel hiirega üle sõites näha
punktide väärtuseid ning saab sisse ja välja zoomida:
Ja kaks paneeli kõrvuti:
Peamõju ehk üldefekt toimib mitme tunnusega mudelis teistest tunnustest sõltumatuna. Näiteks kui reaktsiooniaeg sõltub sõna pikkusest ja sagedusest, nagu viimases näites, siis peaks sõna pikkuse efekt olema alati sama suur sõltumata sõna sagedusest ja sõna sageduse efekt alati sama suur sõltumata sõna pikkusest.
Kuid seletavate tunnuste vahel võib ka esineda koosmõju ehk interaktsioon. See tähendab, et ühe tunnuse mõju mõjutab teise tunnuse mõju. Näiteks pikemaid sõnu tuntakse ära aeglasemalt ja sagedasemaid sõnu kiiremini, aga a) pikki sagedasemaid sõnu tuntakse ära sama kiiresti kui lühikesi sagedasi sõnu, või b) lühikesi sagedasi sõnu tuntakse ära eriti kiiresti. Sellisel juhul on lisaks kummagi tunnuse peamõjule ka tunnuste vahel interaktsioon.
Peamõju ja interaktsioon lm()
funktsioonis:
Kõik peamõjude kombinatsioonid võivad anda interaktsiooni:
Peamõjusid võib olla ka rohkem kui kaks. Ja sel juhul võvad interaktsioonid olla ka kõikide kombinatsioonide vahel:
Kui enne vaatasime ainult peamõjudega sõna pikkuse ja sageduse efekti
reaktsiooniajale, siis nüüd lisame ka interaktsiooni. R-i
lm()
süntaksis võiks selleks kasutada lihtsalt tärni (*),
aga kirjutame siin praegu pikalt välja:
##
## Call:
## lm(formula = Mean_RT ~ Length + log1p(Freq) + Length:log1p(Freq),
## data = ldt2)
##
## Residuals:
## Min 1Q Median 3Q Max
## -220.071 -59.205 -0.926 44.653 243.970
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 771.2282 94.2795 8.180 1.42e-12 ***
## Length 17.8945 9.8342 1.820 0.0720 .
## log1p(Freq) -22.6969 12.5576 -1.807 0.0739 .
## Length:log1p(Freq) 0.1575 1.3934 0.113 0.9103
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 87.93 on 93 degrees of freedom
## Multiple R-squared: 0.5049, Adjusted R-squared: 0.4889
## F-statistic: 31.61 on 3 and 93 DF, p-value: 3.545e-14
Mudeli väljundisse lisandub rida Length:log1p(Freq). Antud juhul see interaktsiooni efekt ei ole oluline, p on suurem kui 0.05.
Kuigi siin näites ei osutunud interaktsioon oluliseks, siis selle
mudeli põhjal peaks reaktsiooni aja prognoose arvutama nii:
RT = 771 + 18*pikkus + -23*sagedus +
0.16*pikkus*sagedus
Ja see tähendaks, et
reaktsiooniaeg on:
Peamõjud ilma interaktsioonita:
Kui faktorite vahel ei ole interaktsioone, siis on ühe tunnuse regressioonijooned teise tunnuse erinevate tasemete puhul paralleelsed.
Peamõjud interaktsiooniga
Kuna interaktsioon mudelis ldt2.mod2
ei olnud oluline,
siis selleks et interaktsiooni efekti illustreerida, toome paar
fiktiivset näidet: Esiteks oletame, et pikkuse ja
sageduse vahel on positiivne interaktsioon, näiteks:
RT
= 700 + 15*pikkus + -25*sagedus + 3*pikkus*sagedus
Niisiis, positiivse interaktsiooni mõjul on madala sagedusega sõnadel
pikkusel väiksem efekt (must joon vasakul), aga sagedasemate sõnade
korral on pikkuse efekt tugevam (järsem kalle, helesinine joon). Sõna
sagedusele, mille peaefekt oli negatiivne, mõjub interaktsioon
vastupidiselt.
Ja kui interaktsioon oleks negatiivne:
RT = 1000 +
15*pikkus + -25*sagedus + -3*pikkus*sagedus
Aga veelkord, need on fiktiivsed näited, mistõttu ei lähe jooned joonistel ka tegelike andmepunktidega päriselt kokku :)
Occam’s razor ehk __Occami habemenoa printsiip (https://et.wikipedia.org/wiki/Ockhami_habemenuga)__ ütleb, et parim seletus on kõige lihtsam seletus. Occami habemenoa printsiibile toetudes tuleks alati mudelist välja visata kõik, mis ei ole oluline, et mudel oleks võimalikult lihtne.
Mudelite võrdlemiseks on mitu üksteist täiendavat meetodit: võib lihtsalt vaadata, et ei oleks ebaolulisi tunnuseid mudelis, võib vaadata mudeli seletusvõimet R-ruudu näol, võib võrrelda erinevusi mudeli jääkides või teha spetsiaalselt mudelite headuse võrdlemiseks mõeldud teste (mis üldiselt toetuvad ka mudeli jääkide võrdlemisele).
R-ruut ehk determinatsioonikordaja näitab protsentuaalselt, kui palju uuritava tunnuse varieerumisest mudel kirjeldab. Parem mudel on see, mis rohkem kirjeldab, mille R-ruut on suurem.
R-ruut läheb alati natuke paremaks, kui rohkem seletavaid tunnuseid lisada. Ka siis, kui seletavad tunnused on marginaalse efektiga. Occami habemenoa printsiipi aitab järgida kohandatud R-ruut, mis vähendab R-ruudu väärtust iga seletava tunnuse lisamisel: täiendava tunnuse lisamisest saadav efekt mudeli seletusvõimele peab olema suurem, kui “karistus” selle lisamise eest.
Seega interaktsiooni lisamisest üldine mudeli seletusvõime kasvas küll 0,007%, aga see on liiga vähe, et ühte lisafaktorit mudelisse lisada, mistõttu kohandatud R-ruut langes. Parem mudel on seega ilma interaktsioonita mudel.
Kohandatud R-ruutu vaatame siis, kui mudeleid võrdleme. Siis, kui oleme parima mudeli välja valinud ja raporteerime, kui hea kirjeldusvõimega mudelit esitame, siis peaks vaatama tavalist R-ruutu.
Anova testiga saab ka võrrelda mudeleid, täpsemalt mudeli jääkide (residuals) jaotust. Niimoodi peaks aga võrdlema samal andmestikul põhinevaid ühe faktori võrra erinevaid mudeleid.
## Analysis of Variance Table
##
## Model 1: Mean_RT ~ Length + log1p(Freq)
## Model 2: Mean_RT ~ Length + log1p(Freq) + Length:log1p(Freq)
## Res.Df RSS Df Sum of Sq F Pr(>F)
## 1 94 719165
## 2 93 719066 1 98.759 0.0128 0.9103
Kui kahe mudeli jääkides ei ole olulist erinevust, siis peaks valima lihtsama mudeli. Kui erinevus on oluline, tähendab see, et mudeli seletusvõime muutus faktori lisamisest oluliselt ja peaks valima keerukama mudeli. Siin võrreldud mudelite ANOVA tulemus on p=0.9 ehk olulist erinevust mudelite vahel pole ja peaksime neist valima lihtsama.
AIC ehk Akaike informatsioonikriteerium on alternatiiv R-ruudule hinnata mudeli headust. Erinevalt R-ruudust on tulemus lihtsalt üks number, mis ei paigutu mingile skaalale ja on võrreldav ainult sama andmestiku pealt tehtud mudelite piires. Mida väiksem AIC, seda parem mudel.
## df AIC
## ldt2.mod1 4 1147.654
## ldt2.mod2 5 1149.641
Lähtudes printsiibist, et parim mudel on võimalikult lihtne, peaks mudelist kõik eba- või väheolulise välja viskama. Seda peaks tegema sammhaaval: valima kõige keerukama interaktsiooni ja/või väiksema efektiga tunnuse ning vaatama, kas seda saab välja visata. Toimingut tuleks korrata seni, kuni jõuame optimaalse mudelini.
Sageli kasutatakse ka hoopis inkrementaalset meetodit, st alustatakse 0-mudelist, kus ei ole ühtegi seletavat faktorit, ning hakatakse ükshaaval lisama tunnuseid ja nende interaktsioone seni, kuni saavutatakse optimaalne mudel. Mõlemal juhul on eesmärk leida võimalikult lihtne, aga samas kõiki olulisi faktoreid sisaldav mudel.
Kasutame Lippus, Pilvik, Lõo & Lindström 2024 kõnetempo repositooriumist täiskasvanute spontaanse kõne andmestikku fonkorp2:
load(url("https://datadoi.ee/bitstream/handle/33/592/fonkorp_globaalne_konetempo.Rda?sequence=23&isAllowed=y"))
Arvutame kõneleja ja vestluspartneri kõnetempo:
fonkorp2$konetempo <- fonkorp2$silpide_arv/fonkorp2$kestus
fonkorp2$kaaskoneleja_konetempo <- fonkorp2$kaaskoneleja_silpide_arv/fonkorp2$kaaskoneleja_kestus
Testime kõnetempo varieerumist (uuritava tunnusena). Alustame 0-mudelist ja lisame kõigepealt kõneleja vanuse, soo ja nende interaktsiooni.
mod0 <- lm(konetempo ~ 1, data = fonkorp2)
mod1a <- lm(konetempo ~ vanus, data = fonkorp2)
mod1b <- lm(konetempo ~ sugu, data = fonkorp2)
Testime 0-mudelit ühe seletava tunnusega muutuja vastu:
## Analysis of Variance Table
##
## Model 1: konetempo ~ 1
## Model 2: konetempo ~ vanus
## Res.Df RSS Df Sum of Sq F Pr(>F)
## 1 163 82.776
## 2 162 81.938 1 0.83762 1.6561 0.2
## Analysis of Variance Table
##
## Model 1: konetempo ~ 1
## Model 2: konetempo ~ sugu
## Res.Df RSS Df Sum of Sq F Pr(>F)
## 1 163 82.776
## 2 162 77.631 1 5.1445 10.736 0.001286 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Anova testi põhjal võiks öelda praegu, et sugu on oluline kõnetempo mõjutaja, vanus mitte. Aga vaatame edasi:
mod2 <- lm(konetempo ~ sugu+vanus, data = fonkorp2)
mod3 <- lm(konetempo ~ sugu*vanus, data = fonkorp2)
## Analysis of Variance Table
##
## Model 1: konetempo ~ sugu
## Model 2: konetempo ~ sugu + vanus
## Res.Df RSS Df Sum of Sq F Pr(>F)
## 1 162 77.631
## 2 161 76.605 1 1.0266 2.1576 0.1438
## Analysis of Variance Table
##
## Model 1: konetempo ~ sugu + vanus
## Model 2: konetempo ~ sugu * vanus
## Res.Df RSS Df Sum of Sq F Pr(>F)
## 1 161 76.605
## 2 160 75.210 1 1.3947 2.967 0.08691 .
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
ANOVA testi põhjal jääks vanus ikkagi välja. Aga vaatame ka Aikaike informatsioonikriteeriumit. AIC käsule võime sisse panna kõik (samal andmestikul põhinevad) mudelid korraga. Võidab see, kellel on kõige väiksem AIC väärtus.
## df AIC
## mod0 2 357.2804
## mod1a 3 357.6124
## mod1b 3 348.7573
## mod2 4 348.5740
## mod3 5 347.5608
AIC põhjal on parim soo ja vanuse interaktsiooni sisaldav mudel. Vaatame nüüd selle väljundit:
##
## Call:
## lm(formula = konetempo ~ sugu * vanus, data = fonkorp2)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.72781 -0.45981 0.02138 0.47721 2.00232
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 5.070240 0.245400 20.661 <2e-16 ***
## suguN -0.166092 0.325352 -0.510 0.6104
## vanus -0.013951 0.006147 -2.269 0.0246 *
## suguN:vanus 0.013830 0.008029 1.722 0.0869 .
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.6856 on 160 degrees of freedom
## Multiple R-squared: 0.0914, Adjusted R-squared: 0.07436
## F-statistic: 5.365 on 3 and 160 DF, p-value: 0.001516
Mudeli väljundist näeme, et soo efekt nüüd on ebaoluline, aga on vanuse efekt on oluline ning peaaegu-et-oluline on ka soo ja vanuse interaktsioon.
Kuna sugu on faktor, siis Intercept ja teiste tunnuste peaefektid kehtivad soo baastaseme ehk M korral. Seega vanuse efekt meestel on -0.014 silp/sek aasta kohta. Naistel peaks vanuse efekti ja interaktsiooni kokku liitma ja -0.014 + 0.014 = 0
Kui meil on rohkem sõltumatuid tunnuseid, mida mudelis testida, on oluline kontrollida, et sõltumatud tunnused ei oleks omavahel liiga tugevasti seotud, sest mitu väga sarnaselt käituvat faktorit teevad mudeli kehvemaks.
## kaaskoneleja_konetempo vanus kaaskoneleja_vanus
## kaaskoneleja_konetempo 1.0000000 0.1122187 -0.1005938
## vanus 0.1122187 1.0000000 0.2277180
## kaaskoneleja_vanus -0.1005938 0.2277180 1.0000000
## vanusevahe -0.1712356 -0.6214024 0.6214024
## vanusevahe
## kaaskoneleja_konetempo -0.1712356
## vanus -0.6214024
## kaaskoneleja_vanus 0.6214024
## vanusevahe 1.0000000
Vanusevahe on nii kõneleja kui vestluspartneri vanusega tugevas korrelatsioonis, seega mudelisse võiks võtta kas vanusevahe või kummagi kõneleja vanused. Muud tunnused on nõrgalt korreleeruvad ja võivad koos mudelis olla.
Selle asemel, et ise ükshaaval mudelisse faktoreid juurde lisada või ära võtta ja vahesamme testida, võib seda lasta ka R-il automaatselt teha.
Käsk step()
kasutab Akaike informatsioonikriteeriumit
(AIC), et ehitada samm-sammuliselt faktoreid kas lisades või eemaldades
optimaalne mudel. Proovime leida faktoreid lisades parima mudeli
täiskasvanud kõnelejate kõnetempo seletamiseks.
y ~ 1
, see läheb käsu step()
objektiks.scope
, kuhu praegusel juhul paneme
maksimaalse mudeli, st kõikide faktorite ja nendevaheliste
interaktsioonidega.direction
, mis määrab faktorite
lisamise suuna. Variandid on “both”, “backward”, “forward”, siit praegu
valime viimase, mis tähendab, et alustatakse kõige väiksemast mudelist
ja lisatakse sellele faktoreid seni, kuni mudel ei lähe enam paremaks.
“Backward” tähendaks, et alustatakse maksimaalsest ja faktoreid võetakse
vähemaks seni, kuni mudel ei lähe enam paremaks, ja nii võib tulemus
tulla veidi erinev.Tulemuseks saadud mudelis ei pruugi kõik faktorid olla olulised p-väärtuse poolest, sest mudeleid võrreldakse ainult AIC põhjal.
Testime seletavate tunnustena kõneleja vanust ja sugu ning vestluspartneri vanust, sugu ja kõnetempot ning kõigi tunnuste vahelist interaktsiooni.
mod_step <- step(lm(konetempo ~ 1, data = fonkorp2), scope = konetempo ~ vanus * sugu * kaaskoneleja_konetempo * kaaskoneleja_sugu * kaaskoneleja_vanus, direction = "forward")
## Start: AIC=-110.13
## konetempo ~ 1
##
## Df Sum of Sq RSS AIC
## + kaaskoneleja_konetempo 1 17.6947 65.081 -147.57
## + sugu 1 5.1445 77.631 -118.66
## + kaaskoneleja_vanus 1 1.0424 81.734 -110.21
## <none> 82.776 -110.13
## + vanus 1 0.8376 81.938 -109.80
## + kaaskoneleja_sugu 1 0.6237 82.152 -109.37
##
## Step: AIC=-147.57
## konetempo ~ kaaskoneleja_konetempo
##
## Df Sum of Sq RSS AIC
## + sugu 1 3.6490 61.432 -155.04
## + kaaskoneleja_vanus 1 2.1068 62.974 -150.97
## + vanus 1 1.9490 63.132 -150.56
## <none> 65.081 -147.57
## + kaaskoneleja_sugu 1 0.0715 65.010 -145.75
##
## Step: AIC=-155.04
## konetempo ~ kaaskoneleja_konetempo + sugu
##
## Df Sum of Sq RSS AIC
## + vanus 1 2.13360 59.299 -158.83
## + kaaskoneleja_vanus 1 1.64084 59.791 -157.48
## <none> 61.432 -155.04
## + kaaskoneleja_sugu 1 0.20370 61.229 -153.58
## + sugu:kaaskoneleja_konetempo 1 0.15303 61.279 -153.45
##
## Step: AIC=-158.83
## konetempo ~ kaaskoneleja_konetempo + sugu + vanus
##
## Df Sum of Sq RSS AIC
## + kaaskoneleja_vanus 1 2.82343 56.475 -164.83
## + vanus:sugu 1 1.29091 58.008 -160.44
## <none> 59.299 -158.83
## + vanus:kaaskoneleja_konetempo 1 0.64797 58.651 -158.64
## + kaaskoneleja_sugu 1 0.13930 59.159 -157.22
## + sugu:kaaskoneleja_konetempo 1 0.12842 59.170 -157.19
##
## Step: AIC=-164.83
## konetempo ~ kaaskoneleja_konetempo + sugu + vanus + kaaskoneleja_vanus
##
## Df Sum of Sq RSS AIC
## + vanus:sugu 1 1.26531 55.210 -166.55
## <none> 56.475 -164.83
## + vanus:kaaskoneleja_konetempo 1 0.47129 56.004 -164.21
## + kaaskoneleja_sugu 1 0.21095 56.264 -163.45
## + kaaskoneleja_konetempo:kaaskoneleja_vanus 1 0.11514 56.360 -163.17
## + sugu:kaaskoneleja_vanus 1 0.07597 56.399 -163.06
## + vanus:kaaskoneleja_vanus 1 0.03302 56.442 -162.93
## + sugu:kaaskoneleja_konetempo 1 0.00148 56.474 -162.84
##
## Step: AIC=-166.55
## konetempo ~ kaaskoneleja_konetempo + sugu + vanus + kaaskoneleja_vanus +
## sugu:vanus
##
## Df Sum of Sq RSS AIC
## <none> 55.210 -166.55
## + vanus:kaaskoneleja_konetempo 1 0.53426 54.676 -166.15
## + kaaskoneleja_sugu 1 0.11512 55.095 -164.89
## + kaaskoneleja_konetempo:kaaskoneleja_vanus 1 0.09467 55.115 -164.83
## + vanus:kaaskoneleja_vanus 1 0.03828 55.172 -164.66
## + sugu:kaaskoneleja_konetempo 1 0.02604 55.184 -164.63
## + sugu:kaaskoneleja_vanus 1 0.00024 55.210 -164.55
##
## Call:
## lm(formula = konetempo ~ kaaskoneleja_konetempo + sugu + vanus +
## kaaskoneleja_vanus + sugu:vanus, data = fonkorp2)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.79108 -0.37142 0.02127 0.35300 1.67235
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 2.602218 0.389497 6.681 3.84e-10 ***
## kaaskoneleja_konetempo 0.486138 0.066242 7.339 1.07e-11 ***
## suguN -0.217945 0.280627 -0.777 0.438536
## vanus -0.018587 0.005373 -3.459 0.000696 ***
## kaaskoneleja_vanus 0.010022 0.003542 2.830 0.005265 **
## suguN:vanus 0.013174 0.006923 1.903 0.058871 .
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.5911 on 158 degrees of freedom
## Multiple R-squared: 0.333, Adjusted R-squared: 0.3119
## F-statistic: 15.78 on 5 and 158 DF, p-value: 1.374e-12
Kuidas mudelit tõlgendada? Alustama peaks olulistest peaefektidest.
Ja lõpetuseks teeme paar rehkendust selle mudeli põhjal:
2.60221810 + # vabaliige on alati sama
3.5 * 0.48613842 + # vestluspartneri tempo 3.5
0 * -0.21794464 + # minu sugu M ehk M == N on FALSE ehk 0
44 * -0.01858738 + # minu vanus 44
25 * 0.01002157 + # kaasvestleja vanus 25
0 * 44 * 0.01317365 # on kokku 0, interaktsioon ei rakendu, sest sugu pole N
## [1] 3.736397
2.60221810 + # vabaliige
5.5 * 0.48613842 + # vestluspartneri tempo 5.5
1 * -0.21794464 + # minu sugu N ehk N == N on TRUE ehk 1
80 * -0.01858738 + # minu vanus 80
44 * 0.01002157 + # kaasvestleja vanus 44
1 * 80 * 0.01317365 # N == N on TRUE ehk 1 * minu vanus 80
## [1] 5.065885
Loeme valimistulemuste andmestiku R-i.
Vaatasime eelmisel korral eraldi soo ja vanuse efekti häältesaagile ja leidsime, et mõlemal faktoril on väike, aga oluline efekt. Nüüd võiksime ühes mudelis testida kõiki võimalikke faktoreid ja välja selgitada, millised kirjeldavad häältesaaki kõige paremini. Andmestikus on sellised faktorid, mille seosed on andmestikku lisatud eeldusel, et neil on ehk hääletustulemusega mingi seos:
## [1] "ringkond" "nimekiri" "nimi"
## [4] "sünniaeg" "sugu" "tähtkuju"
## [7] "haridus" "erakond" "amet"
## [10] "kontakt" "kandidaadi_link" "eesnimi"
## [13] "nr" "hääli_kokku" "e.hääli"
## [16] "hääli_välisriigist" "kokku_ringkonnas" "hääli_kokku_prots_ring"
Enne suurema mudeli juurde asumist tuleks natuke ettevalmistusi teha ja võimalikud seletavad tunnused üle vaadata.
Kui andmestikus on mitu sama tunnuse teisendit (nt sünniaasta ja vanus), siis peaks valima neist ainult ühe. Sarnaselt käituvate tunnuste puhul tuleks samuti valida üks, mis kõige paremini seletab (nt ei ole mõtet kandidaatide mudelisse lisada nii parteilist kuuluvust kui valimisnimekirja).
## e.hääli hääli_välisriigist kokku_ringkonnas nr
## e.hääli 1.00000000 0.57115821 0.06475214 -0.06060796
## hääli_välisriigist 0.57115821 1.00000000 0.01377868 0.02979023
## kokku_ringkonnas 0.06475214 0.01377868 1.00000000 -0.04607272
## nr -0.06060796 0.02979023 -0.04607272 1.00000000
Kandidaatide tabelis on erakondlik_kuuluvus
ja
nimekiri_voi_uksikkandidaat
väga sarnased, sest enamik
kandidaate riigikogu valimistel kandideerib oma erakonna nimekirjas,
seega tasuks valida neist üks:
##
## Eesti Keskerakond Eesti Konservatiivne Rahvaerakond
## 116 117
## Eesti Reformierakond Eesti Vabaduspartei - Põllumeeste Kogu
## 125 1
## Eesti Vabaerakond Eestimaa Ühendatud Vasakpartei
## 87 11
## Elurikkuse Erakond Erakond Eesti 200
## 70 79
## Erakond Eestimaa Rohelised Isamaa Erakond
## 59 112
## Sotsiaaldemokraatlik Erakond
## 102
##
## Eesti Keskerakond Eesti Konservatiivne Rahvaerakond
## 125 125
## Eesti Reformierakond Eesti Vabaerakond
## 125 125
## Eestimaa Ühendatud Vasakpartei Elurikkuse Erakond
## 11 73
## Erakond Eesti 200 Erakond Eestimaa Rohelised
## 125 125
## Isamaa Erakond Sotsiaaldemokraatlik Erakond
## 125 125
## Üksikkandidaadid
## 15
Kandidaatide töökohtadest oleks vist liiga keeruline mingit selgete piiridega faktorit kujundada ilma käsitsi sekkumata :(
Kandidaatide kontaktanmded ei moodusta ka faktoriseeritavat tunnust, siis võiks ehk ainult vaadata, kas meiliaadress on või ei ole ja vaadata, kas häältesaak võiks seostuda sellega, kas kandidaat kasutab e-posti või mitte.
## [1] "5056540 andres.herkel@gmail.com"
## [2] "56691750"
## [3] "5012319 jaak.prozes@fennougria.ee"
## [4] "5093067 jaanika.klopets@gmail.com"
## [5] "5028390 jaanus.ojangu@gmail.com"
## [6] "56354614 juri.pino@gmail.com \n Pardi 3-9, Tallinn"
## [1] 1051
Teeme muutuja kasutab_meili binaarse faktorina selle põhjal, kas aadressis esineb “@” sümbol:
kandidaadid2019$kasutab_meili <- "ei"; kandidaadid2019$kasutab_meili[grep("@", kandidaadid2019$kontakt)] <- "jah"
kandidaadid2019$kasutab_meili <- factor(kandidaadid2019$kasutab_meili, levels = c("jah","ei"))
Et lisada veel võimalikke kirjeldavaid tunnuseid, tekitame kandidaadi nime põhjal ühe tunnuse, mis võiks kirjeldada nime keerukust: kas nime pikkus (~keerukus) mõjutab häältesaaki :)
Ja lõpetuseks: sünniaeg on date-formaadis, mis võib osutuda tülikaks, selle võiks teisendada vanuseks. Valimised toimusid 2019, nii et arvutame vanuse valimiste ajal.
## [1] "Date" "oldClass"
## [1] "1962-08-14" "1984-09-07" "1965-04-04" "1972-12-10" "1966-09-09"
## [6] "1970-07-03"
Kui mudelil ei ole ühtegi seletavat tunnust, uuritava tunnuse varieerumist seletab tema varieerumine ise, siis sellise mudeli valemiks on y ~ 1.
m0 <- lm(log(hääli_kokku) ~ 1, data = kandidaadid2019, subset = haridus != "Algharidus")
summary(m0)
##
## Call:
## lm(formula = log(hääli_kokku) ~ 1, data = kandidaadid2019,
## subset = haridus != "Algharidus")
##
## Residuals:
## Min 1Q Median 3Q Max
## -5.0081 -1.1162 0.0026 1.0334 4.8991
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 5.00805 0.04732 105.8 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.568 on 1097 degrees of freedom
Sõltumatute tunnustena võiks testida:
nimekiri_voi_uksikkandidaat, ringkond, haridus, sugu, vanus
ja nalja pärast ka:
sodiaak, kasutab_meili,
nime_pikkus
Aga kuna me eelmisel korral juba vaatasime
sugu ja haridust, siis alustame neist.
Esimeseks faktoriks lisame hariduse ja võrdleme seda ANOVA testi abil nullmudeliga.
m1 <- lm(log(hääli_kokku) ~ haridus, data = kandidaadid2019, subset = haridus != "Algharidus")
anova(m0, m1)
## Analysis of Variance Table
##
## Model 1: log(hääli_kokku) ~ 1
## Model 2: log(hääli_kokku) ~ haridus
## Res.Df RSS Df Sum of Sq F Pr(>F)
## 1 1097 2697.3
## 2 1095 2500.1 2 197.28 43.202 < 2.2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Faktor haridus muudab mudelit oluliselt, nii et jääb sisse. Vaatame mudeli väljundit:
##
## Call:
## lm(formula = log(hääli_kokku) ~ haridus, data = kandidaadid2019,
## subset = haridus != "Algharidus")
##
## Residuals:
## Min 1Q Median 3Q Max
## -4.3599 -1.0568 0.0468 0.9530 4.6607
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 4.35993 0.09282 46.971 <2e-16 ***
## haridusKõrgharidus 0.88651 0.10679 8.302 3e-16 ***
## haridusPõhiharidus -1.02977 0.41437 -2.485 0.0131 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.511 on 1095 degrees of freedom
## Multiple R-squared: 0.07314, Adjusted R-squared: 0.07144
## F-statistic: 43.2 on 2 and 1095 DF, p-value: < 2.2e-16
## Analysis of Variance Table
##
## Response: log(hääli_kokku)
## Df Sum Sq Mean Sq F value Pr(>F)
## haridus 2 197.27 98.637 43.202 < 2.2e-16 ***
## Residuals 1095 2500.07 2.283
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Lisame teise faktorina soo ning nüüd võrdleme seda mitte nullmudeli vaid eelmise sammuga:
m2 <- lm(log(hääli_kokku) ~ haridus + sugu, data = kandidaadid2019, subset = haridus != "Algharidus")
anova(m1, m2)
## Analysis of Variance Table
##
## Model 1: log(hääli_kokku) ~ haridus
## Model 2: log(hääli_kokku) ~ haridus + sugu
## Res.Df RSS Df Sum of Sq F Pr(>F)
## 1 1095 2500.1
## 2 1094 2478.5 1 21.547 9.5107 0.002094 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Jällegi on mõju oluline, sugu peaks ka mudelisse jääma. Vaatame mudeli kokkuvõtet ja ANOVAt ka.
##
## Call:
## lm(formula = log(hääli_kokku) ~ haridus + sugu, data = kandidaadid2019,
## subset = haridus != "Algharidus")
##
## Residuals:
## Min 1Q Median 3Q Max
## -4.4398 -1.0472 0.0236 0.9863 4.8537
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 4.43984 0.09602 46.237 < 2e-16 ***
## haridusKõrgharidus 0.91185 0.10669 8.547 < 2e-16 ***
## haridusPõhiharidus -1.00316 0.41286 -2.430 0.01527 *
## sugunaine -0.29826 0.09671 -3.084 0.00209 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.505 on 1094 degrees of freedom
## Multiple R-squared: 0.08112, Adjusted R-squared: 0.07861
## F-statistic: 32.2 on 3 and 1094 DF, p-value: < 2.2e-16
## Analysis of Variance Table
##
## Response: log(hääli_kokku)
## Df Sum Sq Mean Sq F value Pr(>F)
## haridus 2 197.27 98.637 43.5377 < 2.2e-16 ***
## sugu 1 21.55 21.547 9.5107 0.002094 **
## Residuals 1094 2478.52 2.266
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Lisame kahe olulise faktori interaktsiooni ja võrdleme seda ainult peamõjusid sisaldava mudeliga:
m3 <- lm(log(hääli_kokku) ~ haridus + sugu + haridus:sugu, data = kandidaadid2019, subset = haridus != "Algharidus")
anova(m2, m3)
## Analysis of Variance Table
##
## Model 1: log(hääli_kokku) ~ haridus + sugu
## Model 2: log(hääli_kokku) ~ haridus + sugu + haridus:sugu
## Res.Df RSS Df Sum of Sq F Pr(>F)
## 1 1094 2478.5
## 2 1092 2463.7 2 14.794 3.2787 0.03805 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Ka see on oluline! Vaatame jälle ka mudeli väljundi üle.
##
## Call:
## lm(formula = log(hääli_kokku) ~ haridus + sugu + haridus:sugu,
## data = kandidaadid2019, subset = haridus != "Algharidus")
##
## Residuals:
## Min 1Q Median 3Q Max
## -4.5352 -1.0322 0.0279 0.9414 4.8504
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 4.5352 0.1078 42.054 < 2e-16 ***
## haridusKõrgharidus 0.7737 0.1260 6.138 1.16e-09 ***
## haridusPõhiharidus -0.6330 0.5122 -1.236 0.21672
## sugunaine -0.6541 0.2083 -3.140 0.00174 **
## haridusKõrgharidus:sugunaine 0.4772 0.2355 2.026 0.04300 *
## haridusPõhiharidus:sugunaine -0.9474 0.8633 -1.097 0.27269
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.502 on 1092 degrees of freedom
## Multiple R-squared: 0.08661, Adjusted R-squared: 0.08243
## F-statistic: 20.71 on 5 and 1092 DF, p-value: < 2.2e-16
Kuidas seda interaktsiooniga mudelit tõlgendama peaks?
## Classes 'ggeffects' and 'data.frame': 6 obs. of 6 variables:
## $ x : Factor w/ 3 levels "Keskharidus (sh keskeriharidus)",..: 1 1 2 2 3 3
## $ predicted: num 93.2 48.5 202.1 169.3 49.5 ...
## $ std.error: num 0.1078 0.1783 0.0652 0.0884 0.5007 ...
## $ conf.low : num 75.5 34.2 177.8 142.4 18.5 ...
## $ conf.high: num 115.2 68.8 229.7 201.4 132.2 ...
## $ group : Factor w/ 2 levels "mees","naine": 1 2 1 2 1 2
## - attr(*, "legend.labels")= chr [1:2] "mees" "naine"
## - attr(*, "x.is.factor")= chr "1"
## - attr(*, "averaged_predictions")= logi FALSE
## - attr(*, "continuous.group")= logi FALSE
## - attr(*, "rawdata")='data.frame': 1098 obs. of 5 variables:
## ..$ response: int [1:1098] 222 43 35 23 15 36 9 5 18 12 ...
## ..$ x : num [1:1098] 2 2 2 2 2 2 1 2 1 1 ...
## ..$ group : Factor w/ 2 levels "mees","naine": 1 2 1 2 1 1 1 1 2 1 ...
## ..$ facet : Factor w/ 1 level "1": 1 1 1 1 1 1 1 1 1 1 ...
## ..$ rowname : chr [1:1098] "1" "2" "3" "4" ...
## - attr(*, "title")= chr "Predicted values of hääli_kokku"
## - attr(*, "x.title")= chr "haridus"
## - attr(*, "y.title")= chr "hääli_kokku"
## - attr(*, "legend.title")= chr "sugu"
## - attr(*, "x.axis.labels")= chr [1:3] "Keskharidus (sh keskeriharidus)" "Kõrgharidus" "Põhiharidus"
## - attr(*, "constant.values")= Named list()
## - attr(*, "terms")= chr [1:2] "haridus" "sugu"
## - attr(*, "original.terms")= chr [1:2] "haridus" "sugu"
## - attr(*, "at.list")=List of 2
## ..$ haridus: chr [1:3] "Keskharidus (sh keskeriharidus)" "Kõrgharidus" "Põhiharidus"
## ..$ sugu : chr [1:2] "mees" "naine"
## - attr(*, "ci.lvl")= num 0.95
## - attr(*, "type")= chr "fe"
## - attr(*, "response.name")= chr "hääli_kokku"
## - attr(*, "back.transform")= logi TRUE
## - attr(*, "response.transform")= chr "log(hääli_kokku)"
## - attr(*, "untransformed.predictions")= num [1:6] 4.54 3.88 5.31 5.13 3.9 ...
## - attr(*, "family")= chr "gaussian"
## - attr(*, "link")= chr "identity"
## - attr(*, "logistic")= chr "0"
## - attr(*, "is.trial")= chr "0"
## - attr(*, "link_inverse")=function (eta)
## - attr(*, "link_function")=function (mu)
## - attr(*, "fitfun")= chr "lm"
## - attr(*, "verbose")= logi TRUE
## - attr(*, "model.name")= chr "m3"
Lisame ühe täiendava faktori, näiteks vanuse:
m4 <- lm(log(hääli_kokku) ~ haridus + sugu + haridus:sugu + vanus, data = kandidaadid2019, subset = haridus != "Algharidus")
anova(m3, m4)
## Analysis of Variance Table
##
## Model 1: log(hääli_kokku) ~ haridus + sugu + haridus:sugu
## Model 2: log(hääli_kokku) ~ haridus + sugu + haridus:sugu + vanus
## Res.Df RSS Df Sum of Sq F Pr(>F)
## 1 1092 2463.7
## 2 1091 2463.7 1 0.023058 0.0102 0.9195
Mudel ei läinud paremaks, nii et see jääb välja, aga vaatame enne mudeli väljundit:
##
## Call:
## lm(formula = log(hääli_kokku) ~ haridus + sugu + haridus:sugu +
## vanus, data = kandidaadid2019, subset = haridus != "Algharidus")
##
## Residuals:
## Min 1Q Median 3Q Max
## -4.5350 -1.0300 0.0265 0.9444 4.8484
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 4.5179243 0.2020855 22.356 < 2e-16 ***
## haridusKõrgharidus 0.7718122 0.1274698 6.055 1.93e-09 ***
## haridusPõhiharidus -0.6297054 0.5134616 -1.226 0.22032
## sugunaine -0.6544883 0.2084666 -3.140 0.00174 **
## vanus 0.0003709 0.0036707 0.101 0.91953
## haridusKõrgharidus:sugunaine 0.4780132 0.2357734 2.027 0.04286 *
## haridusPõhiharidus:sugunaine -0.9450990 0.8640236 -1.094 0.27427
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.503 on 1091 degrees of freedom
## Multiple R-squared: 0.08662, Adjusted R-squared: 0.0816
## F-statistic: 17.24 on 6 and 1091 DF, p-value: < 2.2e-16
Selle mudeli p-väärtus on endiselt oluline, st ebaoluline faktor ei tee mudelit otseselt halvemaks, aga kuna ta ei tee seda ka paremaks, siis ei ole seda tarvis sinna panna. Nii et vanus jääb välja, selle asemel proovime midagi muud.
Lisame vanuse asemel näiteks nimekirja, kus kandidaat kandideeris. Kuna sel tulbal on tabelis üsna pikk nimi ja mudeli väljundis esineb see tunnus tulba nimega, siis selle võiks välja vahetada millegi lühema vastu nt “nimek”.
m4 <- lm(log(hääli_kokku) ~ haridus + sugu + haridus:sugu + nimekiri, data = kandidaadid2019, subset = haridus != "Algharidus")
anova(m3, m4)
## Analysis of Variance Table
##
## Model 1: log(hääli_kokku) ~ haridus + sugu + haridus:sugu
## Model 2: log(hääli_kokku) ~ haridus + sugu + haridus:sugu + nimekiri
## Res.Df RSS Df Sum of Sq F Pr(>F)
## 1 1092 2463.7
## 2 1082 1359.8 10 1104 87.847 < 2.2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
See on jälle väga oluline faktor, jääb sisse!
##
## Call:
## lm(formula = log(hääli_kokku) ~ haridus + sugu + haridus:sugu +
## nimekiri, data = kandidaadid2019, subset = haridus != "Algharidus")
##
## Residuals:
## Min 1Q Median 3Q Max
## -3.8567 -0.7391 -0.1469 0.6311 3.4952
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 5.74918 0.12857 44.718 < 2e-16
## haridusKõrgharidus 0.50538 0.09623 5.252 1.81e-07
## haridusPõhiharidus 0.02772 0.38488 0.072 0.9426
## sugunaine -0.06665 0.15743 -0.423 0.6721
## nimekiriEesti Konservatiivne Rahvaerakond -0.25788 0.14364 -1.795 0.0729
## nimekiriEesti Reformierakond 0.16144 0.14181 1.138 0.2552
## nimekiriEesti Vabaerakond -2.80746 0.14416 -19.475 < 2e-16
## nimekiriEestimaa Ühendatud Vasakpartei -2.57966 0.35284 -7.311 5.14e-13
## nimekiriElurikkuse Erakond -2.14443 0.16593 -12.924 < 2e-16
## nimekiriErakond Eesti 200 -1.55219 0.14251 -10.891 < 2e-16
## nimekiriErakond Eestimaa Rohelised -2.31718 0.14474 -16.009 < 2e-16
## nimekiriIsamaa Erakond -0.58272 0.14200 -4.104 4.37e-05
## nimekiriSotsiaaldemokraatlik Erakond -0.75939 0.14204 -5.346 1.10e-07
## nimekiriÜksikkandidaadid -1.72573 0.30809 -5.601 2.70e-08
## haridusKõrgharidus:sugunaine 0.08283 0.17662 0.469 0.6392
## haridusPõhiharidus:sugunaine -0.79832 0.64521 -1.237 0.2162
##
## (Intercept) ***
## haridusKõrgharidus ***
## haridusPõhiharidus
## sugunaine
## nimekiriEesti Konservatiivne Rahvaerakond .
## nimekiriEesti Reformierakond
## nimekiriEesti Vabaerakond ***
## nimekiriEestimaa Ühendatud Vasakpartei ***
## nimekiriElurikkuse Erakond ***
## nimekiriErakond Eesti 200 ***
## nimekiriErakond Eestimaa Rohelised ***
## nimekiriIsamaa Erakond ***
## nimekiriSotsiaaldemokraatlik Erakond ***
## nimekiriÜksikkandidaadid ***
## haridusKõrgharidus:sugunaine
## haridusPõhiharidus:sugunaine
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.121 on 1082 degrees of freedom
## Multiple R-squared: 0.4959, Adjusted R-squared: 0.4889
## F-statistic: 70.96 on 15 and 1082 DF, p-value: < 2.2e-16
Mudeli väljundist näeme, et valimisnimekirja lisamine kasvatas väga palju mudeli R-ruutu, enne oli see kuskil 8% kandis, nüüd on 50%.
Edasi võiks sammhaaval testida kõik võimalikud kombinatsioonid läbi. Mis on oluline, jääb sisse, mis ei ole, see välja.
Alternatiiv oleks alustada maksimaalsest mudelist, mis oleks:
log(hääli_kokku)~ nimekiri * ringkond * haridus * sugu * vanus * tähtkuju * kasutab_meili * nime_pikkus
See sisaldab 8 faktori peamõju, 28 kahe faktori interaktsiooni, 56 kolme faktori interaktsiooni 70 neljast, 56 viiest, 28 kuuest 8 seitsmest ja 1 kaheksa faktori interakstiooni :O
Tõenäoliselt enamik neist interaktsioonidest ja osa peamõjudest ei ole olulised, aga nende läbitestimine on üsna aeganõudev ning nii keeruka mudeli sisukas seletamine võib olla raske.
R-i baaspaketi käsk anova()
arvutab ainult esimest tüüpi
ANOVA-t, mis põhineb lineaarsel mudelil, kus faktori üks tase on
baastasemeks ja kõiki teisi tasemeid võrreldakse baastaseme väärtusega
(ja tulemused sõltuvad pisut sellest, millises järjekorras tunnuseid
mudelisse lisada). Kui meil aga ei ole üheselt defineeritavat baastaset
ja me tahame rühmi võrrelda rühmaülese keskmise suhtes, siis sobib
selleks paremini kolmandat tüüpi ANOVA. Paketis car
on käsk
Anova()
(NB! suure algustähega), millel on rohkem
valikuid kui baaspaketis.
# kui sul pole see pakett alla laetud, siis kõigepealt installi
# install.packages("car")
library(car)
## Loading required package: carData
## Anova Table (Type III tests)
##
## Response: log(hääli_kokku)
## Sum Sq Df F value Pr(>F)
## (Intercept) 3990.2 1 1768.5709 < 2.2e-16 ***
## haridus 97.8 2 21.6741 5.876e-10 ***
## sugu 22.2 1 9.8577 0.001737 **
## haridus:sugu 14.8 2 3.2787 0.038049 *
## Residuals 2463.7 1092
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Vaatame Tukey HSD tulemust mudeliga, kus on kahe faktori peamõjud ja nende vaheline interaktsioon:
TukeyHSD(aov(log(hääli_kokku) ~ haridus + sugu + haridus:sugu, data = kandidaadid2019, subset = haridus != "Algharidus"))
## Tukey multiple comparisons of means
## 95% family-wise confidence level
##
## Fit: aov(formula = log(hääli_kokku) ~ haridus + sugu + haridus:sugu, data = kandidaadid2019, subset = haridus != "Algharidus")
##
## $haridus
## diff lwr upr
## Kõrgharidus-Keskharidus (sh keskeriharidus) 0.8865119 0.6373791 1.13564458
## Põhiharidus-Keskharidus (sh keskeriharidus) -1.0297743 -1.9964842 -0.06306436
## Põhiharidus-Kõrgharidus -1.9162861 -2.8664479 -0.96612435
## p adj
## Kõrgharidus-Keskharidus (sh keskeriharidus) 0.0000000
## Põhiharidus-Keskharidus (sh keskeriharidus) 0.0335883
## Põhiharidus-Kõrgharidus 0.0000075
##
## $sugu
## diff lwr upr p adj
## naine-mees -0.2964824 -0.4852892 -0.1076756 0.0021137
##
## $`haridus:sugu`
## diff
## Kõrgharidus:mees-Keskharidus (sh keskeriharidus):mees 0.77369590
## Põhiharidus:mees-Keskharidus (sh keskeriharidus):mees -0.63304216
## Keskharidus (sh keskeriharidus):naine-Keskharidus (sh keskeriharidus):mees -0.65413385
## Kõrgharidus:naine-Keskharidus (sh keskeriharidus):mees 0.59673935
## Põhiharidus:naine-Keskharidus (sh keskeriharidus):mees -2.23461586
## Põhiharidus:mees-Kõrgharidus:mees -1.40673806
## Keskharidus (sh keskeriharidus):naine-Kõrgharidus:mees -1.42782975
## Kõrgharidus:naine-Kõrgharidus:mees -0.17695655
## Põhiharidus:naine-Kõrgharidus:mees -3.00831176
## Keskharidus (sh keskeriharidus):naine-Põhiharidus:mees -0.02109169
## Kõrgharidus:naine-Põhiharidus:mees 1.22978152
## Põhiharidus:naine-Põhiharidus:mees -1.60157370
## Kõrgharidus:naine-Keskharidus (sh keskeriharidus):naine 1.25087321
## Põhiharidus:naine-Keskharidus (sh keskeriharidus):naine -1.58048201
## Põhiharidus:naine-Kõrgharidus:naine -2.83135521
## lwr
## Kõrgharidus:mees-Keskharidus (sh keskeriharidus):mees 0.4138731
## Põhiharidus:mees-Keskharidus (sh keskeriharidus):mees -2.0951656
## Keskharidus (sh keskeriharidus):naine-Keskharidus (sh keskeriharidus):mees -1.2489066
## Kõrgharidus:naine-Keskharidus (sh keskeriharidus):mees 0.1987404
## Põhiharidus:naine-Keskharidus (sh keskeriharidus):mees -4.1768376
## Põhiharidus:mees-Kõrgharidus:mees -2.8481673
## Keskharidus (sh keskeriharidus):naine-Kõrgharidus:mees -1.9697411
## Kõrgharidus:naine-Kõrgharidus:mees -0.4905112
## Põhiharidus:naine-Kõrgharidus:mees -4.9350029
## Keskharidus (sh keskeriharidus):naine-Põhiharidus:mees -1.5383262
## Kõrgharidus:naine-Põhiharidus:mees -0.2216485
## Põhiharidus:naine-Põhiharidus:mees -3.9933244
## Kõrgharidus:naine-Keskharidus (sh keskeriharidus):naine 0.6828955
## Põhiharidus:naine-Keskharidus (sh keskeriharidus):naine -3.5645236
## Põhiharidus:naine-Kõrgharidus:naine -4.7655396
## upr
## Kõrgharidus:mees-Keskharidus (sh keskeriharidus):mees 1.13351866
## Põhiharidus:mees-Keskharidus (sh keskeriharidus):mees 0.82908128
## Keskharidus (sh keskeriharidus):naine-Keskharidus (sh keskeriharidus):mees -0.05936113
## Kõrgharidus:naine-Keskharidus (sh keskeriharidus):mees 0.99473830
## Põhiharidus:naine-Keskharidus (sh keskeriharidus):mees -0.29239411
## Põhiharidus:mees-Kõrgharidus:mees 0.03469120
## Keskharidus (sh keskeriharidus):naine-Kõrgharidus:mees -0.88591838
## Kõrgharidus:naine-Kõrgharidus:mees 0.13659810
## Põhiharidus:naine-Kõrgharidus:mees -1.08162064
## Keskharidus (sh keskeriharidus):naine-Põhiharidus:mees 1.49614280
## Kõrgharidus:naine-Põhiharidus:mees 2.68121153
## Põhiharidus:naine-Põhiharidus:mees 0.79017697
## Kõrgharidus:naine-Keskharidus (sh keskeriharidus):naine 1.81885092
## Põhiharidus:naine-Keskharidus (sh keskeriharidus):naine 0.40355954
## Põhiharidus:naine-Kõrgharidus:naine -0.89717078
## p adj
## Kõrgharidus:mees-Keskharidus (sh keskeriharidus):mees 0.0000000
## Põhiharidus:mees-Keskharidus (sh keskeriharidus):mees 0.8190969
## Keskharidus (sh keskeriharidus):naine-Keskharidus (sh keskeriharidus):mees 0.0214345
## Kõrgharidus:naine-Keskharidus (sh keskeriharidus):mees 0.0002924
## Põhiharidus:naine-Keskharidus (sh keskeriharidus):mees 0.0134362
## Põhiharidus:mees-Kõrgharidus:mees 0.0604392
## Keskharidus (sh keskeriharidus):naine-Kõrgharidus:mees 0.0000000
## Kõrgharidus:naine-Kõrgharidus:mees 0.5913273
## Põhiharidus:naine-Kõrgharidus:mees 0.0001331
## Keskharidus (sh keskeriharidus):naine-Põhiharidus:mees 1.0000000
## Kõrgharidus:naine-Põhiharidus:mees 0.1505630
## Põhiharidus:naine-Põhiharidus:mees 0.3954551
## Kõrgharidus:naine-Keskharidus (sh keskeriharidus):naine 0.0000000
## Põhiharidus:naine-Keskharidus (sh keskeriharidus):naine 0.2055641
## Põhiharidus:naine-Kõrgharidus:naine 0.0004525
Tukey HSD test annab kõikide faktori tasemete vaheliste paaride võrdlused. Keerulisema ja rohketasemelise faktori korral võib see väljund olla üsna pikk ja kirju. Tavaliselt post-hoc testi tulemusi ei raporteerita tabelina vaid tehakse sellest teksti sees üldistusi või korjatakse sealt välja võrdlused, mis on sisuliselt huvitavad.
Kordamisküsimuste testi saad ka moodlis teha, seal näed pärast ka õigeid vastuseid ja kommentaare.
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 771.2282027 94.279541 8.1802286 1.422446e-12
## Length 17.8944667 9.834225 1.8196112 7.203563e-02
## log1p(Freq) -22.6968893 12.557574 -1.8074263 7.392896e-02
## Length:log1p(Freq) 0.1574769 1.393383 0.1130177 9.102602e-01
lm()
– lineaarne mudelanova()
– anova test (vaikimisi I tüüpi)
-AIC()
– Aikaike informatsioonikriteeriumstep()
– stepwise protseduur parima mudeli
valimisekscar::Anova(lm(), type="III")
– kolmandat tüüpi
anovacov2cor(cov())
– tunnuste vahelise konrrelatsiooni
testiminecar::vif(model1)
– VIF ehk Variance Inflation
Factor