1. Tietokoneharjoitukset Aluksi Tällä kurssilla käytetään R-ohjelmistoa, jonka käyttämisestä lienee muutama sana paikallaan. R-ohjelmisto on laajasti käytetty vapaassa levityksessä oleva ammattimaiseen tilastolliseen analyysiin soveltuva ohjelmointikieli. Aallon koneilta R löytyy kurssin henkilökunnan tietojen mukaan kaikista Kandidaattikeskuksen (Otakaari 1) ja Maarintalon tietokoneluokista (sekä Windos että Linux). Kurssin tehtävät on mahdollista tehdä perus R-ohjelmiston käyttöliittymällä, joka on mahdollista ladata ilmaiseksi omalle koneelle. R-ohjelmointikieleen on implementoitu monia ohjelmointiympäristöjä (Integrated development environment, IDE). Suosittelemme, että käytätte ohjelmointiympäristöä nimeltä RStudio. Rstudio on niin ikään vapaasti saatavilla, eli sen voi halutessaan ladata omalle koneelleen. Huomaa että RStudio käyttäminen vaatii perus R-ohjelmiston asentamisen. RStudio löytyy Aallon koneilta polusta: c:\program_files\rstudio\bin\rstudio.exe Perusteet Komentoja esitellään kurssin kuluessä sitä mukaa, kun niitä tarvitaan. Tässä muutamia käyttökelpoisia peruskomentoja, joista voi olla apua alkuun pääsemiseksi. Muuttujien luominen Muuttujia luodaan kuten esim. Matlabissa: x = 5 tai vaihtoehtoisesti x <- 5 Vektoreita luodaan komennolla c() x <- c(1,2,3) Matriisi luodaan vektorin avulla X <- matrix(c(1,1,1,2,2,2,3,3,3,4), nrow=5, ncol=2, byrow=false) Argumentit nrow ja ncol kertoo rivien ja sarakkeiden lukumäärän. Argumentti byrow kertoo miten matriisi täytetään, tässä tapauksessa sarakkeittain, eli ylhäältä alas ja vasemmalta oikealle. Huomaa, että R:ssä iso ja pieni kirjain eivät ole sama asia! Koodia kommentoidaan merkillä #. 1 / 10
Työhakemiston vaihtaminen Työhakemisto voidaan asettaa komennolla setwd() siten, että hakemisto tulee sulkujen sisään. Ohjelmistossa Rstudio tämä onnistuu myös graafisesti valitsemalla ohjelman ylävalikosta Session-Set Working Directory-Choose Directory. Scriptit Kurssin tehtävät kannataa tehdä R-scripteinä, joihin voi tarvittaessa palata myöhemmin. Scripti luodaan ohjelman ylävalikosta File- New File- R Script. Scriptin voi ajaa komennolla sourcet("scriptin_nimi.r"). Yksittäiset Scriptin rivit voi ajaa Windows-koneissa näppäinyhdistelmällä ctrl+ r tai ctrl+enter (Ubuntussa ctrl+enter). Datan lataaminen Kurssilla käsitellään usein dataa, joka on tallennettu ulkoiseen tiedostoon. Esimerkiksi työhakemistossa oleva tiedosto "data.txt"voidaan ladata komennolla read.table("data.txt", header=t, sep="\t") Argumentti header=t kertoo, että tiedoston ensimmäinen rivi on otsikkorivi. Jos tiedoston enismmäinen rivi halutaan tulkita dataksi, niin voidaan kirjoitaa header=f sen sijaan. Lisäksi jossain tapauksissa aineisto on eroteltu esimerkiksi tabulaattorilla, tällöin voidaan kirjoittaa sep = "\t" tai vaihtoehtoisesti jokin muu dataa erottava merkki (oletuksena on pilkku). Komentojen etsiminen ja help Lisätietoja monista asioista saa komennolla help(). Esimerkiksi help(matrix) kertoo miten komennolla matrix voidaan luoda matriiseja. Erityisen kätevä on myös help.search(), jolla komentoja yms. Voi hakea vapaalla sanahaulla. Esimerkiksi help.search("transpose") hakee tietokannasta komentoja, joiden help-tiedostossa esiintyy sana transpose. Ajamalle haku huomataan, että matriisin X transpoosi voidaan ottaa komennolla t(x). Muuta R:n käyttämiseen on runsaasti materiaalia olemassa mm. http://a-little-book-of-r-for-time-series.readthedocs.org/en/latest/ 2 / 10
Demotehtävät 1.1 Tiedostoon npaastot.txt on tallennettu tulokset tutkimuksesta, jossa on selvitetty ilman kosteuden (Humidity), lämpötilan (Temp) ja paineen (Pressure) vaikutuksia kuormaauton dieselmoottorin typpipäästöihin (NOx). a) Tutustu aineistoon estimoilalla aineistoa kuvaavia tunnuslukuja ja piirtämällä muuttujia kuvaavat histogrammit. Ovatko muutujat normaalijakautuneita? b) Estimoi lineaarinen malli, jossa typpipäästöjä selitetään muuttuujilla kosteus, lämpötila ja paine. c) Mikä on estimoidun mallin selitysaste? d) Testaa permutaatiotestillä, mitkä regressiokertoimet ovat merkitseviä. Toista permutointi 2000 kertaa. e) Poista selittäjät, jotka eivät ole merkitseviä ja estimoi lineaarinen malli. Suorita seuraavat kohdat ilman poistettuja selittäjiä. f) Laske regressiokertoimien keskihajonnat käyttämällä luentokalvojen kaavoja. g) Oletetaan, että normaalisuusoletus pätee. Laske regressiokertoimien 95% luottamusvälit komennolla confint(). h) Oletetaan, että normaalisuusoletus pätee. Toista (g) käyttämällä luentokalvojen kaavoja. i) Laske regressiokertoimien 95% luottamusvälit käyttämällä bootstrapping menetelmää ja vertaa tuloksia kohtiin (g) ja (h). Käytä bootstrap-estimoimisessa silmukkaa, jonka pituus on 2000. Piirrä myös histogrammit bootstrap-estimaateista. Ratkaisu. a) Ladataan tiedosto npaastot.txt työympäristöön. Lisäksi asetetaan seed(123), jotta saadaan vastaavat tulokset kuin malleissa. paastot=read.table("npaastot.txt", header=t, sep="\t") set.seed(123) Aineisto sisältää 5 muutujaa, ObsNo, NOx, Humidity, Temp ja Pressure. Aineiston tärkeimmät tunnusluvut saadaan komennolla summary() summary(paastot) ObsNo NOx Humidity Temp Pressure Min. : 1.00 Min. :0.6900 Min. : 33.85 Min. :65.44 Min. :28.87 1st Qu.: 5.75 1st Qu.:0.7175 1st Qu.: 77.94 1st Qu.:73.50 1st Qu.:29.03 Median :10.50 Median :0.7600 Median : 96.22 Median :77.82 Median :29.07 Mean :10.50 Mean :0.7910 Mean : 93.98 Mean :78.57 Mean :29.15 3rd Qu.:15.25 3rd Qu.:0.8275 3rd Qu.:111.55 3rd Qu.:86.03 3rd Qu.:29.16 Max. :20.00 Max. :1.0100 Max. :139.47 Max. :89.28 Max. :29.98 3 / 10
Histogrammit saadaan piirrettyä komennolla hist(paastot[,2]) tai hist(paastot[,"nox"]) Kuva 1: Histogrammi NOx-muuttujasta. hist(paastot[,"humidity"]) Kuva 2: Histogrammi Humidity-muuttujasta. 4 / 10
hist(paastot[,"temp"]) Kuva 3: Histogrammi Temp-muuttujasta. hist(paastot[,"pressure"]) Kuva 4: Histogrammi Pressure-muuttujasta. cor(paastot) ObsNo NOx Humidity Temp Pressure ObsNo 1.0000000-0.1260915 0.3686937 0.25908229-0.24143057 NOx -0.1260915 1.0000000-0.8729408 0.65591970 0.27825058 Humidity 0.3686937-0.8729408 1.0000000-0.47282672-0.27050695 Temp 0.2590823 0.6559197-0.4728267 1.00000000 0.02677886 Pressure -0.2414306 0.2782506-0.2705070 0.02677886 1.00000000 5 / 10
Muuttuja NOx korreloi negatiivisesti muuttujan Humidity kanssa ja positiivisesti muutujien Temp ja Pressure kanssa. Muuttujat eivät näytä normaalijakautuneilta. b) Usean muuttujan regressio hoituu R:ssä laittamalla oikealle puolelle selittäjät +-merkillä eroteltuna. sovite1 <- lm(nox~humidity+temp+pressure, data=paastot) summary(sovite1) Tämä tulostaa Call: lm(formula = NOx ~ Humidity + Temp + Pressure, data = paastot) Residuals: Min 1Q Median 3Q Max -0.061616-0.034795 0.003699 0.029233 0.077782 Coefficients: Estimate Std. Error t value Pr(> t ) (Intercept) -0.2707790 1.2538066-0.216 0.8317 Humidity -0.0025280 0.0004242-5.959 2e-05 *** Temp 0.0043960 0.0015320 2.869 0.0111 * Pressure 0.0327257 0.0418425 0.782 0.4456 --- Signif. codes: 0 *** 0.001 ** 0.01 * 0.05. 0.1 1 Residual standard error: 0.04249 on 16 degrees of freedom Multiple R-squared: 0.8441,Adjusted R-squared: 0.8149 F-statistic: 28.89 on 3 and 16 DF, p-value: 1.079e-06 c) Mallin selitysaste on 84,4%, mikä siis on luettu tulosteen kohdasta "Multiple R-squared". Vastaava saadaan myös varianssianalyysihajotelmalla. d) Koska muuttujat eivät ole normaalijakautuneita, on kyseenalaisita päätellä (b) kohdan taulukosta suoraan merkitsevät selittäjät. Permutoidaan selittävät muuttujat yksi kerrallaan ja katsotaan miten se vaikuttaa selitysasteen. k <- 2000 y.mean <- mean(paastot[,"nox"]) SST <- sum((paastot[,"nox"]-y.mean)^2) SSE <- sum((sovite1$res)^2) Rsquare1 <- 1-SSE/SST perm <- matrix(na,nrow =2000,ncol=3) for(i in 1:k){ tmp1 <- paastot tmp2 <- paastot tmp3 <- paastot 6 / 10
} tmp1$pressure <- sample(tmp1$pressure) tmp2$humidity <- sample(tmp2$humidity) tmp3$temp <- sample(tmp3$temp) tmpsovite1 <- lm(nox ~ Humidity+Temp+Pressure, data=tmp1) tmpsovite2 <- lm(nox ~ Humidity+Temp+Pressure, data=tmp2) tmpsovite3 <- lm(nox ~ Humidity+Temp+Pressure, data=tmp3) perm[i,1] <- summary(tmpsovite1)$r.squared perm[i,2] <- summary(tmpsovite2)$r.squared perm[i,3] <- summary(tmpsovite3)$r.squared pre <- 1-sum(perm[,1] < Rsquare1)/k #0.4635 hum <- 1-sum(perm[,2] < Rsquare1)/k #0 temp <- 1-sum(perm[,3] < Rsquare1)/k #0.0115 Muuttujat pre, hum ja temp on muodostettu siten, että ykkösestä on vähennetty se osuus permutaatioista, joissa selitysaste on pienentynyt. Huomaa, että seed:in vaihtaminen saattaa muuttaa tuloksia hieman. Kyseisest luvut ovat nähdään koodista kommentteina. Muuttujat kuvaavat nollahypoteesin (H 0 : regressiokerroin ei ole merkitsevä) p-arvoa (katso luentokalvot). Lukujen perusteella muutujan Pressure nollahypoteesi voidaan hyväksyä 5% merkitsevyystasolla ja täten poistetaan mallista. Muiden regressiokertoimien nollahypoteesit hylätään. Mallinvalintakriteereistä lisää ensi viikon harjoituksissa. e) sovite2=lm(nox~humidity+temp, data=paastot) summary(sovite2) Call: lm(formula = NOx ~ Humidity + Temp, data = paastot) Residuals: Min 1Q Median 3Q Max -0.065394-0.018456-0.001075 0.032302 0.072869 Coefficients: Estimate Std. Error t value Pr(> t ) (Intercept) 0.703544 0.140272 5.016 0.000106 *** Humidity -0.002625 0.000401-6.547 4.98e-06 *** Temp 0.004253 0.001504 2.829 0.011586 * --- Signif. codes: 0 *** 0.001 ** 0.01 * 0.05. 0.1 1 Residual standard error: 0.04201 on 17 degrees of freedom Multiple R-squared: 0.8382,Adjusted R-squared: 0.8191 F-statistic: 44.03 on 2 and 17 DF, p-value: 1.891e-07 7 / 10
f) Muodostetaan ensin uusi datamatriisi, josta on poistettu ylimääräiset selittäjät. Tehdään lisäksi tyypimuunnos data framesta matriisiksi (tiedostotyyppeistä lisää kurssilla Introduction to R-programming) ja lisätään sarake mallin vakiota (intercept) varten. tmp <- as.matrix(paastot[,c(3,4)]) n <- nrow(paastot) Intercept <- rep(1,n) paastot2 <- cbind(intercept,tmp) p <- ncol(paastot2) Lasketaan jäännösvarianssin harhaton estimaatti s 2 res <- sovite2$res s2 <- sum(res^2)/(n-p) Regressiokertoimien otosvarianssit ovat matriisin D 2 (b) = s 2 (X T X) 1 diagonaalialkioita, missä s 2 on jäännösvarianssin harhaton estimaattori. stdev <- sqrt(diag( s2*solve(t(paastot2)%*%paastot2))) Joka vastaa kohdan (e) taulukon arvoja g) confinterval <- confint(sovite2, level=0.95) Ja tuloste on: 2.5 % 97.5 % (Intercept) 0.407595872 0.999491779 Humidity -0.003471148-0.001779119 Temp 0.001080766 0.007425475 h) Vastaavat tulokset saadaan komennoilla coef <- sovite2$coef up <- coef + stdev * qt(0.975,n-p) down <- coef - stdev * qt(0.975,n-p) missä komento qt() antaa t-jakauman kvantiilin vapausasteella n p i) Luottamusvälit bootstrap-menetelmällä k <- 2000 bootmat <- matrix(na,nrow=k,ncol=3) X <- paastot2 set.seed(123) for(i in 1:k){ sovite3 <- lm(nox ~ Humidity + Temp, data=paastot) res.tmp <- sovite3$res res.boot <- sample(res.tmp,replace=true) yb <- sovite3$fitted.values + res.boot bb <- solve(t(x) % * %X) %*%t(x)%*%yb 8 / 10
bootmat[i,] <- bb } hist(bootmat[,1]) hist(bootmat[,2]) hist(bootmat[,3]) qconst <- quantile(bootmat[,1], probs = c(0.025,0.975)) qhum <- quantile(bootmat[,2], probs = c(0.025,0.975)) qtemp <- quantile(bootmat[,3], probs = c(0.025,0.975)) Kotitehtävät 1.2 Tiedostossa TUPAKKA.txt on annettu seuraavat tiedot 11 maasta: KULUTUS = Savukkeiden kulutus per capita vuonna 1930, SAIRAST = keuhkosyöpätapausten lukumäärä per 100 000 henkilöä vuonna 1950. Maat on numeroitu tiedostossa seuraavasti 1 = Islanti 7 = USA 2 = Norja 8 = Hollanti 3 = Ruotsi 9 = Sveitsi 4 = Kanada 10 =Suomi 5 = Tanska 11 =Englanti 6 = Itävalta Huomaa, että aineisto sisältää myös tämän tehtävän kannalta paljon ylimääräistä informaatiota. (a) Formuloi yhden selittäjän lineaarinen regressiomalli, jossa muuttujaa SAIRAST selitään muutujalla KULUTUS ja jossa on mukana vakio. (b) Estimoi mallin regressiokertoimet PNS-menetelmällä ja esitä tulkinnat estimoiduille regressiokertoimille. (c) Määrää estimoidun mallin selitysaste. (d) Onko malli tilastollisesti merkitsevä F -testin perusteella? Käytä testissä 1% merkitsevyystasoa. (e) Onko muuttujan KULUTUS regressiokerroin tilastollisesti merkitsevä t-testin perusteella? Vertaa testisuureen p-arvoa kohdassa (d) saatuun p-arvoon ja selitä niiden yhteys. (f) Piirrä estimoitu regressiosuora aineistoa kuvaavaan pistediagrammiin. (g) Selitä mitä tarkoitetaan käsitteellä luottamusväli. (h) Oleta normaalisuusoletuksen pätevän. Määrää kertoimien hajonnat sekä muodosta regressiosuoran kulmakertoimelle 95%:n luottamusväli. Mikä on 99%:n luottamusväli? Huomaa että luottamusväli on huomattavan leveä vakiotermille. Mistä tämä voisi johtua? 9 / 10
(i) Laske regressiokertoimien 95% luottamusväliä käyttämällä bootstrapping menetelmää (2000 toistoa). Vertaa tuloksia kohtaan (h). (j) Mitä etua bootstrapping menetelmästä on luottamusvälien laskemisessa suhteessa perinteiseen tapaan laskea luottamusvälit? 10 / 10