UPPSALA UNIVESITET Matematiska institutionen Jesper ydén Matematisk statistik 1MS026 vt 2014 DATOÖVNING MED : EGESSION I den här datorövningen studeras följande moment: Enkel linjär regression: skattning, diagnostik, prediktion Multipel regression: modellval, indikatorvariabler Exempel på transformation Spelet kan börja! 1 Enkel linjär regression Vi återvänder här till data om bilmodeller från laboration 1, ladda in data (som är inbyggt i ): data(mtcars); attach(mtcars) Enkel linjär regression utgår från ett samband av typen y i = β 0 + β 1 x i + ɛ i där β 0 och β 1 är regressionskoefficienter, (x i, y i ) är mätvärden och ɛ i N(0, σ 2 ). Låt oss först studera inverkan av bilars vikt på bränsleförbrukningen, dvs. y-värden återfinns som variabeln mpg, x-värden i wt. En plot över data ges av följande kommando: plot(mpg ~ wt, xlab = "Vikt", ylab="förbrukn") 1.1 Skattning av parametrar En i användbar rutin för regression är lm (förkortning för linear model, dvs linjär modell). Modellen formuleras med symbolisk notation enligt Wilkinson och ogers: y = β 0 + β 1 x 1 motsvaras av y x1 y = β 0 + β 1 x 1 + β 2 x 2 + β 3 x 1 x 2 motsvaras av y x1+x2+x1*x2 Anrop av lm ger upphov till en mängd information. En lagring av resultatet i m1 (modell 1) samt en sammanfattande utskrift i en tablå på skärmen kan ske med följande kommandon för våra aktuella variabler:
m1 <- lm(mpg ~ wt, mtcars) summary(m1) Identifiera från tablån förklaringsgrad, värden på koefficienter, signifikanta variabler. Om man enbart är intresserad av koefficienternas värde går det att få dessa genom coef(m1) Undersök även vad följande kommando utför: summary(m1)$coefficients[2,1] Man kan alltså komma åt numeriska värden som presenteras i tablån. Låt oss rita in den skattade linjen i den tidigare uppritade figuren med hjälp av följande kommando: abline(coef(m1), col="red") Titta i figuren och övertyga dig om att de skattade koefficienterna verkar rimliga vid jämförelse med de som finns i utskriften. Konfidensintervall för regressionskoefficienter I tablån i levereras direkt medelfelen för skattningarna (standard error). För att därefter beräkna ett konfidensintervall för exempelvis β 1 behövs lämplig t-kvantil, vilken erhålls med kommandot qt. # Förberedelser: beta1 <- summary(m1)$coefficients[2,1] medfel <- summary(m1)$coefficients[2,2] f <- m1$df.res # Frihetsgrader kvantil <- qt(0.975,f) # Intervallet: c(beta1 - kvantil*medfel, beta1 + kvantil*medfel) En andra ordningens modell Antag att vi vill införa en andra ordningens modell (en kvadratisk term). Studera den ursprungliga plotten och övertyga dig om att det kan vara tänkbart. Följande kommandon anpassar en kvadratisk modell: mqua <- lm(mpg ~ wt + I(wt^2), mtcars); summary(mqua) Studera förändringen i förklaringsgrad jämfört med modellen m1. Betrakta även förändringarna i justerad förklaringsgrad.
1.2 Studium av modell residualer m.m. Slumpens inverkan studeras genom analys av residualerna. Dessa kan extraheras genom residuals(m1) En bild säger mer än tusen ord; låt oss först rita upp sekvensen av residualerna. (De är naturligtvis lika många som antalet observationer.) plot(residuals(m1)) Fundera över: 1. Kan residualerna anses ha väntevärde 0? (Titta i figuren, använd eventuellt mean för att beräkna stickprovsmedelvärde.) 2. Är de oberoende dvs. inga mönster uppträder? För att grovt kontrollera modellantagandet om normalfördelade residualer kan vi rita ett histogram och iakttaga spridningen: hist(residuals(m1)) Ett anrop av qqnorm kan även vara på sin plats. Vi har här relativt få observationer; det är inte lätt att dra någon säker slutsats. Extrahera designmatris Givet en modell från ett anrop av lm, kan den s.k. designmatrisen erhållas, dvs X i den vanliga matrisformuleringen y = Xβ. Följande kommandosekvens extraherar matrisen och beräknar sedan (X T X) 1, en matris som ju förekommer flitigt i regressionssammanhang. X <- model.matrix(m1); solve( t(x) %*% X ) UPPGIFT. Beräkna V[ ˆβ 0 ] genom att dels utnyttja lämpligt element i matrisen (X T X) 1, dels den skattade residualvariansen (hitta den i tablån). Kontrollera ditt svar genom att jämföra med vad som presenteras direkt i tablån (dock där i form av medelfel, standard error). Figurer för diagnostik Här kan vi dels rita olika residualer genom eget manipulerande och utnyttjande av definitioner, dels använda en färdig presentation i. Om man vill styra själv vad som ska ritas kan man exempelvis göra som följer (fyra figurer i en, men givetvis kan man även rita varje figur var för sig): par(mfrow=c(2,2)) # Sekvens av residualer plot(residuals(m1)) # esidualer mot yhat-värden
plot(m1$fit,m1$res) # Studentiserade residualer plot(rstudent(m1)) # Cook s distance plot(cooks.distance(m1)) En och annan punkt verkar ha inflytande att döma av Cook s distance. Kommandot identify, se nedan, kan användas för att identifiera vilken bilmodell det handlar om. Ett hårkors kommer att dyka upp i figuren; klicka med vänster musknapp över intressanta punkter. Avsluta genom att klicka med mellanliggande (eller höger) musknapp. car.models <- row.names(mtcars) identify(1:32,cooks.distance(m1),car.models) Om endast numret på observationen är av intresse, utelämna car.models i anropet av identify. Givet ett objekt resulterande från användning av lm, t.ex. m1 i vårt aktuella fall, kan erbjuda en kavalkad av figurer för diagnostik av residualer. Man skriver helt enkelt plot(m1) Genom att trycka på Enter stegar man sig fram mellan figurerna. 1.3 Prediktion Med en resulterande modell från rutinen lm kan prediktion enkelt utföras: predict(m1,mtcars) Jämför de predikterade värdena med de ursprungliga. Prediktionsintervall kan erhållas genom att lägga till predict(m1, mtcars, interval="prediction") Antag nu att vi vill prediktera för godtyckliga vikter (samlade i en vektor) och vill åskådliggöra resultatet i en figur. Vi passar på att rita såväl konfidensband (för linjen själv) som prediktionsband (för framtida observation). attach(mtcars) # Sekvens av värden på ober. var. för vilka prediktion ska göras pred.frame <- data.frame(wt=seq(1.5,5.5,0.5)) # Beräkning av prediktions- resp. konfidensintervall pp <- predict(m1, int="p", newdata = pred.frame) pc <- predict(m1, int="c", newdata = pred.frame) # Grafik (lite trixande, användning av kommandot matlines) plot(wt,mpg,ylim=range(mpg,pp,na.rm=t)) pred.mpg <- pred.frame$wt matlines(pred.mpg,pc,lty=c(1,2,2),col="blue") matlines(pred.mpg,pp,lty=c(1,3,3),col="black") Notera att prediktionsintervallen är vidare, större osäkerhet.
2 Multipel regression Vi använder oss nu av ytterligare en förklarande variabel: motorstyrkan (hp). Ett anrop med lm och därtill hörande lagring i modellen m2 lyder nu m2 <- lm(mpg ~ wt + hp); summary(m2) Tag fram matrisen X i den vanliga matrisformuleringen y = Xβ med kommandot model.matrix. Undersök gärna residualer osv. precis som ovan, utgå från m2. Jämför förklaringsgraden i m1 med den i m2. Som förväntat? Prediktion: Antag att vi vill förutsäga förbrukningen för en ny, rätt tung bil med förhållandevis liten motor: wt= 3.5, hp= 90. Kommandon: x0 <- data.frame(wt=3.5,hp=90) yhat <- predict(m2,x0) UPPGIFT. Pröva något eget exempel med prediktion för en tänkt bilmodell och jämför med värdena för de befintliga bilmodellerna! 3 Indikatorvariabler och modellval Vi studerar användandet genom ett exempel. En ingenjör vill modellera den förväntade tiden E[Y ] per månad (i timmar) för pga. reparationsarbeten avstängda maskiner som funktion av de förklarande variablerna maskintyp (1 eller 2) samt maskinens ålder (i år). Följande modell föreslås: E[Y ] = β 0 + β 1 x 1 + β 2 x 2 1 + β 3 x 2 där x 1 är maskinens ålder, x 2 maskintyp (x = 1: Typ 1, x = 0, Typ 2). I filen shutdown.dat finns dat insamlat. Spara data i lämplig katalog, läs in i och titta på datas struktur: mask <- read.table("shutdown.dat") mask str(mask) attach(mask) Identifiera de olika variablerna, notera indikatorvariablerna V3 och V4. (a) Skattning av parametrar: mask0 <- lm(v1 ~ V2 + I(V2^2) + V4) summary(mask0) Verkar modellen rimlig? Vilka variabler är signifikanta i regressionsmodellen?
(b) Man vill nu testa den enklare modellen där β 1 = β 2 = 0 (på nivån α = 0.10). Mer specifikt formulerat, H 0 : β 1 = β 2 = 0 H 1 : Minst ett β i 0, i = 1, 2. Med beteckningar från kompendiet i regressionsanalys är då storheten w = Q (1) Q (2) Q(2) /p /(n k p 1) av intresse; man har W F (p, n k p 1). Kvadratsumman Q (1) den mindre modellen, Q (2) till den kompletta. Vi anpassar först den enklare modellen och sparar under namnet mask1: mask1 <- lm(v1 ~ V4) summary(mask1) härrör till Det går att extrahera kvadratsummorna från respektive modell genom att visa modellerna i s.k. ANOVA-tablå och utifrån dessa göra tilldelningar. Därefter kan värdet på w beräknas: anova(mask0) anova(mask1) Q1 <- anova(mask1)$sum[2] Q2 <- anova(mask0)$sum[4] w <- ( (Q1-Q2)/(3-1) )/ ( Q2/(20-1-2-1) ) wcrit <- qf(0.90,3-1,20-1-2-1) w > wcrit Det observerade värdet på teststorheten är större än kvantilen från F -fördelningen. Det finns statistiskt belägg för att maskintyp bidrar till modellen på nivå α = 0.10. Sammanfattningsvis, efter att ha justerat för maskintyp finns det belägg för att reparationstiden beror av ålder. 4 Transformationer I många sammanhang görs transformationer. Vi ska här närmare studera effekten på hållfastheten hos grönsaker (tänk er morötter) efter att dessa blivit upphettade ( skållade ) under en viss tid. Sådana experiment har betydelse för studier av förpackningsstrategier i livsmedelsteknik. Data härstammar från ett försök gjort i Belgien. Temperaturen hölls fix (90 C), tiden för upphettning mättes i sekunder och kraften i N. Vi läser in data och ritar hållfastheten som funktion av längden på upphettningen. Även en figur med logaritmerad hållfasthet på ordinatan ritas:
skalla <- read.table("skalla.dat", col.names=c("temp","tid","hallf") ) attach(skalla) plot(hallf~tid) plot(log(hallf)~tid) Inser du att logaritmeringen av beroende variabel kan leda dels till en bättre linjär relation, dels mer homogen varians? egressionsmodeller estimeras som vanligt: m3 <- lm(hallf ~ Tid) m4 <- lm(log(hallf) ~ Tid) Betrakta resultatet av regressionen: signifikanta variabler, förklaringsgrad, etc. Fortsättningsvis arbetar vi med logaritmerad beroende variabel. (Om du har tid: använd gärna rutinen boxcox (glöm inte att först skriva library(mass)) för att övertyga dig om att logaritmering verkar vara en bra idé.)