data_raw <- read.csv(
"C:/Users/HP/OneDrive/berkasku/SEMESTER 5/ANMUL/data set uts anmul.csv",
sep = ";",
header = TRUE,
stringsAsFactors = FALSE
)
cat("DIMENSI DATA AWAL\n")
## DIMENSI DATA AWAL
print(dim(data_raw))
## [1] 649 33
cat("\nNAMA VARIABEL\n")
##
## NAMA VARIABEL
print(names(data_raw))
## [1] "school" "sex" "age" "address" "famsize"
## [6] "Pstatus" "Medu" "Fedu" "Mjob" "Fjob"
## [11] "reason" "guardian" "traveltime" "studytime" "failures"
## [16] "schoolsup" "famsup" "paid" "activities" "nursery"
## [21] "higher" "internet" "romantic" "famrel" "freetime"
## [26] "goout" "Dalc" "Walc" "health" "absences"
## [31] "G1" "G2" "G3"
cat("\nSTRUKTUR DATA\n")
##
## STRUKTUR DATA
str(data_raw)
## 'data.frame': 649 obs. of 33 variables:
## $ school : chr "GP" "GP" "GP" "GP" ...
## $ sex : chr "F" "F" "F" "F" ...
## $ age : int 18 17 15 15 16 16 16 17 15 15 ...
## $ address : chr "U" "U" "U" "U" ...
## $ famsize : chr "GT3" "GT3" "LE3" "GT3" ...
## $ Pstatus : chr "A" "T" "T" "T" ...
## $ Medu : int 4 1 1 4 3 4 2 4 3 3 ...
## $ Fedu : int 4 1 1 2 3 3 2 4 2 4 ...
## $ Mjob : chr "at_home" "at_home" "at_home" "health" ...
## $ Fjob : chr "teacher" "other" "other" "services" ...
## $ reason : chr "course" "course" "other" "home" ...
## $ guardian : chr "mother" "father" "mother" "mother" ...
## $ traveltime: int 2 1 1 1 1 1 1 2 1 1 ...
## $ studytime : int 2 2 2 3 2 2 2 2 2 2 ...
## $ failures : int 0 0 0 0 0 0 0 0 0 0 ...
## $ schoolsup : chr "yes" "no" "yes" "no" ...
## $ famsup : chr "no" "yes" "no" "yes" ...
## $ paid : chr "no" "no" "no" "no" ...
## $ activities: chr "no" "no" "no" "yes" ...
## $ nursery : chr "yes" "no" "yes" "yes" ...
## $ higher : chr "yes" "yes" "yes" "yes" ...
## $ internet : chr "no" "yes" "yes" "yes" ...
## $ romantic : chr "no" "no" "no" "yes" ...
## $ famrel : int 4 5 4 3 4 5 4 4 4 5 ...
## $ freetime : int 3 3 3 2 3 4 4 1 2 5 ...
## $ goout : int 4 3 2 2 2 2 4 4 2 1 ...
## $ Dalc : int 1 1 2 1 1 1 1 1 1 1 ...
## $ Walc : int 1 1 3 1 2 2 1 1 1 1 ...
## $ health : int 3 3 3 5 5 5 3 1 1 5 ...
## $ absences : int 4 2 6 0 0 6 0 2 0 0 ...
## $ G1 : int 0 9 12 14 11 12 13 10 15 12 ...
## $ G2 : int 11 11 13 14 13 12 12 13 16 12 ...
## $ G3 : int 11 11 12 14 13 13 13 13 17 13 ...
cat("\nLIMA BARIS PERTAMA\n")
##
## LIMA BARIS PERTAMA
print(head(data_raw))
## school sex age address famsize Pstatus Medu Fedu Mjob Fjob reason
## 1 GP F 18 U GT3 A 4 4 at_home teacher course
## 2 GP F 17 U GT3 T 1 1 at_home other course
## 3 GP F 15 U LE3 T 1 1 at_home other other
## 4 GP F 15 U GT3 T 4 2 health services home
## 5 GP F 16 U GT3 T 3 3 other other home
## 6 GP M 16 U LE3 T 4 3 services other reputation
## guardian traveltime studytime failures schoolsup famsup paid activities
## 1 mother 2 2 0 yes no no no
## 2 father 1 2 0 no yes no no
## 3 mother 1 2 0 yes no no no
## 4 mother 1 3 0 no yes no yes
## 5 father 1 2 0 no yes no no
## 6 mother 1 2 0 no yes no yes
## nursery higher internet romantic famrel freetime goout Dalc Walc health
## 1 yes yes no no 4 3 4 1 1 3
## 2 no yes yes no 5 3 3 1 1 3
## 3 yes yes yes no 4 3 2 2 3 3
## 4 yes yes yes yes 3 2 2 1 1 5
## 5 yes yes no no 4 3 2 1 2 5
## 6 yes yes yes no 5 4 2 1 2 5
## absences G1 G2 G3
## 1 4 0 11 11
## 2 2 9 11 11
## 3 6 12 13 12
## 4 0 14 14 14
## 5 0 11 13 13
## 6 6 12 12 13
cat("\nJUMLAH MISSING VALUE PER VARIABEL\n")
##
## JUMLAH MISSING VALUE PER VARIABEL
print(colSums(is.na(data_raw)))
## school sex age address famsize Pstatus Medu
## 0 0 0 0 0 0 0
## Fedu Mjob Fjob reason guardian traveltime studytime
## 0 0 0 0 0 0 0
## failures schoolsup famsup paid activities nursery higher
## 0 0 0 0 0 0 0
## internet romantic famrel freetime goout Dalc Walc
## 0 0 0 0 0 0 0
## health absences G1 G2 G3
## 0 0 0 0 0
cat("\nJUMLAH BARIS DUPLIKAT PADA DATA AWAL\n")
##
## JUMLAH BARIS DUPLIKAT PADA DATA AWAL
print(sum(duplicated(data_raw)))
## [1] 0
# ============================================================
# CLEANING DAN PREPROCESSING
# ============================================================
variabel_pilih <- c(
"G3", "studytime", "failures",
"absences", "Medu", "Fedu"
)
# Memastikan semua variabel yang dibutuhkan tersedia
if (!all(variabel_pilih %in% names(data_raw))) {
stop("Ada variabel yang tidak ditemukan. Periksa nama kolom data.")
}
data_pilih <- data_raw[, variabel_pilih, drop = FALSE]
# Konversi ke numerik
data_pilih[] <- lapply(data_pilih, function(x) {
as.numeric(as.character(x))
})
# Hitung data yang hilang setelah konversi
cat("\nMISSING VALUE PADA VARIABEL PENELITIAN\n")
##
## MISSING VALUE PADA VARIABEL PENELITIAN
print(colSums(is.na(data_pilih)))
## G3 studytime failures absences Medu Fedu
## 0 0 0 0 0 0
# Hapus baris dengan missing value
data_bersih <- data_pilih[complete.cases(data_pilih), ]
# Memeriksa rentang nilai yang valid
baris_valid <- with(
data_bersih,
G3 >= 0 & G3 <= 20 &
studytime %in% 1:4 &
failures >= 0 & failures <= 4 &
absences >= 0 &
Medu %in% 0:4 &
Fedu %in% 0:4
)
data_bersih <- data_bersih[baris_valid, , drop = FALSE]
if (nrow(data_bersih) < 10) {
stop("Data valid terlalu sedikit. Periksa format dan isi CSV.")
}
cat("\nJUMLAH BARIS DATA AWAL:", nrow(data_raw), "\n")
##
## JUMLAH BARIS DATA AWAL: 649
cat("JUMLAH BARIS DATA BERSIH:", nrow(data_bersih), "\n")
## JUMLAH BARIS DATA BERSIH: 649
cat("JUMLAH BARIS YANG TIDAK DIGUNAKAN:",
nrow(data_raw) - nrow(data_bersih), "\n")
## JUMLAH BARIS YANG TIDAK DIGUNAKAN: 0
cat("\nDUPLIKASI PADA VARIABEL TERPILIH:",
sum(duplicated(data_bersih)), "\n")
##
## DUPLIKASI PADA VARIABEL TERPILIH: 103
print(summary(data_bersih))
## G3 studytime failures absences
## Min. : 0.00 Min. :1.000 Min. :0.0000 Min. : 0.000
## 1st Qu.:10.00 1st Qu.:1.000 1st Qu.:0.0000 1st Qu.: 0.000
## Median :12.00 Median :2.000 Median :0.0000 Median : 2.000
## Mean :11.91 Mean :1.931 Mean :0.2219 Mean : 3.659
## 3rd Qu.:14.00 3rd Qu.:2.000 3rd Qu.:0.0000 3rd Qu.: 6.000
## Max. :19.00 Max. :4.000 Max. :3.0000 Max. :32.000
## Medu Fedu
## Min. :0.000 Min. :0.000
## 1st Qu.:2.000 1st Qu.:1.000
## Median :2.000 Median :2.000
## Mean :2.515 Mean :2.307
## 3rd Qu.:4.000 3rd Qu.:3.000
## Max. :4.000 Max. :4.000
write.csv(
data_bersih,
"output/student_por_bersih.csv",
row.names = FALSE
)
# ============================================================
# EXPLORATORY DATA ANALYSIS (EDA)
# ============================================================
statistik_deskriptif <- data.frame(
Variabel = names(data_bersih),
Jumlah = sapply(data_bersih, length),
Mean = sapply(data_bersih, mean),
Median = sapply(data_bersih, median),
Standar_Deviasi = sapply(data_bersih, sd),
Minimum = sapply(data_bersih, min),
Maksimum = sapply(data_bersih, max)
)
cat("\nSTATISTIK DESKRIPTIF\n")
##
## STATISTIK DESKRIPTIF
print(statistik_deskriptif, row.names = FALSE)
## Variabel Jumlah Mean Median Standar_Deviasi Minimum Maksimum
## G3 649 11.9060092 12 3.2306562 0 19
## studytime 649 1.9306626 2 0.8295096 1 4
## failures 649 0.2218798 0 0.5932351 0 3
## absences 649 3.6594761 2 4.6407588 0 32
## Medu 649 2.5146379 2 1.1345520 0 4
## Fedu 649 2.3066256 2 1.0999309 0 4
# Histogram nilai akhir
hist(
data_bersih$G3,
main = "Distribusi Nilai Akhir Bahasa Portugis",
xlab = "Nilai Akhir (G3)",
ylab = "Frekuensi",
col = "#F4B6C2",
border = "white",
breaks = seq(-0.5, 20.5, by = 1)
)

# Boxplot nilai akhir
boxplot(
data_bersih$G3,
main = "Sebaran Nilai Akhir Siswa",
ylab = "Nilai Akhir (G3)",
col = "#C9B6E4",
border = "#8E78B7"
)

# Nilai akhir berdasarkan waktu belajar
boxplot(
G3 ~ factor(studytime),
data = data_bersih,
main = "Nilai Akhir Berdasarkan Waktu Belajar",
xlab = "Waktu Belajar per Minggu",
ylab = "Nilai Akhir (G3)",
names = c("<2 jam", "2-5 jam", "5-10 jam", ">10 jam"),
col = c("#F4B6C2", "#F8D7A3", "#B9DCC4", "#B8D4F0")
)

# Nilai akhir berdasarkan jumlah kegagalan kelas sebelumnya
boxplot(
G3 ~ factor(failures),
data = data_bersih,
main = "Nilai Akhir Berdasarkan Kegagalan Kelas",
xlab = "Jumlah Kegagalan Sebelumnya",
ylab = "Nilai Akhir (G3)",
col = "#D6C6F0"
)

# Ketidakhadiran dan nilai akhir
plot(
data_bersih$absences,
data_bersih$G3,
main = "Ketidakhadiran dan Nilai Akhir",
xlab = "Jumlah Ketidakhadiran",
ylab = "Nilai Akhir (G3)",
pch = 19,
col = "#91B8E8"
)

# Matriks korelasi untuk eksplorasi awal
cat("\nMATRIKS KORELASI\n")
##
## MATRIKS KORELASI
print(round(cor(data_bersih), 3))
## G3 studytime failures absences Medu Fedu
## G3 1.000 0.250 -0.393 -0.091 0.240 0.212
## studytime 0.250 1.000 -0.147 -0.118 0.097 0.050
## failures -0.393 -0.147 1.000 0.123 -0.172 -0.166
## absences -0.091 -0.118 0.123 1.000 -0.009 0.030
## Medu 0.240 0.097 -0.172 -0.009 1.000 0.647
## Fedu 0.212 0.050 -0.166 0.030 0.647 1.000
# ============================================================
# REGRESI LINEAR BERGANDA (MODEL AWAL)
# ============================================================
model_mlr <- lm(
G3 ~ studytime + failures + absences + Medu + Fedu,
data = data_bersih
)
cat("\nRINGKASAN MODEL MLR AWAL\n")
##
## RINGKASAN MODEL MLR AWAL
print(summary(model_mlr))
##
## Call:
## lm(formula = G3 ~ studytime + failures + absences + Medu + Fedu,
## data = data_bersih)
##
## Residuals:
## Min 1Q Median 3Q Max
## -13.2913 -1.4828 0.0462 1.7584 6.7766
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 9.67420 0.41028 23.580 < 2e-16 ***
## studytime 0.71017 0.13811 5.142 3.61e-07 ***
## failures -1.79892 0.19584 -9.186 < 2e-16 ***
## absences -0.02113 0.02457 -0.860 0.3900
## Medu 0.33845 0.13083 2.587 0.0099 **
## Fedu 0.21074 0.13466 1.565 0.1181
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 2.861 on 643 degrees of freedom
## Multiple R-squared: 0.222, Adjusted R-squared: 0.2159
## F-statistic: 36.69 on 5 and 643 DF, p-value: < 2.2e-16
# ============================================================
# SELEKSI VARIABEL DENGAN AIC
# ============================================================
model_aic <- step(
model_mlr,
direction = "both",
trace = 0
)
cat("\nMODEL TERPILIH BERDASARKAN AIC\n")
##
## MODEL TERPILIH BERDASARKAN AIC
print(formula(model_aic))
## G3 ~ studytime + failures + Medu + Fedu
cat("\nRINGKASAN MODEL AIC\n")
##
## RINGKASAN MODEL AIC
print(summary(model_aic))
##
## Call:
## lm(formula = G3 ~ studytime + failures + Medu + Fedu, data = data_bersih)
##
## Residuals:
## Min 1Q Median 3Q Max
## -13.2116 -1.5352 0.0557 1.7884 6.8962
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 9.5868 0.3974 24.123 < 2e-16 ***
## studytime 0.7223 0.1374 5.258 1.98e-07 ***
## failures -1.8179 0.1946 -9.344 < 2e-16 ***
## Medu 0.3405 0.1308 2.604 0.00944 **
## Fedu 0.2045 0.1344 1.521 0.12863
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 2.86 on 644 degrees of freedom
## Multiple R-squared: 0.2211, Adjusted R-squared: 0.2163
## F-statistic: 45.7 on 4 and 644 DF, p-value: < 2.2e-16
cat("\nPERBANDINGAN AIC MODEL\n")
##
## PERBANDINGAN AIC MODEL
print(AIC(model_mlr, model_aic))
## df AIC
## model_mlr 7 3214.021
## model_aic 6 3212.767
# ============================================================
# UJI ASUMSI MODEL TERPILIH
# ============================================================
if (!requireNamespace("car", quietly = TRUE)) {
}
if (!requireNamespace("lmtest", quietly = TRUE)) {
}
if (!requireNamespace("sandwich", quietly = TRUE)) {
}
# Normalitas residual
cat("\nUJI NORMALITAS RESIDUAL\n")
##
## UJI NORMALITAS RESIDUAL
if (length(residuals(model_aic)) <= 5000) {
print(shapiro.test(residuals(model_aic)))
} else {
cat("Jumlah residual melebihi batas Shapiro-Wilk.\n")
}
##
## Shapiro-Wilk normality test
##
## data: residuals(model_aic)
## W = 0.93736, p-value = 7.048e-16
# Multikolinearitas
cat("\nUJI MULTIKOLINEARITAS (VIF)\n")
##
## UJI MULTIKOLINEARITAS (VIF)
print(car::vif(model_aic))
## studytime failures Medu Fedu
## 1.028488 1.055210 1.744130 1.732135
# Heteroskedastisitas
cat("\nUJI BREUSCH-PAGAN\n")
##
## UJI BREUSCH-PAGAN
print(lmtest::bptest(model_aic))
##
## studentized Breusch-Pagan test
##
## data: model_aic
## BP = 13.032, df = 4, p-value = 0.01112
# ============================================================
# ROBUST STANDARD ERRORS
# ============================================================
cat("\nKOEFISIEN DENGAN ROBUST STANDARD ERRORS HC3\n")
##
## KOEFISIEN DENGAN ROBUST STANDARD ERRORS HC3
hasil_robust <- lmtest::coeftest(
model_aic,
vcov. = sandwich::vcovHC(model_aic, type = "HC3")
)
print(hasil_robust)
##
## t test of coefficients:
##
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 9.58679 0.38977 24.5962 < 2.2e-16 ***
## studytime 0.72230 0.13301 5.4305 7.971e-08 ***
## failures -1.81795 0.22123 -8.2176 1.142e-15 ***
## Medu 0.34051 0.13826 2.4628 0.01405 *
## Fedu 0.20454 0.14244 1.4360 0.15150
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# ============================================================
# GRAFIK DIAGNOSTIK MODEL TERPILIH
# ============================================================
par(
mfrow = c(2, 2),
bg = "white",
mar = c(4, 4, 3, 1)
)
plot(model_aic, which = 1, col = "#E78FB3", pch = 19)
plot(model_aic, which = 2, col = "#91B8E8", pch = 19)
plot(model_aic, which = 3, col = "#A8CFA8", pch = 19)
plot(model_aic, which = 5, col = "#C3A6E8", pch = 19)

par(mfrow = c(1, 1))