Während der Vorbereitung auf die Klausur dieses Moduls kam es unter den Studierenden vermehrt zu Annahmen, dass man selbst eher der “Mathe-” oder doch der “Sprachentyp” sei. Man sich also lieber in verbalen Darstellungen vergnügt oder eben in denen der Mathematik. Interessant wäre es also nun zu sehen, ob diese Typentrennungen durch Daten gestützt werden. Sind Stärken auf der mathematischen Seite quasi Prädiktor für Versagen auf der anderen? Vielleicht stehen mathematische und sprachliche Leistungen in keinem Zusammenhang. Vielleicht ist aber alles eine faule Bauernregel - man darf durchaus auf beiden Gebieten gut sein.
\(H_0:\beta_1=0\), wobei \(\beta_1\) den Koeffizienten des Regressionsmodells der durchschnittlichen Portugiesisch-Noten als Funktion der durchschnittlichen Mathematiknoten darstellt. Die Steigung der Regressionsgeraden als Modell von Portugiesischnoten nach Mathematiknoten ist 0. Es gibt keinen Zusammenhang.
\(H_A: \beta_1≠0\), Die Steigung der Regressionsgeraden als Modell von Portugiesischnoten nach Mathematiknoten ist ungleich 0. Es gibt einen Zusammenhang.library(broom)
library(mosaic)
library(cowplot)
library(lsr)
library(caret)
library(modelr)
library(gridExtra)
library(sjmisc)
library(knitr)
temp <- tempfile()
download.file("https://archive.ics.uci.edu/ml/machine-learning-databases/00320/student.zip",temp)
MatheKurs <- read.csv2(unz(temp, "student-mat.csv"))
PortugiesischKurs <- read.csv2(unz(temp, "student-por.csv"))
remove(temp)
Missing<- merge_df(PortugiesischKurs,MatheKurs)
inspect(Missing$G1,G2,G3)$missing
## [1] 0
Schueler=merge(MatheKurs,PortugiesischKurs,by=c("school","sex","age","address","famsize","Pstatus","Medu","Fedu","Mjob","Fjob","reason","nursery","internet","guardian","guardian","traveltime","studytime","failures","schoolsup","famsup","activities","higher","romantic","famrel","freetime","goout","Dalc","Walc","health","absences"))
print(nrow(Schueler))
## [1] 85
Wichtig ist, die Variable paid außen vor zu lassen, da sie nach Definition eine kursspezifische Variable darstellt und keine schülerspezifische:
(…)extra paid classes within the course subject (Math or Portuguese) (binary: yes or no)(…)
Es befinden sich also 85 Schüler sowohl in den Kursen Mathematik als auch Portugiesisch, welche nun die Grundlage für den Leistungsvergleich darstellen werden.
Gegeben sind uns 3 Perioden, G1-G3. Wir untersuchen aber den Einfluss der durchschnittlichen Noten. Erstellen wir diese…SchuelerBeiderKurse<-Schueler %>%
mutate(Matheschnitt=rowMeans(cbind(G1.x,G2.x,G3.x))) %>%
mutate(Portuschnitt=rowMeans(cbind(G1.y,G2.y,G3.y)))
ModusMa<-count(SchuelerBeiderKurse, Matheschnitt) %>% arrange(-n) %>% top_n(1)
ModusPo<-count(SchuelerBeiderKurse, Portuschnitt) %>% arrange(-n) %>% top_n(1)
mh<-gf_dhistogram( ~ Matheschnitt, data = SchuelerBeiderKurse, binwidth = 2, xlab = "Durchschnittsnote Mathematik") %>%
gf_dens(~Matheschnitt, data = SchuelerBeiderKurse,color = "#8b0000") %>%
gf_vline(color = "#ffff74", size = 1, xintercept = ~mean(Matheschnitt, data=SchuelerBeiderKurse)) %>%
gf_vline(color = "#00008b", size = 1, xintercept = ~Matheschnitt, data = ModusMa)
ph<-gf_dhistogram( ~ Portuschnitt, data = SchuelerBeiderKurse, binwidth = 2, xlab = "Durchschnittsnote Portugiesisch")%>%
gf_dens(~Portuschnitt, data = SchuelerBeiderKurse,color = "#8b0000") %>%
gf_vline(color = "#ffff74", size = 3, xintercept = ~mean(Portuschnitt, data=SchuelerBeiderKurse)) %>%
gf_vline(color = "#00008b", size = 1, xintercept = ~Portuschnitt, data = ModusPo)
av<-gf_violin(Matheschnitt ~ 1, data = SchuelerBeiderKurse, fill = "#00008b",alpha = 0.3, ylab= "Durchschnittsnote Mathematik") %>%
gf_boxplot(Matheschnitt ~ 1, data = SchuelerBeiderKurse) %>%
gf_point(mean(Matheschnitt)~1, data = SchuelerBeiderKurse, color = "#ffff74", size = 6) %>%
gf_point(Matheschnitt~1, data = ModusMa, color = "#ff0000")
bv<-gf_violin(Portuschnitt ~ 1, data = SchuelerBeiderKurse, fill = "#00008b",alpha = 0.3, ylab= "Durchschnittsnote Portugiesisch") %>%
gf_boxplot(Portuschnitt ~ 1, data = SchuelerBeiderKurse) %>%
gf_point(mean(Portuschnitt)~1, data = SchuelerBeiderKurse, color = "#ffff74", size = 6) %>%
gf_point(Portuschnitt~1, data = ModusPo, color = "#ff0000")
grid.arrange(mh, ph, av, bv, nrow = 2)
Mathe_summary <- SchuelerBeiderKurse %>%
summarise(Mittelwert = mean(Matheschnitt),
MAD = aad(Matheschnitt),
Varianz = var(Matheschnitt),
sd = sd(Matheschnitt),
Q_1 = favstats(Matheschnitt)$Q1,
Median= median(Matheschnitt),
Q_3 = favstats(Matheschnitt)$Q3,
IQR = iqr(Matheschnitt),
Modus= ModusMa$Matheschnitt,
min = favstats(Matheschnitt)$min,
max = favstats(Matheschnitt)$max,
Range = favstats(Matheschnitt)$max-favstats(Matheschnitt)$min)
Portu_summary <- SchuelerBeiderKurse %>%
summarise(Mittelwert = mean(Portuschnitt),
MAD = aad(Portuschnitt),
Varianz = var(Portuschnitt),
sd = sd(Portuschnitt),
Q_1 = favstats(Portuschnitt)$Q1,
Median= median(Portuschnitt),
Q_3 = favstats(Portuschnitt)$Q3,
IQR = iqr(Portuschnitt),
Modus= ModusPo$Portuschnitt,
min = favstats(Portuschnitt)$min,
max = favstats(Portuschnitt)$max,
Range = favstats(Matheschnitt)$max-favstats(Matheschnitt)$min)
Zusammenfassung<-merge_df(Mathe_summary,Portu_summary)
rownames(Zusammenfassung)[rownames(Zusammenfassung) == "1"] = "Mathematik"
rownames(Zusammenfassung)[rownames(Zusammenfassung) == "2"] = "Portugiesisch"
kable(Zusammenfassung)
| Mittelwert | MAD | Varianz | sd | Q_1 | Median | Q_3 | IQR | Modus | min | max | Range | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Mathematik | 12.10588 | 2.854717 | 12.058761 | 3.472573 | 10 | 12.00000 | 14.66667 | 4.666667 | 11.66667 | 3.666667 | 18.66667 | 15 |
| Portugiesisch | 12.92941 | 2.046228 | 6.804482 | 2.608540 | 11 | 12.66667 | 14.66667 | 3.666667 | 13.00000 | 4.333333 | 18.00000 | 15 |
Die Lagemaße, welche Werte also repräsentativ sind, zeigen, dass, bis auf den gleichen Q_3-Wert, im Fach Portugiesich typischerweise mit höheren Wertungen abgeschlossen wird. Bezogen auf die Streuungsmaße, d.h. wie unterschiedlich bzw. ähnlich die Werte sind: Die Daten streuen in der Mathematik mehr. Sowohl mittlerer absoluter Abstand, Varianz, Standardabweichung als auch Interquartilsabstand zeigen, dass es typisch für einzelne Mathematikbewertungen ist weiter auseinander zu liegen bzw. extremer streuen. So liegt z.B. das Q1 gerade am Schnitt, um den Kurs zu bestehen. 25% der Studenten liegen hier noch darunter. In Portugiesisch liegt Q1 um einen ganzen Punkt darüber. Dazu liegt es dichter am Q2 und hat letztlich auch den geringeren IQR, streut dichter.
Über die Spannweite 0-20 aller möglichen Wertungen, liegen beide Fächer dennoch nah beieinander. Portugiesisch scheint aber sicherer zu absolvieren.SchuelerBeiderKurse<-SchuelerBeiderKurse %>%
mutate(Kursergebnis_Mathe = case_when(Matheschnitt < 9.5 ~ "Durchgefallen",
Matheschnitt >= 9.5 ~ "Bestanden",)) %>%
mutate(Kursergebnis_Portugiesisch = case_when(Portuschnitt < 9.5 ~ "Durchgefallen",
Portuschnitt >= 9.5 ~ "Bestanden"))
bm<-gf_bar(~ nrow(SchuelerBeiderKurse), data = SchuelerBeiderKurse, fill = ~Kursergebnis_Mathe, xlab = "Absolventen")
bp<-gf_bar(~ nrow(SchuelerBeiderKurse), data = SchuelerBeiderKurse, fill = ~Kursergebnis_Portugiesisch, xlab = "Absolventen")
plot_grid(bm, bp)
SchuelerBeiderKurse %>%
select(Kursergebnis_Mathe, Kursergebnis_Portugiesisch) %>%
table()
## Kursergebnis_Portugiesisch
## Kursergebnis_Mathe Bestanden Durchgefallen
## Bestanden 68 0
## Durchgefallen 14 3
tally( ~Kursergebnis_Mathe & Kursergebnis_Portugiesisch,format = "percent", data = SchuelerBeiderKurse)
## Kursergebnis_Portugiesisch
## Kursergebnis_Mathe Bestanden Durchgefallen
## Bestanden 80.000000 0.000000
## Durchgefallen 16.470588 3.529412
Unsere Vermutung spiegelt sich in beiden Balken wieder. Beinahe niemand fällt im sprachwissenschaftlichen Kurs durch (vorausgesetzt wird hier ein “aufrundungsgeneigter” Dozent).
68 Absolventen haben nach ihrem Notendurchschnitt in Mathematik bestanden, 17 nicht. 82 Absolventen schafften es entsprechend in Portugiesisch, 3 sind duchgefallen. Das entspricht einer Erfolgsquote von ≈80% in Mathematik und ≈96% in Portugiesisch. Die Zahlen lassen auf ein insgesamt positives Sentiment der Schüler gegenüber einem breiten Wissenspektrum schließen und “klammern”, zumindest bisher, den gesuchten Zusammenhang nicht aus.Portu_IQR <- iqr(~ Portuschnitt, data = SchuelerBeiderKurse)
Portu_Q1 <- quantile(~Portuschnitt, p = .25, data = SchuelerBeiderKurse)
untere_Grenze <- Portu_Q1 - 1.5 * Portu_IQR
SchuelerBeiderKurse %>%
filter(Portuschnitt < untere_Grenze) %>%
summarise(Mathe= Matheschnitt,
Portugiesisch= Portuschnitt)
shapiro.test(SchuelerBeiderKurse$Matheschnitt)
##
## Shapiro-Wilk normality test
##
## data: SchuelerBeiderKurse$Matheschnitt
## W = 0.97725, p-value = 0.138
shapiro.test(SchuelerBeiderKurse$Portuschnitt)
##
## Shapiro-Wilk normality test
##
## data: SchuelerBeiderKurse$Portuschnitt
## W = 0.96622, p-value = 0.02509
SBKmodel<-lm(Portuschnitt~Matheschnitt, data = SchuelerBeiderKurse)
summary(SBKmodel)
##
## Call:
## lm(formula = Portuschnitt ~ Matheschnitt, data = SchuelerBeiderKurse)
##
## Residuals:
## Min 1Q Median 3Q Max
## -3.8780 -1.2929 -0.0383 0.8858 4.3766
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 6.16138 0.69325 8.888 1.10e-13 ***
## Matheschnitt 0.55907 0.05507 10.152 3.28e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.753 on 83 degrees of freedom
## Multiple R-squared: 0.5539, Adjusted R-squared: 0.5485
## F-statistic: 103.1 on 1 and 83 DF, p-value: 3.284e-16
Wir sehen, dass mit jedem Zuwachs eines Punktes im Fach “Mathematik” auch die Portugiesischnote um ≈0,56 verbessert (Steigung “Matheschnitt”). Im Modell haben Schüler selbst bei einer “0”-Punkte-Bewertung im Fach Mathematik, noch eine Wertung von ≈6,16 im Fach Portugiesisch (Intercept).
Der traditionelle Weg würde uns schon jetzt zeigen, dass eine solche Steigung unter Annahme einer H0-Verteilung quasi null entspricht2 * pt(10.152, df = 83, lower.tail = FALSE)
## [1] 3.28237e-16
Wir gehen aber den simulationsbasierten Weg im letzten Abschnitt der Arbeit.
Hervorzuheben ist hier, dass das Bestimmtheitsmaß R² von ≈0,55 nicht nur zeigt, dass unser Modell einen um 55% kleineren Vorhersagefehler erbringt als ein reines Nullmodell, sondern auch ein Indiz für eine stark positive Korrelation der erbrachten Leistungen in den Kursen Mathematik und Portugiesisch andeutet, da sich der Korrelationskoeffizient aus der Quadratwurzel von R² ergibt.Toleranzwert = 1e-15
abs((cor(Matheschnitt~Portuschnitt,data = SchuelerBeiderKurse)) %>% #Der Korrelationskoeffizient sollte sich mit
-(sqrt(summary(SBKmodel)$r.squared)))<=Toleranzwert #der Quadratwurzel des R² quasi aufheben
## [1] TRUE
sqrt(summary(SBKmodel)$r.squared)
## [1] 0.7442518
gf_point(Portuschnitt~Matheschnitt, data = SchuelerBeiderKurse, alpha = 0.2, size = 2.5) %>%
gf_lm(alpha = 0.5)
SchuelerBeiderKurse %>%
add_residuals(SBKmodel) %>%
ggplot +
aes(x = resid) +
geom_histogram(binwidth = .8, center=1) -> residh
qplot(sample = .stdresid, data = SBKmodel) +
geom_abline(color = "green") +
labs(x = "theoretical", y= "sample")-> residq
SchuelerBeiderKurse %>%
add_predictions(SBKmodel) %>%
add_residuals(SBKmodel) %>%
ggplot() +
aes(y = resid, x = pred) +
geom_jitter(alpha = .2, width = .005) +
geom_boxplot(aes(group = pred), alpha = .7) -> predbox
gf_point(resid(SBKmodel) ~ fitted(SBKmodel),ylab = "resid", xlab = "fitted") -> scatter
grid.arrange(residh, residq, predbox, scatter, nrow = 1)
mean(SBKmodel$residuals^2)
## [1] 2.999695
sqrt(mean(SBKmodel$residuals^2))
## [1] 1.731963
any(cooks.distance(SBKmodel) > 1)
## [1] FALSE
set.seed(1337)
BootSBK <- do(10000) *lm(Portuschnitt~Matheschnitt, data = mosaic::resample(SchuelerBeiderKurse))
Empmodel<-coef(lm(Portuschnitt~Matheschnitt, data = SchuelerBeiderKurse))[2]
ModelQ1<-quantile( ~ Matheschnitt, probs = c(0.025, 0.975), data = BootSBK)[1]
ModelQ2<-quantile( ~ Matheschnitt, probs = c(0.025, 0.975), data = BootSBK)[2]
gf_histogram( ~ Matheschnitt, data = BootSBK) %>%
gf_vline(xintercept = ~Empmodel) %>%
gf_vline(color = c("blue"), xintercept = ~ c(ModelQ1, ModelQ2), data = NA)
confint(BootSBK)
sd( ~ Matheschnitt, data = BootSBK)
## [1] 0.06731947
Wir können erkennen, dass das 95%-Konfidenzintervall der Steigung nicht die Null oder gar negative Werte beinhaltet, sondern sich von ≈ 0,43 bis ≈ 0,69 erstreckt. Mit einer Sicherheit von 95% wird eine erneute Resampling-Stichprobe wieder einen Wert in diesem Intervall ausgeben und den wahren Wert der Population überdecken. Dieser Schätzkorridor hat einen Standardfehler von 0.06731947. Unsere Erwartungswerte liegen also zwischen dem “Estimate” unseres Koeffizienten “Matheschnitt” von 0.6080122 ± 2*0.06731947.
Das entsprechende Konfidenzintervall unseres Achsenabschnitts verläuft zwischen ≈ 4,39 und ≈ 7,79, das unseres R² zwischen ≈ 0,41 und ≈ 0,69.
set.seed(1337)
SBKnull <- do(10000) *lm(Portuschnitt ~ shuffle(Matheschnitt), data = SchuelerBeiderKurse)
gf_histogram( ~ Matheschnitt, data = SBKnull) %>%
gf_vline(xintercept = ~Empmodel, color = "blue")
sdnull<-sd( ~ Matheschnitt, data = SBKnull)
(Empmodel-0)/sdnull
## Matheschnitt
## 6.849185
xpnorm(Empmodel, mean = mean(~Matheschnitt, data=SBKnull), sd = sdnull)
## Matheschnitt
## 1
SBKnull <- SBKnull %>%
mutate(effektnull = abs(Matheschnitt))
prop( ~ (effektnull >= Empmodel), data = SBKnull)
## prop_TRUE
## 0
predict(SBKmodel,newdata = data.frame(Matheschnitt = 5), interval = "prediction")
## fit lwr upr
## 1 8.956727 5.364877 12.54858
Bei der Analyse wurden die Durchschnittswerte von Periodenergebnissen berechnet, die wiederum auch nur Mittelwerte ihrer jeweiligen Periode darstellen. Sämtliche Einzelleistungen innerhalb der (unbekannten) Vektoren fallen so “unter den Tisch”.
Es wurden zudem lediglich Daten an zwei Schulen in Portugal erhoben. Wir können also maximal auf vergleichbare portugiesische Schüler schließen, sofern davon ausgegangen wird, dass die beiden Standorte repräsentativ sind. Zudem ist die Stichprobe recht knapp bemessen, um aus ihr heraus zu inferieren.
Auch gab es keine weitere Beschreibung äußerer Einflüsse oder zum Verhalten der Schüler. So kann man beispielsweise Störvariablen vermuten, aber eben nicht sicher nachweisen.
Unser p-Wert scheint zwar sehr eindeutig, jedoch ist er, so wie die Schätzung des Standardfehlers, durch die Verletzung der Annahme der Homoskedastizität beeinflusst. Die eigentliche Schätzung der Steigung bleibt dabei unberührt.