La pregunta clau que ens plantegem en aquest projecte és:
Les hores d’estudi (studytime) i el nombre d’absències (absences) tenen una relació directa amb el rendiment acadèmic final dels estudiants (G3)?
Per respondre aquesta pregunta, no només descriurem les dades, sinó que aplicarem un model estadístic per analitzar exactament quants punts es guanyen estudiant o es perden faltant a classe.
El nostre conjunt de dades prové del repositori UC Irvine Machine Learning. Cada registre representa un alumne concret, incloent informació acadèmica i personal.
El conjunt té 395 registres (alumnes) i 33 variables.
glimpse(myData)
## Rows: 395
## Columns: 33
## $ school <chr> "GP", "GP", "GP", "GP", "GP", "GP", "GP", "GP", "GP", "GP",…
## $ sex <chr> "F", "F", "F", "F", "F", "M", "M", "F", "M", "M", "F", "F",…
## $ age <int> 18, 17, 15, 15, 16, 16, 16, 17, 15, 15, 15, 15, 15, 15, 15,…
## $ address <chr> "U", "U", "U", "U", "U", "U", "U", "U", "U", "U", "U", "U",…
## $ famsize <chr> "GT3", "GT3", "LE3", "GT3", "GT3", "LE3", "LE3", "GT3", "LE…
## $ Pstatus <chr> "A", "T", "T", "T", "T", "T", "T", "A", "A", "T", "T", "T",…
## $ Medu <int> 4, 1, 1, 4, 3, 4, 2, 4, 3, 3, 4, 2, 4, 4, 2, 4, 4, 3, 3, 4,…
## $ Fedu <int> 4, 1, 1, 2, 3, 3, 2, 4, 2, 4, 4, 1, 4, 3, 2, 4, 4, 3, 2, 3,…
## $ Mjob <chr> "at_home", "at_home", "at_home", "health", "other", "servic…
## $ Fjob <chr> "teacher", "other", "other", "services", "other", "other", …
## $ reason <chr> "course", "course", "other", "home", "home", "reputation", …
## $ guardian <chr> "mother", "father", "mother", "mother", "father", "mother",…
## $ traveltime <int> 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 3, 1, 2, 1, 1, 1, 3, 1, 1,…
## $ studytime <int> 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 1, 2, 3, 1, 3, 2, 1, 1,…
## $ failures <int> 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0,…
## $ schoolsup <chr> "yes", "no", "yes", "no", "no", "no", "no", "yes", "no", "n…
## $ famsup <chr> "no", "yes", "no", "yes", "yes", "yes", "no", "yes", "yes",…
## $ paid <chr> "no", "no", "yes", "yes", "yes", "yes", "no", "no", "yes", …
## $ activities <chr> "no", "no", "no", "yes", "no", "yes", "no", "no", "no", "ye…
## $ nursery <chr> "yes", "no", "yes", "yes", "yes", "yes", "yes", "yes", "yes…
## $ higher <chr> "yes", "yes", "yes", "yes", "yes", "yes", "yes", "yes", "ye…
## $ internet <chr> "no", "yes", "yes", "yes", "no", "yes", "yes", "no", "yes",…
## $ romantic <chr> "no", "no", "no", "yes", "no", "no", "no", "no", "no", "no"…
## $ famrel <int> 4, 5, 4, 3, 4, 5, 4, 4, 4, 5, 3, 5, 4, 5, 4, 4, 3, 5, 5, 3,…
## $ freetime <int> 3, 3, 3, 2, 3, 4, 4, 1, 2, 5, 3, 2, 3, 4, 5, 4, 2, 3, 5, 1,…
## $ goout <int> 4, 3, 2, 2, 2, 2, 4, 4, 2, 1, 3, 2, 3, 3, 2, 4, 3, 2, 5, 3,…
## $ Dalc <int> 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1,…
## $ Walc <int> 1, 1, 3, 1, 2, 2, 1, 1, 1, 1, 2, 1, 3, 2, 1, 2, 2, 1, 4, 3,…
## $ health <int> 3, 3, 3, 5, 5, 5, 3, 1, 1, 5, 2, 4, 5, 3, 3, 2, 2, 4, 5, 5,…
## $ absences <int> 6, 4, 10, 2, 4, 10, 0, 6, 0, 0, 0, 4, 2, 2, 0, 4, 6, 4, 15,…
## $ G1 <int> 5, 5, 7, 15, 6, 15, 12, 6, 16, 14, 10, 10, 14, 10, 14, 14, …
## $ G2 <int> 6, 5, 8, 14, 10, 15, 12, 5, 18, 15, 8, 12, 14, 10, 16, 14, …
## $ G3 <dbl> 11, 11, 11, 17, 11, 9, 15, 12, 11, 13, 11, 13, 9, 8, 11, 7,…
En aquest primer histograma, observem una distribució normal. La gran majoria d’alumnes s’agrupen al voltant de la nota central (10-11). Les cues són simètriques, indicant que hi ha tants alumnes excel·lents com suspensos greus.
ggplot(myData, aes(x = G3)) +
geom_histogram(binwidth = 1, color="black", fill="lightblue")
Aquí veiem un comportament diferent. La distribució no és simètrica, ja que està esbiaixada cap a l’esquerra. La immensa majoria d’estudiants (barres més altes) dediquen poc temps a l’estudi (nivells 1 i 2), mentre que molt pocs arriben al nivell 4. Això ens indica que a l’esforç màxim, pocs estudiants hi arriben.
ggplot(myData, aes(x = studytime)) +
geom_histogram(binwidth = 0.5, color="black", fill="lightgreen")
Aquest gràfic mostra una forta asimetria. La barra més alta està al 0, indicant que el comportament estàndard és no faltar. Però també podem veure a l’última barra que hi ha un petit repunt.
ggplot(myData, aes(x = absences)) +
geom_histogram(binwidth = 2, color="black", fill="salmon")
Per entendre com es relacionen les variables, analitzem els estadístics i els patrons visuals.
La mitjana (10.94) i la mediana (11) són gairebé idèntiques. En el gràfic, la caixa està perfectament centrada i els bigotis tenen longituds similars. Això confirma que no tenim problemes d’asimetria.
mean(myData$G3)
## [1] 10.93671
sd(myData$G3)
## [1] 3.097984
median(myData$G3)
## [1] 11
ggplot(myData, aes(y = G3)) +
geom_boxplot(fill = "lightblue", color = "black", width = 0.5)
En aquest gràfic observem una tendència ascendent clara. Tot i que hi ha dispersió, els punts es desplacen cap amunt a mesura que estudiem més hores. La línia negra és la de la tendència i té un pendent positiu, el que indica que estudiar més augmenta la probabilitat de treure millor nota.
ggplot(myData, aes(x = studytime, y = G3)) +
geom_jitter(alpha = 0.6, color = "darkgreen", width = 0.2) +
geom_smooth(method = "lm", se = FALSE, color = "black")
Aquí la relació és la inversa. La línia de tendència mostra un pendent negatiu; això indica el contrari, és a dir, que quantes més faltes facis, més possibilitats de treure pitjor nota.
ggplot(myData, aes(x = absences, y = G3)) +
geom_point(alpha = 0.6, color = "darkred") +
geom_smooth(method = "lm", se = FALSE, color = "black")
Ajustem un model de regressió lineal múltiple: \[G3 = \beta_0 + \beta_1(studytime) + \beta_2(absences)\]
model_regressio = lm(G3 ~ studytime + absences, data = myData)
summary(model_regressio)
##
## Call:
## lm(formula = G3 ~ studytime + absences, data = myData)
##
## Residuals:
## Min 1Q Median 3Q Max
## -6.3302 -1.1004 -0.0734 1.0684 6.9535
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 7.12742 0.25980 27.43 <2e-16 ***
## studytime 2.48649 0.10824 22.97 <2e-16 ***
## absences -0.25673 0.01824 -14.08 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.798 on 392 degrees of freedom
## Multiple R-squared: 0.6647, Adjusted R-squared: 0.663
## F-statistic: 388.6 on 2 and 392 DF, p-value: < 2.2e-16
Els resultats confirmen el que hem vist als gràfics:
Com que tenim dues variables independents (estudi i absències), el model no és una recta, sinó un pla en l’espai. La seva forta inclinació cap amunt en l’eix de l’estudi confirma visualment que és el factor més determinant (+2,49), mentre que s’inclina lleugerament cap avall amb les absències. Apart també podem veure que el pla talla els punts pel mig, indicant que el model captura correctament els punts.
library(scatterplot3d)
s3d = with(myData, scatterplot3d(studytime,absences,G3, angle = 60, box = FALSE))
s3d$plane3d(model_regressio, col = 'red')
# 6. Validació dels Residus
Per assegurar-nos que el model és fiable per fer inferència RL, fer prediccions i fer contrastos, hem de verificar que es compleixin la normalitat dels residus, la independència dels residus i l’homoscedasticitat dels residus.
En el gràfic “Residuals vs Fitted”, els punts no formen cap patró, estan dispersos aleatòriament.
par(mfrow = c(2, 2))
plot(model_regressio)
par(mfrow = c(1, 1))
Utilitzem aquest test per confirmar que els residus segueixen una distribució Normal. Les hipòtesis són: * \(H_0\) (Hipòtesi Nul·la): Els residus segueixen una distribució Normal. * \(H_1\) (Hipòtesi Alternativa): Els residus NO segueixen una distribució Normal.
shapiro.test(resid(model_regressio))
##
## Shapiro-Wilk normality test
##
## data: resid(model_regressio)
## W = 0.99445, p-value = 0.1633
Anàlisi: El p-valor obtingut és superior a 0.05. Això vol dir que no rebutgem la hipòtesi nul·la i acceptem que els errors són Normals. El model passa aquesta prova.
Verifiquem si la variància dels errors és constant (si el model és igual de fiable per a notes altes i baixes). * \(H_0\): La variància dels errors és constant (Homoscedasticitat). * \(H_1\): La variància dels errors canvia (Heteroscedasticitat).
bptest(model_regressio)
##
## studentized Breusch-Pagan test
##
## data: model_regressio
## BP = 2.9628, df = 2, p-value = 0.2273
Anàlisi: El p-valor és superior a 0.05. Per tant, assumim que existeix homoscedasticitat i el model és vàlid.
Un cop hem comprovat que el nostre model compleix els supòsits i permet fer inferència lineal, és important verificar la significació individual de cada variable. Ja que a vegades en un model de regressió lineal múltiple, dues variables poden estar molt relacionades entre elles, fent que semblin importants juntes però no per separat. Fer això ens permet saber que tant l’estudi com l’assistència tenen relació directa amb la nota, sense dependre de la presència de les altres dues variables.
Per a cada coeficient (\(\beta\)), plantegem: * \(H_0: \beta = 0\) (La variable no afecta la nota). * \(H_1: \beta \neq 0\) (La variable sí afecta la nota).
# Contrast 1: Només Estudi
summary(lm(G3 ~ studytime, data = myData))$coefficients
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 5.649132 0.2912155 19.39846 2.747201e-59
## studytime 2.597752 0.1322946 19.63612 2.590002e-60
# Contrast 2: Només Absències
summary(lm(G3 ~ absences, data = myData))$coefficients
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 12.3376647 0.19381415 63.65719 4.085250e-209
## absences -0.2873196 0.02782247 -10.32689 2.799365e-22
Anàlisi: Podem veure que en tots dos casos, els p-valors són més petits que 0.05, pràcticament zero. Això indica que tenen una relació molt forta: les hores d’estudi expliquen la nota per si mateixes, i les absències també. Això vol dir que cadascuna de les variables aporta una informació única i valuosa sobre el comportament de l’alumne. Això reforça la decisió de mantenir-les totes dues al model final.
Volem fer unes prediccions amb els dos casos possibles perquè això ens permetrà saber com seran els possibles futurs estudiants. Les notes possibles: des del pitjor escenari possible (poc esforç i moltes absències) fins al millor (màxim esforç i 0 absències). A més, utilitzarem intervals de confiança per donar un rang on és molt probable que caigui la nota real.
nous_estudiants= tibble(
studytime = c(1, 2, 4),
absences = c(15, 4, 0)
)
prediccions =predict(model_regressio, nous_estudiants, interval = "confidence")
resultat_final= nous_estudiants %>%
bind_cols(as_tibble(prediccions))
resultat_final
## # A tibble: 3 × 5
## studytime absences fit lwr upr
## <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1 15 5.76 5.32 6.21
## 2 2 4 11.1 10.9 11.3
## 3 4 0 17.1 16.6 17.5
Podem analitzar que hi ha una gran diferència entre les dues prediccions: el fracàs per al perfil 1 té la nota de 5.7 i l’èxit rotund per al perfil 3 té la nota de 17.0. Això demostra que amb les variables triades podem anticipar la seva nota amb un marge d’error realment petit. ### Visualització del Model: Valors Reals vs Predits
Per avaluar visualment la precisió del nostre model, gràfiquem les notes reals que han tret els alumnes (Eix X) contra les notes que el nostre model ha predit per a ells (Eix Y). Podem veure que els punts blaus cauen exactament a sobre de la superfície vermella això passa perque el que fa la preddicio es buscar quin valor de nota (alçada) correspon a una combinació concreta d’estudi. Podem veure que el punt d’abaix a l’esquerra es de l’alumne que te moltes absencies i ha estudiat molt poc, ja que casi la nota esta tocant el terra. En canvi la bola de dalt a la dreta correspont a l’alumne que ha ha estudiat molt i no ha ha faltat mai.
s3d= scatterplot3d(x = myData$studytime, y = myData$absences, z = myData$G3, angle = 60)
# 2. AFEGIM EL PLA VERMELL (El model)
s3d$plane3d(model_regressio, col = "red", draw_polygon = TRUE)
# 3. AFEGIM ELS PUNTS BLAUS (Les prediccions)
s3d$points3d(x = nous_estudiants$studytime,
y = nous_estudiants$absences,
z = resultat_final$fit,
col = "blue",
pch = 19,
cex = 2,
type = "h")
Finalment, farem un petit contrast d’anàlisi de variància; per fer-ho, crearem un nou model que serà el mateix que el de la pregunta però afegint la variable categòrica del sexe.
Per què? Volem saber si, a igualtat d’esforç i
assistència, ser home o dona penalitza o beneficia la nota. Si la
variable sex fos significativa, voldria dir que hi ha
factors externs (culturals, socials, família, etc.) que estem ignorant;
si no ho és, confirmem que els sistemes són iguals.
model_b = lm(G3 ~studytime+absences+sex, data=myData)
anova(model_regressio, model_b)
## Analysis of Variance Table
##
## Model 1: G3 ~ studytime + absences
## Model 2: G3 ~ studytime + absences + sex
## Res.Df RSS Df Sum of Sq F Pr(>F)
## 1 392 1267.8
## 2 391 1265.9 1 1.8621 0.5752 0.4487
Anàlisi de l’ANOVA: L’ANOVA ens dona un p-valor de 0.4487. Això ens indica que no hi ha evidència suficient per rebutjar la hipòtesi nul·la. Què vol dir això? Que les petites diferències de nota que puguem veure entre nois i noies són fruit de l’atzar, no d’un patró real. Afegir el gènere no redueix l’error del model de manera significativa.
Per estar-ne completament segurs, calculem manualment quant millora la capacitat explicativa del model (la variància explicada):
Observem que el \(R^2\) Ajustat del model amb sexe és una mica inferior al del model original. En estadística, quan afegim una variable i el R^2 Ajustat baixa (o no puja), significa que aquesta variable és irrellevant i no aporta valor important al model.
sqe0 = sum(residuals(lm(G3 ~ 1, data=myData))^2)
sqeB = sum(residuals(model_b)^2)
sqeA = sum(residuals(model_regressio)^2)
n = nrow(myData)
R2_b = 1-(sqeB/(n-4))/((sqe0)/(n-1))
R2_a=1-(sqeA/(n-3))/((sqe0)/(n-1))
R2_a
## [1] 0.6630316
R2_b
## [1] 0.662666
En l’anàlisi realitzada, hem pogut veure que el nostre model té una eficàcia molt alta, amb un valor de \(R^2 = 0.665\). Això ens indica que hem trobat les claus per explicar les notes. Les dades han revelat clarament que les hores d’estudi són el factor més important amb un impacte positiu: és a dir, quan més hores dedica l’alumne, més possibilitats té de treure millor nota. En canvi, les faltes d’assistència tenen un efecte clarament negatiu.
A més a més, hem utilitzat aquest model per realitzar prediccions sobre perfils hipotètics, demostrant que podem fer bones aproximacions amb precisió a la nota final d’un alumne (sigui un suspès o un excel·lent) només coneixent el seu esforç i assistència.
Pel que fa a la pregunta d’estudi (“Com afecten les hores d’estudi i les absències al rendiment?”), podem afirmar rotundament que sí, existeix una relació causal estadística entre aquestes variables. Els tests de significació han mostrat p-valors pràcticament de zero, la qual cosa confirma que aquests resultats són forts i no fruit de l’atzar. També hem fet una comprovació addicional per veure si el sexe era determinant, i hem confirmat mitjançant l’ANOVA que ser noi o noia no influeix significativament en el resultat final.
Una de les principals limitacions o dificultats que hem tingut no ha estat amb aquestes dades, sinó amb el procés previ. Vam haver de tornar a fer tot l’estudi des de zero perquè vam començar amb un conjunt de dades diferent (sobre plantes) que va resultar ser dolent: no tenia cap correlació ni variabilitat. Aquest canvi forçat ens ha permès, però, trobar aquest nou conjunt que sí que funciona perfectament per aplicar tècniques de regressió.
Els passos futurs que podríem fer serien intentar millorar encara més el model. Podríem buscar dades sobre l’entorn familiar per veure si això també afecta la nota.