Cieľom tejto analýzy je zistiť, ktoré faktory najviac ovplyvňujú výsledné skóre študentov na skúške. Dataset obsahuje údaje o čase venovanom štúdiu, spánku, dochádzke, predchádzajúcich výsledkoch a aktuálnom výsledku skúšky. Prostredníctvom regresnej analýzy skúmame, ako tieto premenné spolu súvisia a ktoré z nich majú na výkon študentov najväčší vplyv.
data <- read.csv("student_exam_scores.csv", header=TRUE)
str(data)
## 'data.frame': 200 obs. of 6 variables:
## $ student_id : chr "S001" "S002" "S003" "S004" ...
## $ hours_studied : num 8 1.3 4 3.5 9.1 8.4 10.8 2 5.6 1.3 ...
## $ sleep_hours : num 8.8 8.6 8.2 4.8 6.4 5.1 6 4.3 5.9 8.9 ...
## $ attendance_percent: num 72.1 60.7 73.7 95.1 89.8 58.5 54.2 75.8 81.6 66.8 ...
## $ previous_scores : int 45 55 86 66 71 75 88 55 84 70 ...
## $ exam_score : num 30.2 25 35.8 34 40.3 35.7 37.9 18.3 34.7 24.7 ...
summary(data)
## student_id hours_studied sleep_hours attendance_percent
## Length:200 Min. : 1.000 Min. :4.000 Min. : 50.30
## Class :character 1st Qu.: 3.500 1st Qu.:5.300 1st Qu.: 62.20
## Mode :character Median : 6.150 Median :6.700 Median : 75.25
## Mean : 6.325 Mean :6.622 Mean : 74.83
## 3rd Qu.: 9.000 3rd Qu.:8.025 3rd Qu.: 87.42
## Max. :12.000 Max. :9.000 Max. :100.00
## previous_scores exam_score
## Min. :40.0 Min. :17.10
## 1st Qu.:54.0 1st Qu.:29.50
## Median :67.5 Median :34.05
## Mean :66.8 Mean :33.95
## 3rd Qu.:80.0 3rd Qu.:38.75
## Max. :95.0 Max. :51.30
column_medians <- sapply(data, median, na.rm = TRUE)
data_imputed <- data
for (col in names(data)) {
data_imputed[[col]][is.na(data_imputed[[col]])] <- column_medians[col]
}
data <- data_imputed
model <- lm(exam_score ~ hours_studied + attendance_percent + previous_scores, data=data)
summary(model)
##
## Call:
## lm(formula = exam_score ~ hours_studied + attendance_percent +
## previous_scores, data = data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -6.9823 -2.5569 0.0532 2.5379 6.2655
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 5.02604 1.50433 3.341 0.000999 ***
## hours_studied 1.59599 0.06751 23.641 < 2e-16 ***
## attendance_percent 0.10978 0.01527 7.188 1.35e-11 ***
## previous_scores 0.15896 0.01392 11.418 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 3.064 on 196 degrees of freedom
## Multiple R-squared: 0.7994, Adjusted R-squared: 0.7963
## F-statistic: 260.3 on 3 and 196 DF, p-value: < 2.2e-16
xvars <- data[, c("hours_studied", "attendance_percent", "previous_scores")]
round(cor(xvars), 3)
## hours_studied attendance_percent previous_scores
## hours_studied 1.000 -0.031 0.069
## attendance_percent -0.031 1.000 0.052
## previous_scores 0.069 0.052 1.000
hours_studied & previous_scores Ak je medzi nimi stredná alebo vyššia korelácia, znamená to, že študenti, ktorí majú dobré výsledky z minulosti, majú často aj viac odštudovaných hodín. → V modeli to môže spôsobiť, že efekt „úsilia“ a „dlhodobého výkonu“ sa čiastočne prelieva.
hours_studied & attendance_percent Ak je korelácia nízka, znamená to, že dochádzka a študijný čas sú nezávislé správania. → Pre model je to dobré: každá premenná vysvetľuje inú časť variácie výsledkov.
attendance_percent & previous_scores Ak je korelácia stredná, znamená to, že študenti, ktorí majú lepšiu dochádzku, mali často aj lepšie predchádzajúce výsledky. → Môže to mierne nafúknuť neistotu koeficientov, ale nebýva to ohrozujúce. —
library(car)
vif(model)
## hours_studied attendance_percent previous_scores
## 1.006029 1.003939 1.007764
Ak má previous_scores vysoký VIF → znamená to, že je veľmi podobný inej premenné (zvyčajne hours_studied alebo attendance_percent). V praxi:
model má problém určiť, čo presne vysvetľujú minulé skóre a čo nová aktivita študenta
koeficient previous_scores bude nestabilný, môže meniť znamienko alebo veľkosť
Ak majú všetky premenné VIF < 5 → dáta nemajú problém s multikolinearitou → všetky efekty sú spoľahlivo oddeliteľné.
model_noGPA <- lm(exam_score ~ hours_studied + attendance_percent, data=data)
summary(model_noGPA)
##
## Call:
## lm(formula = exam_score ~ hours_studied + attendance_percent,
## data = data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -8.6345 -2.8849 -0.0802 2.9866 8.4354
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 14.59078 1.60831 9.072 < 2e-16 ***
## hours_studied 1.65060 0.08668 19.043 < 2e-16 ***
## attendance_percent 0.11925 0.01963 6.075 6.3e-09 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 3.944 on 197 degrees of freedom
## Multiple R-squared: 0.6659, Adjusted R-squared: 0.6625
## F-statistic: 196.3 on 2 and 197 DF, p-value: < 2.2e-16
model_noAttendance <- lm(exam_score ~ hours_studied + previous_scores, data=data)
summary(model_noAttendance)
##
## Call:
## lm(formula = exam_score ~ hours_studied + previous_scores, data = data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -8.8566 -2.1947 0.1192 2.3712 8.4391
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 12.98579 1.14157 11.38 <2e-16 ***
## hours_studied 1.57899 0.07565 20.87 <2e-16 ***
## previous_scores 0.16439 0.01559 10.55 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 3.436 on 197 degrees of freedom
## Multiple R-squared: 0.7465, Adjusted R-squared: 0.7439
## F-statistic: 290 on 2 and 197 DF, p-value: < 2.2e-16
Ak po odstránení previous_scores:
významnosť hours_studied narastie → znamená to, že previous_scores mu „kradlo“ časť vysvetlenej variability.
R² klesne → previous_scores bol dôležitou premennou pre predikciu.
Ak po odstránení attendance:
koeficient hours_studied sa skoro nezmení → znamená to, že attendance_percent nevysvetľoval nič, čo by sa prekrývalo s hours_studied.
R² ostane podobné → attendance_percent malo malý dopad na výsledky skúšky.
data$Hours_c <- scale(data$hours_studied)
data$Attend_c <- scale(data$attendance_percent)
data$Prev_c <- scale(data$previous_scores)
model_scaled <- lm(exam_score ~ Hours_c + Attend_c + Prev_c, data=data)
summary(model_scaled)
##
## Call:
## lm(formula = exam_score ~ Hours_c + Attend_c + Prev_c, data = data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -6.9823 -2.5569 0.0532 2.5379 6.2655
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 33.9550 0.2167 156.706 < 2e-16 ***
## Hours_c 5.1508 0.2179 23.641 < 2e-16 ***
## Attend_c 1.5644 0.2177 7.188 1.35e-11 ***
## Prev_c 2.4899 0.2181 11.418 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 3.064 on 196 degrees of freedom
## Multiple R-squared: 0.7994, Adjusted R-squared: 0.7963
## F-statistic: 260.3 on 3 and 196 DF, p-value: < 2.2e-16
vif(model_scaled)
## Hours_c Attend_c Prev_c
## 1.006029 1.003939 1.007764
Koeficienty sa stanú porovnateľné → môžeš vidieť, ktorá premenná hrá NAJVÄČŠIU rolu v predikcii exam_score. Napr.:
ak je |β(previous_scores)| najväčší → minulé výsledky majú najväčší vplyv
ak je najväčší |β(hours_studied)| → štúdium teraz má väčšiu váhu ako minulé skóre
VIF po škálovaní nezmizne (ak existoval) → ak previous_scores bolo zdrojom multikolinearity, ostane ním aj po škálovaní → škálovanie ovplyvňuje stabilitu numeriky, ale nie samotnú štruktúru dát.
Výsledky analýzy ukazujú, že na úspech študentov pri skúške najvýraznejšie vplývajú predchádzajúce akademické výsledky a počet hodín venovaných štúdiu. Dochádzka má menší, no stále samostatný príspevok k vysvetleniu variácie vo výsledkoch skúšky. Korelačná matica aj hodnoty VIF naznačujú, že medzi premennými existujú len mierne vzťahy, ktoré nepredstavujú vážny problém multikolinearity. Regresný model je preto stabilný a jeho koeficienty je možné spoľahlivo interpretovať. Celkovo môžeme povedať, že kombinácia dlhodobej výkonnosti študentov a ich aktuálneho študijného úsilia najpresnejšie predpovedá výsledné skóre na skúške.