Andmestikud endiselt:
ldt.csv
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.
Sõna sagedust joonistades peame arvestama sellega, et mudelis on see logaritmitud ja regressioonijoont arvestades peame seda ka lograitmima, aga siis ei ole skaala ühikust kerge aru saada. Siin joonisel on see lahendatud nii, et punktid ja jooned on joonistatud logaritmitud väärtustega ning joonise x-teljele on lisatud skaala, kus väärtused on uuesti astendatud.
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, show_data = T) + labs(x = "")
# efektid eraldi paneelidele
paneel1 = plot(ggpredict(model = ldt2.mod1), show_data = T)$Length
paneel2 = plot(ggpredict(model = ldt2.mod1), show_data = T)$Freq
grid.arrange(paneel1, paneel2, ncol=2)
# install.packages("sjPlot")
library(sjPlot)
plot_model(ldt2.mod1, type = "pred", grid = T) + labs(x = "")
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
Kui efekte visualiseerida, siis võiks joonistada eraldi paneelid kaaskõneleja kõnetempo ja kaaskõneleja vanusega, sest need on mudelis ainult peamõjudena, kuid kõneleja soo ja vanuse vahel on interaktsioon, seetõttu neid võiks näidata ühel paneelil.
partneri_tempo <- ggplot(fonkorp2, aes(y = konetempo, x = kaaskoneleja_konetempo))+
geom_point()+
geom_smooth(method = "lm")
parneri_vanus <- ggplot(fonkorp2, aes(y = konetempo, x = kaaskoneleja_vanus))+
geom_point()+
geom_smooth(method = "lm")
sugu_vanus <- ggplot(fonkorp2, aes(y = konetempo, x = vanus, col = sugu))+
geom_point()+
geom_smooth(method = "lm")
subplot(ggplotly(partneri_tempo),
ggplotly(parneri_vanus),
ggplotly(sugu_vanus))
## `geom_smooth()` using formula = 'y ~ x'
## `geom_smooth()` using formula = 'y ~ x'
## `geom_smooth()` using formula = 'y ~ x'
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).
Vaatame uuesti välteandmestikku:
dat <- read.delim("http://datadoi.ut.ee/bitstream/handle/33/51/Lippus_etal_JPhon2013_dataset.txt?sequence=4&isAllowed=y")
dat$Quantity <- factor(dat$Quantity); levels(dat$Quantity) <- paste0("Q", levels(dat$Quantity))
# keskmistatud andmestik
dat2 <- dat %>%
dplyr::filter(Struct == "cvcv") %>%
group_by(SP, Gender, Quantity, Intonation) %>%
summarise(C1 = mean(C1, na.rm=T), V1 = mean(V1), C2 = mean(C3), V2 = mean(V2),
TP.time = mean(TP.time, na.rm=T), S1.f0.end = mean(S1.f0.end, na.rm=T),
S1.f0.range = mean(S1.f0.range, na.rm=T), S2.f0.range = mean(S2.f0.range, na.rm=T),
Euk1 =mean(Euk1), Euk2 = mean(Euk2))
Ja teeme mudeli kahe faktori ja nendevahelise interaktsiooniga (vokaali kestus sõltub aktsentueeritusest ja vältest)
## Analysis of Variance Table
##
## Response: log(V1)
## Df Sum Sq Mean Sq F value Pr(>F)
## Quantity 2 14.9633 7.4816 127.9372 < 2.2e-16 ***
## Intonation 1 1.0178 1.0178 17.4049 6.126e-05 ***
## Quantity:Intonation 2 0.0270 0.0135 0.2311 0.794
## Residuals 108 6.3157 0.0585
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Kahe faktori vaheline interaktsioon (Quantity:Intonation) ei ole siin mudelis oluline ja Occami printsiipi järgides peaks selle mudelist välja jätma.
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(V1)
## Sum Sq Df F value Pr(>F)
## (Intercept) 264.960 1 4530.8459 < 2e-16 ***
## Quantity 6.230 2 53.2682 < 2e-16 ***
## Intonation 0.204 1 3.4894 0.06447 .
## Quantity:Intonation 0.027 2 0.2311 0.79405
## Residuals 6.316 108
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Miks I tüüpi ANOVAga on aktsentueeritus oluline aga III tüüpi ANOVAga pigem ei ole? Sest kui võrrelda kahe rühma keskmiseid omavahel, on erinevus deaktsentueeritud ja aktsentueeritud sõnade vahel 17.4 ms, aga kui võrrelda kummagi rühma keskmist üldkeskmisega, siis on erinevus vastavalt 9.6 ja -7.8 ms.
Vaatame Tukey HSD tulemust välteandmete mudeliga, kus on kahe faktori peamõjud ja nende vaheline interaktsioon. Tegelikult mudelis (mida vaatasime eelmisel lehel ANOVA testiga) ei olnud interaktsioon oluline ja optimaalsest mudelist võiks selle välja jätta. Samas näeme, et interaktsiooni tasemete võrdluses on paarid, mis siiski on üksteisest erinevad (aga erinevus on kirjeldatud juba peamõjudega).
## Tukey multiple comparisons of means
## 95% family-wise confidence level
##
## Fit: aov(formula = log(V1) ~ Quantity * Intonation, data = dat2)
##
## $Quantity
## diff lwr upr p adj
## Q2-Q1 0.6296095 0.49687974 0.7623392 0.0000000
## Q3-Q1 0.8524131 0.72141904 0.9834072 0.0000000
## Q3-Q2 0.2228036 0.09091601 0.3546912 0.0003224
##
## $Intonation
## diff lwr upr p adj
## H*L-deaccented 0.1899807 0.0996909 0.2802706 6.15e-05
##
## $`Quantity:Intonation`
## diff lwr upr p adj
## Q2:deaccented-Q1:deaccented 0.58612667 0.341727316 0.8305260 0.0000000
## Q3:deaccented-Q1:deaccented 0.82435938 0.587057687 1.0616611 0.0000000
## Q1:H*L-Q1:deaccented 0.14737915 -0.081541631 0.3762999 0.4273983
## Q2:H*L-Q1:deaccented 0.80624002 0.577319234 1.0351608 0.0000000
## Q3:H*L-Q1:deaccented 1.02771669 0.798795909 1.2566375 0.0000000
## Q3:deaccented-Q2:deaccented 0.23823272 -0.002852592 0.4793180 0.0547310
## Q1:H*L-Q2:deaccented -0.43874752 -0.671588138 -0.2059069 0.0000044
## Q2:H*L-Q2:deaccented 0.22011335 -0.012727273 0.4529540 0.0751601
## Q3:H*L-Q2:deaccented 0.44159002 0.208749402 0.6744306 0.0000037
## Q1:H*L-Q3:deaccented -0.67698023 -0.902359482 -0.4516010 0.0000000
## Q2:H*L-Q3:deaccented -0.01811937 -0.243498617 0.2072599 0.9999030
## Q3:H*L-Q3:deaccented 0.20335731 -0.022021942 0.4287366 0.1017071
## Q2:H*L-Q1:H*L 0.65886087 0.442323485 0.8753982 0.0000000
## Q3:H*L-Q1:H*L 0.88033754 0.663800159 1.0968749 0.0000000
## Q3:H*L-Q2:H*L 0.22147667 0.004939294 0.4380141 0.0418639
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