In diesem Kapitel wird die Leistung / Performanz mittels einer multiplen linearen Regression vorhergesagt. Ziel ist es, das beste Modell zu identifizieren und die Wichtigkeit der Prädiktoren zu analysieren.
packages <- c("ggplot2", "tidyverse","rio", "sjPlot", "performance", "here",
"psych", "buildmer", "ggResidpanel", "sandwich", "lmtest", "papaja")
lapply(packages, function(package){
if (!require(package, character.only = TRUE)) {
install.packages(package, dependencies = TRUE)
}
library(package, character.only = TRUE)
})
here::here()
data <- rio::import(file = "data.csv")
str(data)
## 'data.frame': 1470 obs. of 5 variables:
## $ DistanceFromHome : int 1 8 2 3 2 2 3 24 23 27 ...
## $ JobInvolvement : int 3 2 2 3 3 3 4 3 2 3 ...
## $ JobSatisfaction : int 4 2 3 3 2 4 1 3 3 3 ...
## $ WorkLifeBalance : int 1 3 3 3 3 2 2 3 3 2 ...
## $ PerformanceRating: int 3 4 3 4 4 4 4 4 4 3 ...
summary(data)
## DistanceFromHome JobInvolvement JobSatisfaction WorkLifeBalance
## Min. : 1.000 Min. :1.00 Min. :1.000 Min. :1.000
## 1st Qu.: 2.000 1st Qu.:2.00 1st Qu.:2.000 1st Qu.:2.000
## Median : 7.000 Median :3.00 Median :3.000 Median :3.000
## Mean : 9.193 Mean :2.73 Mean :2.729 Mean :2.761
## 3rd Qu.:14.000 3rd Qu.:3.00 3rd Qu.:4.000 3rd Qu.:3.000
## Max. :29.000 Max. :4.00 Max. :4.000 Max. :4.000
## PerformanceRating
## Min. :1.000
## 1st Qu.:3.000
## Median :4.000
## Mean :3.251
## 3rd Qu.:4.000
## Max. :4.000
Alle Variablen – außer DistanceFromHome – wurden auf einer 4-stufigen Likert-Skala erhoben und zeigen überdurchschnittliche Ausprägungen. DistanceFromHome weist darauf hin, dass Mitarbeiter im Durchschnitt 9 Kilometer und maximal 29 Kilometer von ihrem Arbeitsplatz entfernt wohnen. Es gibt keine fehlenden Werte in den Daten.
psych::pairs.panels(data,
method = "pearson",
hist.col = "grey",
density = TRUE,
ellipses = FALSE,
lm = TRUE,
stars = TRUE,
bg = "grey",
col = "grey")
Die Streudiagramme zeigen, dass die Performanz am stärksten mit der Mitarbeiterzufriedenheit korreliert. Die Korrelation zwischen Performanz und Job Involvement sowie zwischen Performanz und DistanceFromHome ist schwach. Es besteht keine Korrelation zwischen Performanz und Work-Life-Balance. Zudem wurde keine Multikollinearität festgestellt, da die Prädiktoren nicht miteinander korrelieren.
Das buildmer-Paket unterstützt die automatische Vorselektion von Variablen in komplexen Regressionsmodellen. Es filtert die wichtigsten Prädiktoren heraus, um das optimale Modell zu bestimmen, das sowohl einfach als auch aussagekräftig ist. In diesem Fall werden Likelihood-Ratio-Tests in einer schrittweisen Rückwärtsselektion verwendet.
Hinweis: In der Modellformel werden auch Interaktionen berücksichtigt.
formula <- PerformanceRating ~ JobSatisfaction * JobInvolvement *
WorkLifeBalance * DistanceFromHome
max_model <- buildmer::buildmer(formula = formula,
buildmerControl = buildmerControl(dep = "PerformanceRating",
direction = c("order", "backward"),
quiet = TRUE, crit = "LRT"), data = data)
formula2 <- formula(max_model)
print(formula2)
## PerformanceRating ~ 1 + JobSatisfaction + JobInvolvement + DistanceFromHome
Die Rückwärtsselektion schlägt vor, die Variable Work-Life-Balance aus dem Modell zu entfernen. Es wurden keine Interaktionen identifiziert.
Zunächst wird eine lineare Regression mit allen Prädiktoren berechnet. Alle Variablen werden z-standardisiert, um die Bedeutung der Prädiktoren zu prüfen.
set.seed(42)
modell1 <- lm(formula = PerformanceRating ~.,
data = as.data.frame(scale(data)))
sjPlot::tab_model(modell1, title = "Linear model 1",
pred.labels = c("Intercept", "Distance From Home",
"Job Involvement", "Job Satisfaction", "Work-Live Balance"),
digits.re = 2, show.se = TRUE, show.stat = TRUE,
string.ci = "95% CI", string.est = "β", string.stat = "t",
string.se = "SE", col.order = c("est", "se", "ci", "stat", "p"))
| Performance Rating | |||||
|---|---|---|---|---|---|
| Predictors | β | SE | 95% CI | t | p |
| Intercept | -0.00 | 0.03 | -0.05 – 0.05 | -0.00 | 1.000 |
| Distance From Home | -0.07 | 0.03 | -0.12 – -0.02 | -2.81 | 0.005 |
| Job Involvement | 0.11 | 0.03 | 0.06 – 0.16 | 4.52 | <0.001 |
| Job Satisfaction | 0.20 | 0.03 | 0.16 – 0.25 | 8.09 | <0.001 |
| Work-Live Balance | 0.05 | 0.03 | -0.00 – 0.10 | 1.84 | 0.066 |
| Observations | 1470 | ||||
| R2 / R2 adjusted | 0.061 / 0.058 | ||||
Die Variablen Job Involvement und Job Satisfaction sind hochsignifikant. Der Prädiktor DistanceFromHome ist zwar signifikant, das Konfidenzintervall reicht jedoch fast bis zur Null. Die Work-Life-Balance ist nur marginal signifikant.
set.seed(42)
modell2 <- lm(formula = PerformanceRating ~.-WorkLifeBalance,
data = as.data.frame(scale(data)))
sjPlot::tab_model(modell2, title = "Linear model 2",
pred.labels = c("Intercept", "Distance From Home",
"Job Involvement", "Job Satisfaction"),
digits.re = 2, show.se = TRUE, show.stat = TRUE,
string.ci = "95% CI", string.est = "β", string.stat = "t",
string.se = "SE", col.order = c("est", "se", "ci", "stat", "p"))
| Performance Rating | |||||
|---|---|---|---|---|---|
| Predictors | β | SE | 95% CI | t | p |
| Intercept | -0.00 | 0.03 | -0.05 – 0.05 | -0.00 | 1.000 |
| Distance From Home | -0.07 | 0.03 | -0.12 – -0.02 | -2.85 | 0.004 |
| Job Involvement | 0.11 | 0.03 | 0.06 – 0.16 | 4.49 | <0.001 |
| Job Satisfaction | 0.20 | 0.03 | 0.15 – 0.25 | 8.04 | <0.001 |
| Observations | 1470 | ||||
| R2 / R2 adjusted | 0.059 / 0.057 | ||||
Nach dem Entfernen der Work-Life-Balance aus dem Modell verbessert sich der p-Wert des Prädiktors DistanceFromHome leicht.
Mit einem Likelihood-Ratio-Test werden die beiden Modelle verglichen, um das bessere auszuwählen.
anova(modell1, modell2)
## Analysis of Variance Table
##
## Model 1: PerformanceRating ~ DistanceFromHome + JobInvolvement + JobSatisfaction +
## WorkLifeBalance
## Model 2: PerformanceRating ~ (DistanceFromHome + JobInvolvement + JobSatisfaction +
## WorkLifeBalance) - WorkLifeBalance
## Res.Df RSS Df Sum of Sq F Pr(>F)
## 1 1465 1379.6
## 2 1466 1382.8 -1 -3.1803 3.3772 0.06631 .
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Der Test zeigt nur eine marginale Signifikanz. Somit ist Modell 2 Modell 1 nicht eindeutig überlegen.
ggResidpanel::resid_panel(model = modell1, theme = "gray", smoother = TRUE)
Das Modell ist insgesamt zufriedenstellend, jedoch gibt es zwei Punkte zu beachten. Der Residuen-Plot zeigt zwar ein erwartbares gestaffeltes Muster aufgrund der 4-stufigen Likert-Skala, es gibt jedoch Anzeichen für Heteroskedastizität (ungleiche Varianzen). Im Q-Q-Plot und Histogramm zeigt sich zudem eine leichte Schiefe, was darauf hinweist, dass die Residuen nicht vollständig normalverteilt sind.
performance::check_distribution(modell1)
## # Distribution of Model Family
##
## Predicted Distribution of Residuals
##
## Distribution Probability
## normal 69%
## tweedie 9%
## beta 6%
##
## Predicted Distribution of Response
##
## Distribution Probability
## normal 47%
## beta 9%
## beta-binomial 9%
Ein Vergleich mit verschiedenen Verteilungen legt jedoch nahe, dass die vorhergesagten Verteilungen der Residuen und der Kriteriumsvariablen am wahrscheinlichsten normalverteilt sind.
Durch die Berechnung robuster Standardfehler und Konfidenzintervalle wird die lineare Regression robuster gegenüber Annahmeverletzungen wie Heteroskedastizität und Nicht-Normalverteilung der Residuen, was zu verlässlicheren Ergebnissen führt.
robust_se <- sandwich::vcovHC(modell1, type = "HC3")
confint_robust <- lmtest::coefci(modell1, vcov = robust_se)
print(confint_robust)
## 2.5 % 97.5 %
## (Intercept) -0.049740513 0.04974051
## DistanceFromHome -0.121505829 -0.02063850
## JobInvolvement 0.061628223 0.16724449
## JobSatisfaction 0.153812402 0.25581699
## WorkLifeBalance -0.003849719 0.09696841
Das robuste Konfidenzintervall für Work-Life-Balance schließt die Null mit ein, was für Modell 2 ohne Work-Life-Balance als finales Modell spricht.
Mit der Berechnung der Kennwerte “Nützlichkeit”, “Redundanz” und “Supression” kann die Wichtigkeit der einzelnen Prädiktoren detailliert analysiert werden.
Die Nützlichkeit betrachtet den Varianzanteil, der ausschließlich auf einen bestimmten Prädiktor zurückzuführen ist. Prädiktoren mit geringer Nützlichkeit können ausgeschlossen werden.
nuetzlichkeit <- rep(NA, times=3)
names(nuetzlichkeit) <- c("DistanceFromHome", "JobInvolvement", "JobSatisfaction")
nuetzlichkeit["DistanceFromHome"] <- summary(modell2)$r.squared - summary(lm(data = data,
formula = PerformanceRating ~.-DistanceFromHome))$r.squared
nuetzlichkeit["JobInvolvement"] <- summary(modell2)$r.squared - summary(lm(data = data,
formula = PerformanceRating ~.-JobInvolvement))$r.squared
nuetzlichkeit["JobSatisfaction"] <- summary(modell2)$r.squared - summary(lm(data = data,
formula = PerformanceRating ~. -JobSatisfaction))$r.squared
enframe(nuetzlichkeit, name = "Predictor", value = "Value") %>% arrange(desc(Value))
## # A tibble: 3 × 2
## Predictor Value
## <chr> <dbl>
## 1 JobSatisfaction 0.0397
## 2 JobInvolvement 0.0109
## 3 DistanceFromHome 0.00288
Die Berechnungen zeigen, dass die Mitarbeiterzufriedenheit den höchsten Nützlichkeitswert aufweist, während DistanceFromHome nur eine geringe Nützlichkeit zeigt.
Ein Prädiktor ist redundant, wenn andere Prädiktoren einen wesentlichen Teil seiner Varianz erklären. Das Hinzufügen eines redundanten Prädiktors würde die Zusammenhänge anderer Prädiktoren auf das Kriterium (Arbeitsleistung) verringern. Redundante Prädiktoren sollten ausgeschlossen werden.
# Kriteriumskorrelationen bestimmen
correlations <- cor(data[,c(1:3, 5)])
print(correlations)
## DistanceFromHome JobInvolvement JobSatisfaction
## DistanceFromHome 1.000000000 0.00878328 -0.003668839
## JobInvolvement 0.008783280 1.00000000 -0.021475910
## JobSatisfaction -0.003668839 -0.02147591 1.000000000
## PerformanceRating -0.072054902 0.10873299 0.201711838
## PerformanceRating
## DistanceFromHome -0.0720549
## JobInvolvement 0.1087330
## JobSatisfaction 0.2017118
## PerformanceRating 1.0000000
criterion_correlations <- correlations[4,1:3]
print(criterion_correlations)
## DistanceFromHome JobInvolvement JobSatisfaction
## -0.0720549 0.1087330 0.2017118
# Beta-Gewichte extrahieren
beta_weights <- modell2$coefficients[2:4]
# beta mal r berechnen
beta_times_r <- criterion_correlations * beta_weights
# beta_times_r vergleichen mit r²
ist_redundant <- abs(beta_times_r) < criterion_correlations^2
print(ist_redundant)
## DistanceFromHome JobInvolvement JobSatisfaction
## FALSE FALSE FALSE
# Stärke der Redundanz
redundanz <- criterion_correlations^2 - nuetzlichkeit
enframe(redundanz, name = "Predictor", value = "Value") %>% arrange(desc(Value))
## # A tibble: 3 × 2
## Predictor Value
## <chr> <dbl>
## 1 DistanceFromHome 0.00231
## 2 JobSatisfaction 0.000940
## 3 JobInvolvement 0.000902
Keiner der Prädiktoren ist redundant. Allerdings erklären die Variablen Mitarbeiterzufriedenheit und Job Involvement einen Teil der Varianz von DistanceFromHome, wodurch sie wichtiger sind.
Eine Suppressor-Variable erhöht das R² des Modells, indem sie Varianzen in anderen Prädiktoren unterdrückt. Dies verstärkt den positiven Zusammenhang eines anderen Prädiktors mit dem Kriterium. Suppressor-Variablen sollten im Modell bleiben.
# r² mit Nuetzlichkeit vergleichen
suppression <- criterion_correlations^2 < nuetzlichkeit
print(suppression)
## DistanceFromHome JobInvolvement JobSatisfaction
## FALSE FALSE FALSE
Es zeigen sich bei den Prädiktoren keine Supressionseffekte.
coefficients_df <- broom::tidy(modell2)
coefficients_df %>%
dplyr::filter(term != "(Intercept)") %>%
ggplot2::ggplot(aes(x = reorder(term, estimate), y = estimate)) +
geom_col() +
labs(title = "Wichtigkeit der Variablen basierend auf Regressionskoeffizienten",
x = "Variablen",
y = "Koeffizienten") +
papaja::theme_apa()
Die Regressionskoeffizienten zeigen, dass die Mitarbeiterzufriedenheit den größten Einfluss auf die Arbeitsleistung hat. Ebenfalls wichtig ist das Job Involvement, während die Länge des Arbeitswegs einen schwächeren, negativen Einfluss auf die Performanz hat.