Latar Belakang
Pada projek kali ini, kita akan memprediksi tingkat kelulusan mahasiswa dalam mendaftar universitas yang sesuai dengan profil mereka. Projek ini ditujukan bagi mahasiswa yang ingin mengetahui tingkat kelulusan mereka dalam mendaftar suatu universitas.
Library
library(dplyr) # untuk data wrangling
library(GGally) # untuk mengecek korelasi
library(Metrics) # untuk melakukan evaluasi model
library(car) # untuk mengecek multikolinearitas
Persiapan Data
Data yang akan kita gunakan pada projek ini berasal dari website Kaggle.
adm <- read.csv("Admission_Predict_Ver1.1.csv")
str(adm)
## 'data.frame': 500 obs. of 9 variables:
## $ Serial.No. : int 1 2 3 4 5 6 7 8 9 10 ...
## $ GRE.Score : int 337 324 316 322 314 330 321 308 302 323 ...
## $ TOEFL.Score : int 118 107 104 110 103 115 109 101 102 108 ...
## $ University.Rating: int 4 4 3 3 2 5 3 2 1 3 ...
## $ SOP : num 4.5 4 3 3.5 2 4.5 3 3 2 3.5 ...
## $ LOR : num 4.5 4.5 3.5 2.5 3 3 4 4 1.5 3 ...
## $ CGPA : num 9.65 8.87 8 8.67 8.21 9.34 8.2 7.9 8 8.6 ...
## $ Research : int 1 1 1 1 0 1 1 0 0 0 ...
## $ Chance.of.Admit : num 0.92 0.76 0.72 0.8 0.65 0.9 0.75 0.68 0.5 0.45 ...
Pada dataset yang akan kita pakai, kita akan mengubah tipe data pada kolom Research menjadi faktor.
adm <- adm %>%
mutate(Research = as.factor(Research)) %>%
select(-c(Serial.No.))
Kemudian kita cek apakah dalam data kita terdapat missing value
anyNA(adm)
## [1] FALSE
Karena hasilnya False, berarti data kita sudah aman dari missing value.
Selanjutnya, kita akan menggunakan ggcorr dari package GGally untuk mengecek apakah terdapat korelasi di antara variabelnya.
ggcorr(adm, label = T, hjust = 1, layout.exp = 3)
## Warning in ggcorr(adm, label = T, hjust = 1, layout.exp = 3): data in column(s)
## 'Research' are not numeric and were ignored
# Train-Test Split Sebelum melakukan pemodelan, kita akan membagi data menjadi data train dan data test. Data test nantinya akan digunakan untuk menguji apakah model dapat melakukan prediksi terhadap unseen data.
RNGkind(sample.kind = "Rounding")
## Warning in RNGkind(sample.kind = "Rounding"): non-uniform 'Rounding' sampler
## used
set.seed(417)
index <- sample(nrow(adm), nrow(adm)*0.8)
adm_train <- adm[index,]
adm_test <- adm[-index,]
Model Fitting
Dari proses eksplorasi data, diketahui bahwa hampir semua variabel menunjukkan korelasi yang kuat dengan variabel Chance.of.Admit. Namun, variabel yang memiliki korelasi paling kuat dengan variabel Chance.of.Admit adalah variabel CGPA. Maka, untuk model pertama, kita akan membuat model regresi menggunakan fungsi lm() untuk memprediksi Chance.of.Admit berdasarkan CGPA. Kemudian, kita cek summary dari model tersebut.
model_coa <- lm(Chance.of.Admit ~ CGPA, adm_train)
summary(model_coa)
##
## Call:
## lm(formula = Chance.of.Admit ~ CGPA, data = adm_train)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.278658 -0.026732 0.007236 0.038514 0.173809
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -1.026711 0.045939 -22.35 <2e-16 ***
## CGPA 0.204113 0.005343 38.20 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.06591 on 398 degrees of freedom
## Multiple R-squared: 0.7857, Adjusted R-squared: 0.7852
## F-statistic: 1459 on 1 and 398 DF, p-value: < 2.2e-16
Dari output di atas, dapat kita lihat bahwa nilai Multiple R-Squared dari model adalah sebesar 0.7857. Kemudian, slope (kemiringan) dari CGPA menunjukkan nilai yang positif yaitu sebesar 0.204113 dan signifikan secara statistik (p-value lebih kecil dari 0.05).
Kemudian, kita akan mencoba membuat model regresi baru dengan menggunakan semua variabel prediktor.
model_coa_all <- lm(Chance.of.Admit ~ ., adm_train)
summary(model_coa_all)
##
## Call:
## lm(formula = Chance.of.Admit ~ ., data = adm_train)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.270700 -0.023131 0.009303 0.033413 0.149355
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -1.2433991 0.1148134 -10.830 < 2e-16 ***
## GRE.Score 0.0017262 0.0005603 3.081 0.00221 **
## TOEFL.Score 0.0030926 0.0009802 3.155 0.00173 **
## University.Rating 0.0051267 0.0044043 1.164 0.24512
## SOP 0.0072423 0.0051493 1.406 0.16038
## LOR 0.0120247 0.0046033 2.612 0.00934 **
## CGPA 0.1157812 0.0106360 10.886 < 2e-16 ***
## Research1 0.0242427 0.0073516 3.298 0.00106 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.05953 on 392 degrees of freedom
## Multiple R-squared: 0.8278, Adjusted R-squared: 0.8247
## F-statistic: 269.2 on 7 and 392 DF, p-value: < 2.2e-16
Dapat kita lihat dari output di atas, nilai Adjusted R-Squared menunjukkan 0.8247, yaitu lebih tinggi dari model sebelumnya. Kemudian, tidak semua variabel menunjukkan hasil yang signifikan secara statistik.
Kemudian untuk model terakhir, kita akan menggunakan salah satu teknik pemilihan variabel prediktor dengan algoritma stepwise regression. Kita akan menggunakan fungsi step() dengan parameter direction = "backward".
model_backward <- step(object = model_coa_all,
direction = "backward",
trace = F)
summary(model_backward)
##
## Call:
## lm(formula = Chance.of.Admit ~ GRE.Score + TOEFL.Score + SOP +
## LOR + CGPA + Research, data = adm_train)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.271478 -0.025299 0.008715 0.033685 0.149731
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -1.2778948 0.1109730 -11.515 < 2e-16 ***
## GRE.Score 0.0017627 0.0005597 3.149 0.001762 **
## TOEFL.Score 0.0031991 0.0009764 3.276 0.001144 **
## SOP 0.0095475 0.0047554 2.008 0.045356 *
## LOR 0.0127637 0.0045614 2.798 0.005392 **
## CGPA 0.1177694 0.0105027 11.213 < 2e-16 ***
## Research1 0.0244923 0.0073518 3.331 0.000946 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.05956 on 393 degrees of freedom
## Multiple R-squared: 0.8272, Adjusted R-squared: 0.8246
## F-statistic: 313.6 on 6 and 393 DF, p-value: < 2.2e-16
Dari output hasil di atas, dapat dilihat bahwa nilai Adjusted R-Squared-nya sebesar 0.8246, lebih besar dari model yang hanya menggunakan variabel prediktor CGPA serta hampir sama dengan model yang menggunakan semua variabel prediktor. Kemudian, dapat kita lihat juga bahwa semua variabel prediktornya menunjukkan hasil yang signifikan secara statistik.
Prediksi
Selanjutnya, kita akan melakukan prediksi dengan menggunakan data adm_test. kita akan menggunakan semua model untuk membandingkan model mana yang memiliki performa paling baik.
pred_coa <- predict(model_coa, newdata = adm_test)
pred_coa_all <- predict(model_coa_all, newdata = adm_test)
pred_model_backward <- predict(model_backward, newdata = adm_test)
Untuk membandingkan performa ketiga model, kita dapat melihatnya dari nilai r squared (untuk model dengan 1 prediktor) dan adjusted r square (untuk model yang lebih dari 1 prediktor).
summary(model_coa)$r.squared # pakai r.squared (multiple r squared) karena 1 prediktor
## [1] 0.7857312
summary(model_coa_all)$adj.r.squared
## [1] 0.8247485
summary(model_backward)$adj.r.squared
## [1] 0.8245902
Kita juga dapat mengevaluasi dari nilai error model. Untuk kasus ini, kita akan menggunakan metrics RMSE.
rmse(predicted = pred_coa, actual = adm_test$Chance.of.Admit)
## [1] 0.06885397
rmse(predicted = pred_coa_all, actual = adm_test$Chance.of.Admit)
## [1] 0.06255868
rmse(predicted = pred_model_backward, actual = adm_test$Chance.of.Admit)
## [1] 0.06287739
dari output di atas, dapat kita lihat bahwa model yang menggunakan semua prediktor memiliki nilai adjusted r squared yang paling besar. Selain itu, model ini juga memiliki nilai error yang paling kecil. Oleh karena itu, model yang akan kita gunakan yaitu model model_coa_all
Uji Asumsi
Normalitas Residual
Salah satu asumsi model regresi linier menyatakan bahwa error yang diperoleh dari model harus terdistribusi secara normal di sekitar mean 0. Kita akan memvalidasi asumsi ini dengan melakukan visualisasi error dari data
# visualisasi residual/errror
hist(model_coa_all$residuals)
Selain itu, kita juga melakukan uji asumsi dengan menggunakan
shapiro.test()
# uji asumsi dengan shapiro.test()
shapiro.test(model_coa_all$residuals)
##
## Shapiro-Wilk normality test
##
## data: model_coa_all$residuals
## W = 0.92043, p-value = 1.03e-13
Shapiro-Wilk hypothesis test:
H0: error/residual berdistribusi normalH1: error/residual tidak berdistribusi normal
Kesimpulan: Dari hasil visualisasi serta hasil uji shapiro wilk, dapat kita simpulkan bahwa error/residual tidak berdistribusi normal, maka uji asumsi normalitas tidak terpenuhi.
Homoskedastisitas
Asumsi lain yang perlu diuji adalah apakah error pada model terdistribusi dengan variansi yang sama/konstan di rentang data yang berbeda atau tidak. Kita bisa melakukan visualisasi antara fitted values (hasil prediksi ke data untuk training model) dengan error. Kemudian, kita bisa melakukan uji kembali dengan fungsi bptest dari packagelmtest.
# visualisasi fitted values vs residual/error
plot(model_coa_all$fitted.values, model_coa_all$residuals)
abline(h=0, col="red")
# uji asumsi dengan bptest()
library(lmtest)
## Loading required package: zoo
##
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
bptest(model_coa_all)
##
## studentized Breusch-Pagan test
##
## data: model_coa_all
## BP = 23.496, df = 7, p-value = 0.001396
Breusch-Pagan hypothesis test:
- H0: error menyebar konstan (Homoscedasticity)
- H1: error menyebar tidak konstan/membentuk pola (Heteroscedasticity)
Kesimpulan: Dari hasil visualisasi serta hasil uji breusch-Pagan, dapat disimpulkan bahwa error menyebar tidak konstan/membentuk pola sehingga terdapat heteroscedasticity, maka uji asumsi homoskedastisitas tidak terpenuhi.
Multikolinearitas
Dengan menggunakan nilai VIF, kita dapat menentukan ada tidaknya multikolinearitas antar variabel prediktor. Nilai VIF yang tinggi menunjukkan korelasi yang tinggi antar variabel prediktor. Kita dapat menggunakan fungsi vif dari packagecar.
# uji asumsi dengan vif()
vif(model_coa_all)
## GRE.Score TOEFL.Score University.Rating SOP
## 4.667379 4.136433 2.818546 2.892376
## LOR CGPA Research
## 2.019346 4.857383 1.504708
Penentuan:
- nilai VIF > 10 : ada multicollinearity
- nilai VIF < 10 : tidak ada multicollinearity
Kesimpulan: Karena semua nilai VIF < 0, sehingga dapat disimpulkan bahwa tidak terdapat multicollinearity, uji asumsi pun terpenuhi
Kesimpulan
Kita dapat memprediksi tingkat kelulusan mahasiswa yang mendaftar suatu universitas dengan menggunakan model_coa_all. Model tersebut menggunakan seluruh prediktor yang ada. Model ini merupakan model terbaik karena memiliki nilai adjusted r squared yang terbaik yaitu sebesar 0.8247485 atau 82.47% serta memiliki nilai error yang paling kecil yaitu sebesar 0.06255868.
Akan tetapi, sangat disayangkan bahwa untuk uji asumsi model tersebut, untuk uji asumsi normalitas dan homoskedastisitas belum terpenuhi. Maka dari itu, penggunaan model ini belum menjadi pilihan yang terbaik.