regression_multiple

index

Multiple Regression

Beispiel: Everitt (2010) car cleaning data

Daten einlesen, erster grafischer Eindruck
# Daten einlesen
car.data <- read.delim("http://www.psych.uni-goettingen.de/de/mat/mv/everitt-car-data.txt")

# variablen direkt in namespace holen
attach(car.data)

# einen Eindruck der Daten bekommen (erste 10 Zeilen)
car.data[1:10,]

# eine Korrelationsmatrix
cor(car.data)

# ein erster grafischer Überblick (Fig 4.1)
# pairs erzeugt multiple scatterplots
# panel legt den Inhalt der einzelnen Fenster fest
# text trägt die Werte in der Spalte sex an die jeweils geplotteten x-y-Koordinaten aus den übergebenen Matrix-Spalten
# die 0 und 1 zeigen die Lage der verschiedenen AVen für Frauen bzw Männer
pairs(cbind(time,age,extro),panel=function(x,y) text(x,y,sex))

mr 1

Linear Model spezifizieren, Anpassung rechnen lassen
# mit den drei Prädiktoren sex, age und extro
# Kurzergebnis ausgeben lassen
summary(lm(time~sex+age+extro))

# Summary zwei Prädiktoren sex, extro
summary(lm(time~sex+extro))


# ergibt output

Call:
lm(formula = time ~ sex + extro)

Residuals:
    Min      1Q  Median      3Q     Max 
-26.193  -9.474  -2.149  10.165  23.918 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  15.6797     4.4365   3.534 0.001118 ** 
sex          19.1801     4.4727   4.288 0.000124 ***
extro         0.5093     0.1151   4.423 8.24e-05 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 

Residual standard error: 12.95 on 37 degrees of freedom
Multiple R-squared: 0.632,	Adjusted R-squared: 0.6121 
F-statistic: 31.77 on 2 and 37 DF,  p-value: 9.284e-09 

# Omnibus F-Test (F-statistic) prüft Hyp., dass alle Regressionskoeffizienten gleich 0 sind.
# bzw. ob durch die Vorhersage-Linearkombination ein signifikanter Anteil der Varianz am Kriterium erklärt wird.
# Multiple R-squared: Anteil der Varianz des Kriteriums, der durch die Kombination der Prädiktoren gebunden/erklärt wird.
# Adjusted R-squared: rechnet R-squared so um, dass die Anzahl der erklärenden Terme im Modell berücksichtigt wird.
#  adjusted R-squared steigt im Gegensatz zu R-squared nur, wenn der neue Term das Modell um mehr als durch Zufall erwartet verbessert.
#  adjusted R-squared kann negativ sein und ist immer <= R-squared. 

p Anzahl der Regressore im linear Model (ohne constant), n ist sample-size.

# unter Coefficients finden sich die unstandardisierten Beta-Gewichte mit ihrem Standardfehler sowie ein T-Test zur Prüfung des Einzeleffekts
# (t-Werte sind Estimate / Std. Error)
Vorhersage eines einzelnen Kriteriumswertes (Vp 3) mit Prädiktor sex und extero (zu Fuß)
# lm-Objekt speichern
m.lm <- lm(time~sex+extro)
# Summary-Objekt speichern
s.lm <- summary(m.lm)
# was gibt es im Summary-Objekt?
names(s.lm)
# nur die Koeffizienten brauchen wir
koeff <- s.lm$coefficients[,1]
# Vp 3 Vorhersagewert (fitted value) berechnen
e.time.3 <- koeff['(Intercept)'] + koeff['sex'] * sex[3] + koeff['extro'] * extro[3]
e.time.3
# Vorhersagewerte finden sich im lm-Objekt unter fitted.values
m.lm$fitted.values
# müßte gleich sein dem 3. Wert in den Vorhersagewerten
m.lm$fitted.values[3]

Vorhergesagte Werte mit predict

predict(m.lm)
Standardisierte Beta-Gewichte sind vergleichbarer
 
# Standardisierte Beta-Gewichte:
# Vars standardisieren
car.data['st.sex'] <- car.data$sex / sd(car.data$sex)
car.data['st.age'] <- car.data$age / sd(car.data$age)
car.data['st.extro'] <- car.data$extro / sd(car.data$extro)
car.data['st.time'] <- car.data$time / sd(car.data$time)

# vergleichende Summaries

# unstandardisiert
summary(lm(car.data$time~car.data$sex+car.data$extro))

# Prädiktoren standardisiert
summary(lm(car.data$time~car.data$st.sex+car.data$st.extro))

# Kriterium und Prädiktoren standardisiert
summary(lm(car.data$st.time~car.data$st.sex+car.data$st.extro))


# Alternative: scale() benutzen und die Standardisierng 'on the fly' machen anstelle eine neue Variable zu bilden
summary(lm(scale(car.data$time) ~ scale(car.data$sex) + scale(car.data$extro)))

# Alternative: standardisierte Regressionskoeffizienten aus den unstandardisieren errechnen

# standardisierte Regressionskoeffizienten lassen sich auch einfach ausrechnen
# raw-coeffizient(predictor) * sd(predictor) / sd(criterion)
# das unstandardisierte Modell speichern
ureg <- lm(car.data$time~car.data$sex+car.data$extro)

# die standardisierten Regressionskoeffizienten berechnen und ausgeben
ureg$coefficients['car.data$sex'] * sd(car.data$sex) / sd(car.data$time)
ureg$coefficients['car.data$extro'] * sd(car.data$extro) / sd(car.data$time)


Einen Scatterplot erstellen mit den beiden Regressionsgeraden für das jeweilige Geschlecht
#Fig 4.2
# vergleichend die beiden Regressionsgeraden für Männer und Frauen
# Grafikumgebung zurücksetzen
par(mfrow=c(1,1))
# einen Vektor mit 'm' für Maänner und 'f' für Frauen erstellen 
Sex<-rep("m",length(sex))
Sex[sex==0]<-"f"
# einen Vektor mit 50 Elementen erstellen die in regelmäßigen Abständen zwischen 0 und 90 liegen
x<-seq(0,90,length=50)
# die Geradengleichungen mit derselben Steigung und verschiedenem Y-Achsenabschnitt
ym<-15.68+19.18+0.51*x
yf<-15.68+0.51*x
# und nun der plot
plot(car.data$time ~ car.data$extro,			# plotte Grundmodell
 xlab="Extroversion score",						# X-Achsen-Beschriftung
 ylab="Time spent looking after car (mins)",type="n") # Y-Achsen-Beschriftung
 text(car.data$extro,car.data$time,labels=Sex)	# an die Koordinaten den Text (Buchstaben) ausgeben
 lines(x,ym,lty=1)	# Regressionsgerade für Männer einzeichnen, Linienart festlegen
 lines(x,yf,lty=2)	# dito für Frauen
 legend("topleft",c("Male","Female"),	# eine Legende in die linke, obere Ecke
 	lty=1:2)	# zugeordneter Linientyp in der Legende, der dem der Regressionsgeraden entspricht

mr 2

Wechselwirkungsterm mit in MR einbeziehen
# Daten vorbereiten
time  <- car.data$time
sex   <- car.data$sex
extro <- car.data$extro

# das Modell anpassen und Summary ausgeben
rr <- lm(time~sex+extro+sex:extro)
summary(rr)

# ergibt output
Call:
lm(formula = time ~ sex + extro + sex:extro)

Residuals:
    Min      1Q  Median      3Q     Max 
-24.807  -9.445  -1.677  10.477  27.183 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  20.0182     5.4560   3.669 0.000782 ***
sex           7.8178     9.5705   0.817 0.419379    
extro         0.3607     0.1590   2.268 0.029430 *  
sex:extro     0.3052     0.2279   1.339 0.188970    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 

Residual standard error: 12.81 on 36 degrees of freedom
Multiple R-squared: 0.6495,	Adjusted R-squared: 0.6203 
F-statistic: 22.23 on 3 and 36 DF,  p-value: 2.548e-08 

# Alternativ kann dasselbe Modell angepasst werden, 
# indem ein neuer Prädiktor aus dem Produkt der alten berechnet und in das Modell mit eingefügt wird 
mult.sex.extro <- sex * extro

rr2 <- lm(time ~ sex + extro + mult.sex.extro)
summary(rr2)


#Fig 4.3
# Abbildung die zusätzlich noch die Wechselwirkung mit einbezieht

# Grafik vorbereiten
Sex<-rep("m",length(sex))
Sex[sex==0]<-"f"
x<-seq(0,90,length=50)
# für Männer ist x = 1
#ym<-20+7.82+(0.36+0.31)*x
# eine Gerade über den Wertebereich von x mit 1
ym <- rr$coefficients['(Intercept)'] + rr$coefficients['sex'] * 1 + (rr$coefficients['extro'] * 1 + rr$coefficients['sex:extro'] * 1) * x
# für Frauen ist x = 0
# yf<-20+0.36*x
yf <- rr$coefficients['(Intercept)'] + rr$coefficients['sex'] * 0 + (rr$coefficients['extro'] * 1 + rr$coefficients['sex:extro'] * 0) * x
plot(time~extro,xlab="Extroversion score",
ylab="Time spent looking after car (mins)",type="n")
text(extro,time,labels=Sex)
lines(x,ym,lty=1)
lines(x,yf,lty=2)
legend("topleft",c("Male","Female"),lty=1:2)

mr 3

Prüfung auf Multikollinearität und Prädiktorenselektion mit Course-Data

# Daten einlesen
course.data <- read.delim("http://www.psych.uni-goettingen.de/de/mat/mv/course-data.txt")
# und die Spalten in den Namespace holen
attach(course.data)

# ein Einblick in die Struktur des Data.Frames
course.data[1:10,]

# ein erster grafischer Überblick
pairs(course.data)
# oder
plot(course.data)

mr 5

Kontrolle auf Probleme mit Multikollinearität mit dem VIF (Variance Inflation Factor). VIF wird gebildet aus der multiplen Korrelation eines Prädiktors mit dem Rest der Prädiktoren. Daumenregel: Wenn der VIF 10 überschreitet gibt es Probleme mit Kollinearität im Pool der Prädiktoren.

Der VIF kann leicht errechnet werden, indem man die Restprädiktoren in ein 'lm' steckt als Prädiktoren und den relevanten Prädiktor als Kriterium. Das multiple R^2 finet man im Summary.
Die Formel für VIF ist 1 / (1 - R^2)

vif.teach     <- 1 /(1 - summary(lm(teach     ~         exam + knowledge + grade + enroll))$r.squared)
vif.teach     
vif.exam      <- 1 /(1 - summary(lm(exam      ~ teach        + knowledge + grade + enroll))$r.squared)
vif.exam      
vif.knowledge <- 1 /(1 - summary(lm(knowledge ~ teach + exam             + grade + enroll))$r.squared)
vif.knowledge 
vif.grade     <- 1 /(1 - summary(lm(grade     ~ teach + exam + knowledge         + enroll))$r.squared)
vif.grade     
vif.enroll    <- 1 /(1 - summary(lm(enroll    ~ teach + exam + knowledge + grade         ))$r.squared)
vif.enroll    


Jede Änderung an den Prädiktoren bzw. den Vpn verändert das Gesamtgefüge und erfordert eine Neuanpassung des Modells. Das gilt bei der Herausnahme oder beim Hinzufügen eines einzigen Prädiktors oder natürlich einer Gruppe. Entscheidungen über das weitere Vorgehen müssen bei jedem Einzelschritt durch Neuanpassung überprüft werden.

forward: Anfangen mit dem Prädiktor mit der höchsten Einzelkorrelation, dann je den vielversprechendsten Prädiktor neu mit aufnehmen

backward: Anfangen mit allen Prädiktoren und dann den je 'schwächsten' aus dem Modell nehmen.

stepwise: Kombination: Schrittweise hinzunehmen und dann prüfen, ob aus den bereits integrierten Variablen sich eine als nicht mehr bedeutsam erweist.

AIC: Akaike's information criterion.
AIC 'bestraft' die Hinzunahme von Variablen, rechnet aber deren zusätzlichen Erklärungswert gegen. Frage, die das AIC beantwortet: Wie ist der Verlust an Erklärung im Vergleich mit dem Gewinn durch ein sparsameres Modell?
Kriterium: AIC soll kleiner werden (auch im Minus-Bereich)

# Backward regression
# volles Modell generieren
reg<-lm(overall~teach+exam+knosuwledge+grade+enroll)

# backward
step(reg, direction="backward")

# Kriterium: AIC soll kleiner werden (auch im Minus-Bereich)

# 'step' kann auch 'forward' und 'both'

Beurteilung einzelner Fälle, standardized residuals, deletion-residuals, leverage und Cook's-distance

Leverage

lever <- hatvalues(m.lm)

 

Cook's distance: Einfluss eines Falles auf die Parameterschätzung des Gesamtmodells. Ein Wert größer 1 heisst, dass diese Beobachtung einen unverhältnismäßig großen Einfluss hat (Empfehlung Everitt, 2010).
Die Funktion cooks.distance(), der das lineare Modell übergeben wird, liefert die cook's distance für die Beobachtungen zurück.
Ein plot() des Modells liefert mehrere Grafiken u. a. verschiedene Residual-Plots sowie einen Plot der die Cook's Distance visualisiert

mr 1

mr 2

mr 3

mr 5