Probleme Linearer Regression
Auf dieser Seite findest du Übungen zur Bewältigung von Kollinearitätsproblemen in R.
Der gesamte Code, den du hier findest, kann von dir 1:1 in R umgesetzt werden. Die größte Lernwirkung hat diese Einführung, wenn du möglichst alles einmal selbst in R durchführst.
01 Vorbereitungen
Bevor wir loslegen können, müssen wir die Packages laden, die wir für unser Vorhaben benötigen. Zunächst ist das nur das SfL
Package. Falls du dieses noch nicht geladen hast, hole dies nun nach:
library(SfL)
Nun laden wir die Datensätze, die wir nutzen werden:
data(data_a)
data(data_c)
data(data_s)
data(data_t)
data(data_v)
02 Feststellung Problematischer Korrelation
Je mehr Variablen in einem Regressionsmodell berücksichtigt werden sollen, desto höher ist die Wahrscheinlichkeit, dass einige dieser Variablen stark miteinander korreliert sind. Da Korrelation zwischen Prediktorvariablen zu Kollinearität in linearen Modellen führt, und solche Kollinearität zur Zuverlässigkeit solcher Modelle signifikant verschlechtert, muss dieses Problem unbedingt berücksichtigt werden.
Hierzu muss zunächst überprüft werden, welche Variablen miteinander korreliert sind. Dies funktioniert z.B. mit folgendem Befehl aus dem SfL
Package:
library(SfL)
correlation_matrix(data = data_s,
variables = c("baseDurLog", "speakingRate", "googleFreq",
"age", "speaker", "typeOfS", "folSeg", "folType", "item", "transcription", "biphoneProbSum", "biphoneProbSumBin", "monoMultilingual", "pauseBin", "preC"))
Betrachten wir die Korrelationskoeffizienten näher, finden wir folgende problematische Fälle:
folSeg
vs.folType
biphoneProbSumBin
vs.biphoneProbSum
biphoneProbSumBin
vs.item
biphoneProbSumBin
vs.transcriptions
biphoneProbSum
vs.item
biphoneProbSum
vs.transcription
item
vs.transcription
03 Vergleich und Ausschluss
Idee: Die stark korrelierten Variablen werden in simple Modelle eingesetzt und diese dann vergliechen. Die Variable mit der jeweils größeren Vorhersagekraft wird behalten.
Potentielles Problem: Der Verlust von Variablen kann einem Verlust an Vorhersagekraft entsprechen.
Vorgehen: Mit der predictor_competition()
Funktion des SfL
Packages kann herausgefunden werden, welche Variable der jeweils bessere Prediktor ist. Alternativ kann dieses Vorgehen auch manuell durchgeführt werden.
Schritt 1
folSeg
vs. folType
predictor_competition(data = data_s,
dependent = "sDurLog",
independent1 = "folSeg",
independent2 = "folType")
Analysis of Variance Table
Model 1: sDurLog ~ folSeg
Model 2: sDurLog ~ folType
Res.Df RSS Df Sum of Sq F Pr(>F)
1 135 22.221
2 145 24.453 -10 -2.2321 1.356 0.2074
Wie vom Output angedeutet, sind beide Variablen gleich gute Prediktoren. In diesem Fall können wir wählen, welchen wir für die weitere Analyse behalten möchten.
Wir behalten folType
. Weitere Vergleiche mit folSeg
entfallen.
Schritt 2
biphoneProbSumBin
vs. biphoneProbSum
predictor_competition(data = data_s,
dependent = "sDurLog",
independent1 = "biphoneProbSumBin",
independent2 = "biphoneProbSum")
Analysis of Variance Table
Model 1: sDurLog ~ biphoneProbSumBin
Model 2: sDurLog ~ biphoneProbSum
Res.Df RSS Df Sum of Sq F Pr(>F)
1 148 24.264
2 148 23.937 0 0.32695
Wie vom Output angedeutet, sind beide Variablen gleich gute Prediktoren. In diesem Fall können wir wählen, welchen wir für die weitere Analyse behalten möchten.
Wir behalten biphoneProbSumBin
. Weitere Vergleiche mit biphoneProbSum
entfallen.
Schritt 3
item
vs. transcription
predictor_competition(data = data_s,
dependent = "sDurLog",
independent1 = "item",
independent2 = "transcription")
Analysis of Variance Table
Model 1: sDurLog ~ item
Model 2: sDurLog ~ transcription
Res.Df RSS Df Sum of Sq F Pr(>F)
1 105 16.919
2 114 19.843 -9 -2.9244 2.0165 0.04442 *
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Wie vom Output angedeutet, ist eine Variable ein besserer Prediktor als die andere Variable. Anhand des RSS-Wertes stellen wir fest, die bessere Prediktorvariable ist item
.
Weitere Vergleiche mit transcription
entfallen.
Schritt 4
biphoneProbSumBin
vs. item
predictor_competition(data = data_s,
dependent = "sDurLog",
independent1 = "biphoneProbSumBin",
independent2 = "item")
Analysis of Variance Table
Model 1: sDurLog ~ biphoneProbSumBin
Model 2: sDurLog ~ item
Res.Df RSS Df Sum of Sq F Pr(>F)
1 148 24.264
2 105 16.919 43 7.3446 1.06 0.3961
Wie vom Output angedeutet, sind beide Variablen gleich gute Prediktoren. In diesem Fall können wir wählen, welchen wir für die weitere Analyse behalten möchten.
Wir behalten item
. Weitere Vergleiche mit biphoneProbSumBin
entfallen.
Weiteres Vorgehen
Mit den Gewinnern der vorherigen Schritte sowie den Variablen, die keine problematischen Korrelationskoeffizienten gezeigt haben, können nun regulär lineare Modelle erstellt werden. Zum Beispiel:
<- lm(sDurLog ~
mdl + # Gewinner
folType + # Gewinner
item + # alle weiteren Variablen
baseDurLog +
speakingRateLog +
googleFreqLog +
age +
speaker +
typeOfS +
monoMultilingual +
pauseBin
preC,data = data_s)
04 Principal Component Analysis
Möchten wir nach Möglichkeit keine Vielzahl von Variablen verlieren, können wir eine PCA durchführen. Allerdings funktionieren diese nur beschränkt gut bei kategorischen Variablen. Daher wird im folgenden Verlauf auf ein fiktives Beispiel mit rein numerischen Variablen gesetzt.
Zunächst werden die Beispieldaten erstellt:
<- rbind(c(1,-0.8,-0.7), c(-0.8,1, 0.9), c(-0.7,0.9,1))
sigma <- c(10, 5, 2)
mu <- as.data.frame(mvrnorm(n=1000, mu=mu, Sigma=sigma))
df1
<- rbind(c(1,-0.8,-0.7), c(-0.8,1, 0.9), c(-0.7,0.9,1))
sigma <- c(9, 4, 1)
mu <- as.data.frame(mvrnorm(n=1000, mu=mu, Sigma=sigma))
df2
<- rbind(c(1,-0.8,-0.7), c(-0.8,1, 0.9), c(-0.7,0.9,1))
sigma <- c(11, 6, 3)
mu <- as.data.frame(mvrnorm(n=1000, mu=mu, Sigma=sigma))
df3
<- cbind(df1, df2, df3)
df
colnames(df) <- c("var1", "var2", "var3", "var4", "var5", "var6", "var7", "var8", "var9")
Bitte beachte, dass du beim Umsetzen der PCA minimal andere Ergebnisse erhalten wirst, da die hier erstellten Variablen zufällige Werte enthalten. Die einzelnen Schritte beeinflusst das nicht.
Schritt 1
Zuerst wird ein Data Frame erstellt, der nur die Variablen enthält, die problematische Korrelationen aufweisen. Dafür müssen wir zunächst die Korrelationen überprüfen:
correlation_matrix(df)
Offenbar ist jede Variable mit mindestens einer anderen Variable stark korreliert. Daher müssen wir keinen neuen Data Frame erstellen, sondern können den jetzigen für weitere Schritte nutzen.
Schritt 2
Mit der PCA Funktion von R - pc()
- berechnen wir die PCA:
<- princomp(df, cor=TRUE, score=TRUE) pc
Schritt 3
Als nächstes können wir uns die Eigenvalues der neu erstellten Variablen anschauen. Hierzu nutzen wir das factoextra
Package.
install.packages("factoextra")
library("factoextra")
get_eigenvalue(pc)
eigenvalue variance.percent cumulative.variance.percent
Dim.1 2.64833838 29.4259820 29.42598
Dim.2 2.62724036 29.1915596 58.61754
Dim.3 2.53887662 28.2097402 86.82728
Dim.4 0.33286865 3.6985406 90.52582
Dim.5 0.30974824 3.4416471 93.96747
Dim.6 0.28595582 3.1772869 97.14476
Dim.7 0.09197875 1.0219862 98.16674
Dim.8 0.08800664 0.9778515 99.14459
Dim.9 0.07698653 0.8554059 100.00000
Je höher die Eigenvalue einer neuen Variable - hier Dim.x genannt - desto mehr Varianz kann diese Variable in den Daten erklären.
Schritt 4
Anhand üblicher Kriterien muss nun entschieden werden, welche der neuen Variablen für weitere Analysen behalten werden.
Kriterium 1
Die Eigenvalue einer Variable muss mindestens 1 betragen, da eine Variable mit Eigenvalue 1 mindestens sich selbst erklären kann.
get_eigenvalue(pc)
eigenvalue variance.percent cumulative.variance.percent
Dim.1 2.64833838 29.4259820 29.42598
Dim.2 2.62724036 29.1915596 58.61754
Dim.3 2.53887662 28.2097402 86.82728
Dim.4 0.33286865 3.6985406 90.52582
Dim.5 0.30974824 3.4416471 93.96747
Dim.6 0.28595582 3.1772869 97.14476
Dim.7 0.09197875 1.0219862 98.16674
Dim.8 0.08800664 0.9778515 99.14459
Dim.9 0.07698653 0.8554059 100.00000
Die folgenden PCA Components erfüllen das Kriterium: Dim.1
, Dim.2
, Dim.3
Kriterium 2
Die ‚cumulative variance explained‘ der neuen Variablen sollte mindestens 70 % betragen.
get_eigenvalue(pc)
eigenvalue variance.percent cumulative.variance.percent
Dim.1 2.64833838 29.4259820 29.42598
Dim.2 2.62724036 29.1915596 58.61754
Dim.3 2.53887662 28.2097402 86.82728
Dim.4 0.33286865 3.6985406 90.52582
Dim.5 0.30974824 3.4416471 93.96747
Dim.6 0.28595582 3.1772869 97.14476
Dim.7 0.09197875 1.0219862 98.16674
Dim.8 0.08800664 0.9778515 99.14459
Dim.9 0.07698653 0.8554059 100.00000
Die folgenden PCA Components erfüllen das Kriterium: Dim.1
, Dim.2
, Dim.3
Kriterium 3
Es sollte keine großen Unterschiede zwischen den Eigenvalues der neuen Variablen geben.
get_eigenvalue(pc)
eigenvalue variance.percent cumulative.variance.percent
Dim.1 2.64833838 29.4259820 29.42598
Dim.2 2.62724036 29.1915596 58.61754
Dim.3 2.53887662 28.2097402 86.82728
Dim.4 0.33286865 3.6985406 90.52582
Dim.5 0.30974824 3.4416471 93.96747
Dim.6 0.28595582 3.1772869 97.14476
Dim.7 0.09197875 1.0219862 98.16674
Dim.8 0.08800664 0.9778515 99.14459
Dim.9 0.07698653 0.8554059 100.00000
Die folgenden PCA Components erfüllen das Kriterium: Dim.1
, Dim.2
, Dim.3
Kriterium 4
Neue Variablen sind nur hilfreich, wenn sie auch interpretierbar sind. Obwohl es sich hier um fiktive Variablen handelt, können wir dieses Kriterium heranziehen. Components, die “ein bisschen von allem” in ihren Loadings enthalten, sind nicht interpretierbar. Enthalten Components allerdings große Anteile einiger bestimmter Variablen, sind die i.d.R. interpretierbar.
$loadings[,1:3] pc
Comp.1 Comp.2 Comp.3
var1 0.2383359 0.40961666 0.2877117
var2 -0.2595344 -0.45275418 -0.2968547
var3 -0.2635848 -0.42026070 -0.2935514
var4 0.1430101 -0.36227606 0.3882110
var5 -0.1440861 0.38539583 -0.4389340
var6 -0.1408366 0.36496130 -0.4273685
var7 0.4807232 -0.09797024 -0.2606992
var8 -0.5118988 0.12084916 0.2837557
var9 -0.5021733 0.11591147 0.2615927
Die folgenden PCA Components erfüllen das Kriterium: Dim.1
, Dim.2
, Dim.3
Entscheidung
Nach allen Kriterien sind folgende Components als neue Variablen zu behalten: Dim.1
, Dim.2
, Dim.3
Schritt 5
Nun müssen die Variablen, die behalten werden, extrahiert werden:
<- as.data.frame(pc$scores)[1:3] pcframe
Bei einem echten Anwendungsfall würde man diese als zusätzliche Spalten zum eigentlichen Data Frame hinzufügen, damit sie im weiteren Analyseprozess zur Verfügung stehen.
Schritt 6
Nun steht die Interpretation der neuen Variablen an. In Schritt 4 haben wir die Loadings der einzelnen Components schon kurz gesehen. Hier schauen wir uns diese nun im Detail an.
$loadings[,1:3] pc
Comp.1 Comp.2 Comp.3
var1 0.2383359 0.40961666 0.2877117
var2 -0.2595344 -0.45275418 -0.2968547
var3 -0.2635848 -0.42026070 -0.2935514
var4 0.1430101 -0.36227606 0.3882110
var5 -0.1440861 0.38539583 -0.4389340
var6 -0.1408366 0.36496130 -0.4273685
var7 0.4807232 -0.09797024 -0.2606992
var8 -0.5118988 0.12084916 0.2837557
var9 -0.5021733 0.11591147 0.2615927
Die Loadings einer PCA Component stellen ihre Korrelation mit den ursprünglichen Variablen dar. Je höher die Korrelation, desto mehr der ursprünglichen Variable ist in einer Component enthalten.
Comp.1 umfasst die Effekte von var7
, var8
und var9
am stärksten, da hier die höchsten Korrelationen festzustellen sind. Dabei geht der Effekt von var7
in die entgegengesetzte Richtung zu den Effekten von var8
und var9.
Comp.2 umfasst die Effekte von var1
, var2
und var3
am stärksten, da hier die höchsten Korrelationen festzustellen sind. Dabei geht der Effekt von var1
in die entgegengesetzte Richtung zu den Effekten von var2
und var3.
Comp.3 umfasst die Effekte von var4
, var5
und var6
am stärksten, da hier die höchsten Korrelationen festzustellen sind. Dabei geht der Effekt von var4
in die entgegengesetzte Richtung zu den Effekten von var5
und var6.
Weiteres Vorgehen
Mit den neuen Variablen sowie den Variablen, die nicht Teil der PCA waren (falls es solche gab), können nun regulär lineare Modelle erstellt werden. Zum Beispiel:
# Erstellen einer abhängigen Variable zur Veranschaulichung
$numbers2 <- c(rep(1:10, 50)*-1)
pcframe
<- lm(numbers2 ~ Comp.1 + Comp.2 + Comp.3, pcframe)
mdl
anova(mdl)
Analysis of Variance Table
Response: numbers2
Df Sum Sq Mean Sq F value Pr(>F)
Comp.1 1 11.5 11.490 1.4009 0.236857
Comp.2 1 69.3 69.268 8.4454 0.003741 **
Comp.3 1 0.1 0.141 0.0172 0.895672
Residuals 996 8169.1 8.202
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
05 Aufgaben
Checke bei den unten angebenen Modellen, ob es hohe Korrelationskoeffizienten zwischen Prediktoren gibt. Falls ja, nutze eine der beiden Strategien zur Vermeidung von Kollinearitätsproblemen.
Aus data_s
:
sDurLog
~bsex
+age
+location
sDurLog
~typeOfS
+pauseBin
sDurLog
~baseDurLog
+speakingRate
sDurLog
~biphoneProbSumBin
+folType
+preC
sDurLog
~bsex
+age
+location
+typeOfS
+pauseBin
+baseDurLog
+speakingRate
+biphoneProbSumBin
+folType
+preC
Aus data_a
:
height
~bsex
+hair
height
~hair
+eyes
height
~bsex
+hair
+hair
+eyes
Aus data_v
:
duration
~ vowel
+ structure
+ rate