This is an R Markdown document. Markdown is a simple formatting syntax for authoring HTML, PDF, and MS Word documents. For more details on using R Markdown see http://rmarkdown.rstudio.com.
When you click the Knit button a document will be generated that includes both content as well as the output of any embedded R code chunks within the document. You can embed an R code chunk like this:
summary(cars)
## speed dist
## Min. : 4.0 Min. : 2.00
## 1st Qu.:12.0 1st Qu.: 26.00
## Median :15.0 Median : 36.00
## Mean :15.4 Mean : 42.98
## 3rd Qu.:19.0 3rd Qu.: 56.00
## Max. :25.0 Max. :120.00
You can also embed plots, for example:
Note that the echo = FALSE
parameter was added to the
code chunk to prevent printing of the R code that generated the
plot.
1. Dataset
Sumber Dataset : Kaggle dengan tema data ujian mahasiswa
Jumlah Data : - Baris (records) : 111 - Kolom (variable) : 9
Jenis Variabel Dalam Dataset :
ID = Kode unik untuk tiap mahasiswa (character)
Nama = Nama mahasiswa (character)
Umur = Usia mahasiswa (numeric/continuous)
Gender = Jenis Kelamin mahasiswa (factor/kategori : laki-laki, perempuan)
Nilai = Nilai total/akhir mahasiswa (numeric/continuous)
Matkul = Mata kuliah yang diambil (factor/kategori)
Tanggal = Tanggal ujian (character)
UTS = Nilai Ujian Tengah Semester (numeric)
UAS = Nilai Ujian Akhir Semester (numeric)
Dataset ini merupakan gabungan variable kategorikal dan numerik yang dapat digunakan untuk analisis deskriptif maupun inferensial, khususnya dalam melihat distribusi nilai mahasiswa berdasarkan factor umur, gender, dan mata kuliah.
Tahap-tahap Pre Processing
1.Data Wrangling
Pada awal proses, informasi ujian mahasiswa dimuat dengan menggunakan fungsi read. csv(). Data ini mencakup rincian seperti nama mahasiswa, tanggal ujian, jenis kelamin, mata kuliah, ID, usia, nilai, UTS, dan UAS. Setelah itu, tipe data perlu disesuaikan agar sesuai dengan karakteristik masing-masing variabel. Contohnya, variabel Nama dan ID diubah menjadi karakter, sedangkan Gender dan Matkul dijadikan faktor, sementara Umur, Nilai, UTS, dan UAS dikonversi menjadi numerik. Selain itu, struktur data juga dimodifikasi dengan fungsi pivot_longer() sehingga kolom UTS dan UAS dapat dikelola dengan lebih fleksibel. Hasil dari tahap ini adalah sebuah dataset yang terstruktur rapi dan konsisten untuk keperluan analisis lebih lanjut.
getwd()
## [1] "C:/Users/ASUS"
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(tidyr)
library(readr)
data_ujian <- read.csv("data ujian.csv", stringsAsFactors = FALSE)
View(data_ujian)
glimpse(data_ujian)
## Rows: 111
## Columns: 9
## $ ID <chr> "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12",…
## $ Nama <chr> "Budi", "Ani", "Joko", "Siti", "Agus", "Dewi", "Eka", "Adi", "…
## $ Umur <int> 24, 21, 20, 21, 23, 21, 21, 23, 22, 24, 23, 22, 22, 20, 22, 23…
## $ Gender <chr> "Laki-laki", "Perempuan", "Laki-laki", "Perempuan", "Laki-laki…
## $ Nilai <dbl> 85.0, 77.5, 90.0, 60.0, 77.5, 85.0, 90.0, 67.5, 75.0, 82.5, 83…
## $ Matkul <chr> "Kimia", "Matematika", "Biologi", "Matematika", "Fisika", "Bio…
## $ Tanggal <chr> "9/8/2023", "15/8/2023", "15/8/2023", "9/8/2023", "9/8/2023", …
## $ UTS <int> 90, 75, 85, 55, 80, 75, 85, 70, 80, 85, 79, 95, 94, 88, 88, 74…
## $ UAS <int> 80, 80, 95, 65, 75, 95, 95, 65, 70, 80, 88, 85, 81, 91, 85, 84…
summary(data_ujian)
## ID Nama Umur Gender
## Length:111 Length:111 Min. :20.00 Length:111
## Class :character Class :character 1st Qu.:21.00 Class :character
## Mode :character Mode :character Median :22.00 Mode :character
## Mean :21.95
## 3rd Qu.:23.00
## Max. :24.00
## NA's :11
## Nilai Matkul Tanggal UTS
## Min. :60.00 Length:111 Length:111 Min. :55.00
## 1st Qu.:78.50 Class :character Class :character 1st Qu.:76.00
## Median :82.75 Mode :character Mode :character Median :83.00
## Mean :82.50 Mean :82.78
## 3rd Qu.:86.50 3rd Qu.:88.00
## Max. :94.00 Max. :95.00
## NA's :11 NA's :11
## UAS
## Min. :65.00
## 1st Qu.:75.00
## Median :81.50
## Mean :82.21
## 3rd Qu.:90.00
## Max. :95.00
## NA's :11
suppressPackageStartupMessages(library(dplyr))
perintah ini membaca file data ujian.csv ke R, menampilkan datanya, dan memberi ringkasan kolom serta tipe datanya. Paket dplyr, tidyr, dan readr digunakan untuk memudahkan manipulasi dan rapikan data
data_ujian <- data_ujian %>%
mutate(
Nama = as.character(Nama),
Tanggal = as.character(Tanggal),
Gender = as.factor(Gender),
Matkul = as.factor(Matkul),
ID = as.character(ID),
Umur = as.numeric(Umur),
Nilai = as.numeric(Nilai),
UTS = as.numeric(UTS),
UAS = as.numeric(UAS)
)
data_long <- data_ujian %>%
pivot_longer(cols = c(UTS, UAS),
names_to = "Jenis_ujian",
values_to = "Skor")
head(data_long)
Perintah diatas mengubah tipe data kolom sesuai kebutuhan, lalu merapikan data dari lebar ke panjang sehingga kolom UTS dan UAS digabung menjadi Jenis_ujian dan skor
2. Data Cleaning
Tahap pembersihan data dilakukan dengan memeriksa nilai hilang (NA) serta string kosong, kemudian menghapusnya agar data tidak bias. Selanjutnya, data duplikat diperiksa menggunakan fungsi duplicated() dan dihapus bila ditemukan. Deteksi outlier dilakukan dengan metode Interquartile Range (IQR) pada variabel Nilai. Nilai yang berada di luar batas bawah dan batas atas dianggap sebagai outlier. Data tersebut kemudian difilter sehingga hanya nilai yang wajar dan representatif yang dipertahankan. Dengan demikian, dataset yang digunakan sudah bebas dari nilai hilang, duplikasi, dan outlier ekstrem.
colSums(is.na(data_ujian))
## ID Nama Umur Gender Nilai Matkul Tanggal UTS UAS
## 0 0 11 0 11 0 0 11 11
data_ujian_clean <- data_ujian %>%
filter(
!(is.na(Umur) & is.na(Nilai) & is.na(UTS) & is.na(UAS))
) %>%
drop_na(Umur, Nilai, UTS, UAS) %>%
distinct()
tail(data_ujian_clean,10)
colSums(is.na(data_ujian_clean))
## ID Nama Umur Gender Nilai Matkul Tanggal UTS UAS
## 0 0 0 0 0 0 0 0 0
nrow(data_ujian_clean)
## [1] 100
nrow(data_ujian)
## [1] 111
nrow(data_ujian_clean)
## [1] 100
colSums(is.na(data_ujian_clean))
## ID Nama Umur Gender Nilai Matkul Tanggal UTS UAS
## 0 0 0 0 0 0 0 0 0
sum(duplicated(data_ujian_clean))
## [1] 0
head(data_ujian_clean)
didalam dataset terdapat NA dan duplikat, maka dilakukan pembersihan data dengan menghapus NA dan duplikat sehingga tersisa 100 baris tanpa nilai kosong atau ganda
boxplot(data_ujian_clean$Nilai, main = "Boxplot Nilai")
Boxplot diatas menunjukkan sebaran nilai. Garis tebal di dalam kotak adalah median sekitar 82, sedangkan kotak menggambarkan 50% data utama yang berada di rentang 78 hingga 85. Garis (whisker) menunjukkan nilai terendah normal sekitar 70 dan nilai tertinggi mendekati 90. Terdapat satu outlier dibawah 60 yang menandakan nilai tersebut menyimpang dari data lainnya.
Q1 <- quantile(data_ujian_clean$Nilai, 0.25, na.rm = TRUE)
Q3 <- quantile(data_ujian_clean$Nilai, 0.75, na.rm = TRUE)
IQR <- Q3 - Q1
batas_bawah <- Q1 - 1.5 * IQR
batas_atas <- Q3 + 1.5 * IQR
tabel_outlier <- data.frame(
Statistik = c("Q1", "Q3", "IQR", "Batas Bawah", "Batas Atas"),
Nilai = c(Q1, Q3, IQR, batas_bawah, batas_atas)
)
tabel_outlier
outliers <- data_ujian_clean %>% filter(Nilai < batas_bawah | Nilai > batas_atas)
cat("Jumlah outlier:", nrow(outliers), "\n")
## Jumlah outlier: 1
data_no_outlier <- data_ujian_clean %>%
filter(Nilai >= batas_bawah & Nilai <= batas_atas)
cat("Jumlah data sesudah hapus outlier:", nrow(data_no_outlier), "\n")
## Jumlah data sesudah hapus outlier: 99
Setelah menghitung IQR, ditemukan 1 outlier pada kolom Nilai, sehingga setelah dihapus tersisa 99 data
Identifikasi Data Untuk mengenali ciri-ciri data, dilakukan pemeriksaan deskriptif melalui fungsi summary() dan skimr::skim(). Untuk memvisualisasikan sebaran, histogram digunakan bagi variabel numerik seperti usia, nilai, UTS, dan UAS. Di samping itu, interaksi antarvariabel numerik dianalisis lewat matriks korelasi yang kemudian divisualisasikan dengan corrplot. Temuan analisis mengungkapkan bahwa nilai UTS dan UAS saling berkorelasi positif, yang menunjukkan bahwa mahasiswa yang memiliki nilai UTS tinggi biasanya juga mendapatkan nilai UAS yang tinggi.
summary(data_ujian_clean)
## ID Nama Umur Gender
## Length:100 Length:100 Min. :20.00 : 0
## Class :character Class :character 1st Qu.:21.00 Laki-laki:50
## Mode :character Mode :character Median :22.00 Perempuan:50
## Mean :21.95
## 3rd Qu.:23.00
## Max. :24.00
## Nilai Matkul Tanggal UTS
## Min. :60.00 : 1 Length:100 Min. :55.00
## 1st Qu.:78.50 Biologi :24 Class :character 1st Qu.:76.00
## Median :82.75 Fisika :24 Mode :character Median :83.00
## Mean :82.50 Kimia :25 Mean :82.78
## 3rd Qu.:86.50 Matematika:26 3rd Qu.:88.00
## Max. :94.00 Max. :95.00
## UAS
## Min. :65.00
## 1st Qu.:75.00
## Median :81.50
## Mean :82.21
## 3rd Qu.:90.00
## Max. :95.00
skimr::skim(data_ujian_clean)
## Warning: There was 1 warning in `dplyr::summarize()`.
## ℹ In argument: `dplyr::across(tidyselect::any_of(variable_names),
## mangled_skimmers$funs)`.
## ℹ In group 0: .
## Caused by warning:
## ! There were 2 warnings in `dplyr::summarize()`.
## The first warning was:
## ℹ In argument: `dplyr::across(tidyselect::any_of(variable_names),
## mangled_skimmers$funs)`.
## Caused by warning in `sorted_count()`:
## ! Variable contains value(s) of "" that have been converted to "empty".
## ℹ Run `dplyr::last_dplyr_warnings()` to see the 1 remaining warning.
Name | data_ujian_clean |
Number of rows | 100 |
Number of columns | 9 |
_______________________ | |
Column type frequency: | |
character | 3 |
factor | 2 |
numeric | 4 |
________________________ | |
Group variables | None |
Variable type: character
skim_variable | n_missing | complete_rate | min | max | empty | n_unique | whitespace |
---|---|---|---|---|---|---|---|
ID | 0 | 1 | 1 | 3 | 0 | 100 | 0 |
Nama | 0 | 1 | 3 | 5 | 0 | 93 | 0 |
Tanggal | 0 | 1 | 8 | 9 | 0 | 2 | 0 |
Variable type: factor
skim_variable | n_missing | complete_rate | ordered | n_unique | top_counts |
---|---|---|---|---|---|
Gender | 0 | 1 | FALSE | 2 | Lak: 50, Per: 50, emp: 0 |
Matkul | 0 | 1 | FALSE | 5 | Mat: 26, Kim: 25, Bio: 24, Fis: 24 |
Variable type: numeric
skim_variable | n_missing | complete_rate | mean | sd | p0 | p25 | p50 | p75 | p100 | hist |
---|---|---|---|---|---|---|---|---|---|---|
Umur | 0 | 1 | 21.95 | 1.37 | 20 | 21.0 | 22.00 | 23.0 | 24 | ▆▇▇▆▆ |
Nilai | 0 | 1 | 82.50 | 5.75 | 60 | 78.5 | 82.75 | 86.5 | 94 | ▁▁▅▇▃ |
UTS | 0 | 1 | 82.78 | 7.69 | 55 | 76.0 | 83.00 | 88.0 | 95 | ▁▁▆▇▆ |
UAS | 0 | 1 | 82.21 | 8.22 | 65 | 75.0 | 81.50 | 90.0 | 95 | ▃▇▇▆▇ |
hist(data_ujian_clean$Umur, main = "Distribusi Umur", col = "skyblue", xlab = "Umur")
hist(data_ujian_clean$Nilai, main = "Distribusi Nilai", col = "red", xlab = "Nilai")
hist(data_ujian_clean$UTS, main = "Distribusi UTS", col = "green", xlab = "UTS")
hist(data_ujian_clean$UAS, main = "Distribusi UAS", col = "purple", xlab = "UAS")
Empat histogram ini memperlihat sebaran umur, nilai, UTS, DAN UAS mahasiswa, memudahkan melihat pola, konsentrasi, serta rentang nilai tiap variabel dan membantu mengidentifikasi distribusi data secara keseluruhan
suppressPackageStartupMessages(library(dplyr))
numeric_data <- data_ujian_clean %>% select(Umur, Nilai, UTS, UAS)
cor_matrix <- cor(numeric_data, use = "complete.obs")
print(cor_matrix)
## Umur Nilai UTS UAS
## Umur 1.00000000 -0.09025176 0.12328988 -0.24161041
## Nilai -0.09025176 1.00000000 0.69990207 0.74385067
## UTS 0.12328988 0.69990207 1.00000000 0.04326406
## UAS -0.24161041 0.74385067 0.04326406 1.00000000
Matriks korelasi menunjukkan hubungan antar variabel numerik: Nilai berkorelasi kuat dengan UTS (0,70) dan UAS (0,74), sedangkan umur hampir tidak berkorelasi dengan variabel lain.
library(corrplot)
## corrplot 0.95 loaded
corrplot(cor_matrix, method = "color", addCoef.col = "black",
tl.col = "black", tl.cex = 0.8, number.cex = 0.7)
headmap menunjukkan bahwa nilai berkorelasi kuat dengan UTS (0,70) dan UAS (0,74), sehingga keduanya berpengaruh besar terhadap nilai akhir. Sebaliknya, umur tidak memiliki hubungan berarti dengan ketiga variabel tersebut.
Ekstraksi Data
Dari variabel tanggal, diambil informasi tambahan yang berkaitan dengan bulan dan tahun dengan bantuan paket lubridate. Di samping itu, dibuat variabel baru yang dinamai Kategori_Umur, yang mengategorikan mahasiswa dalam kelompok usia seperti Remaja, Dewasa Awal, Dewasa, dan Lainnya. Penambahan variabel-variabel ini memberi sudut pandang baru untuk analisis yang mempertimbangkan waktu dan kategori usia.
head(data_ujian$Tanggal, 20)
## [1] "9/8/2023" "15/8/2023" "15/8/2023" "9/8/2023" "9/8/2023" "9/8/2023"
## [7] "15/8/2023" "15/8/2023" "15/8/2023" "15/8/2023" "15/8/2023" "9/8/2023"
## [13] "9/8/2023" "9/8/2023" "15/8/2023" "15/8/2023" "9/8/2023" "15/8/2023"
## [19] "9/8/2023" "9/8/2023"
str(data_ujian$Tanggal)
## chr [1:111] "9/8/2023" "15/8/2023" "15/8/2023" "9/8/2023" "9/8/2023" ...
library(lubridate)
##
## Attaching package: 'lubridate'
## The following objects are masked from 'package:base':
##
## date, intersect, setdiff, union
library(dplyr)
data_ujian_clean <- data_ujian %>%
mutate(
Tanggal = parse_date_time(Tanggal, orders = c("dmy", "d-m-Y", "d/m/Y")),
Bulan = month(Tanggal, label = TRUE, abbr = TRUE),
Tahun = year(Tanggal)
)
head(data_ujian_clean %>% select(Tanggal, Bulan, Tahun), 20)
data_ujian_clean <- data_ujian_clean %>%
mutate(
Kategori_Umur = cut(Umur,
breaks = c(0, 20, 25, 30, 100),
labels = c("Remaja", "Dewasa Awal", "Dewasa", "Lainnya"))
)
head(data_ujian_clean %>% select(Umur, Kategori_Umur), 10)
Integrasi Data Tahap integrasi dilakukan dengan menambahkan tabel referensi berisi rentang nilai numerik dan padanannya dalam bentuk nilai huruf (A, B, C, D, E). Dataset utama kemudian digabungkan dengan tabel ini menggunakan fungsi left_join(). Hasilnya, setiap mahasiswa memiliki dua representasi nilai, yaitu dalam bentuk angka dan huruf. Proses ini membuat analisis lebih mudah dilakukan, misalnya saat ingin melihat distribusi nilai berdasarkan kategori huruf.
tabel_nilai <- data.frame(
Range = c("0-59", "60-69", "70-79", "80-89", "90-100"),
Nilai_Huruf = c("E", "D", "C", "B", "A")
)
print(tabel_nilai)
## Range Nilai_Huruf
## 1 0-59 E
## 2 60-69 D
## 3 70-79 C
## 4 80-89 B
## 5 90-100 A
data_gabungan <- data_ujian_clean %>%
filter(is.finite(Nilai)) %>%
mutate(Range = case_when(
Nilai <= 59 ~ "0-59",
Nilai <= 69 ~ "60-69",
Nilai <= 79 ~ "70-79",
Nilai <= 89 ~ "80-89",
Nilai <= 100 ~ "90-100",
TRUE ~ NA_character_
)) %>%
left_join(tabel_nilai, by = "Range")
head(data_gabungan)
data_gabungan_clean <- data_gabungan %>%
filter(!is.na(Nilai_Huruf))
str(data_gabungan_clean)
## 'data.frame': 100 obs. of 14 variables:
## $ ID : chr "1" "2" "3" "4" ...
## $ Nama : chr "Budi" "Ani" "Joko" "Siti" ...
## $ Umur : num 24 21 20 21 23 21 21 23 22 24 ...
## $ Gender : Factor w/ 3 levels "","Laki-laki",..: 2 3 2 3 2 3 3 2 3 2 ...
## $ Nilai : num 85 77.5 90 60 77.5 85 90 67.5 75 82.5 ...
## $ Matkul : Factor w/ 5 levels "","Biologi","Fisika",..: 4 5 2 5 3 2 5 3 5 2 ...
## $ Tanggal : POSIXct, format: "2023-08-09" "2023-08-15" ...
## $ UTS : num 90 75 85 55 80 75 85 70 80 85 ...
## $ UAS : num 80 80 95 65 75 95 95 65 70 80 ...
## $ Bulan : Ord.factor w/ 12 levels "Jan"<"Feb"<"Mar"<..: 8 8 8 8 8 8 8 8 8 8 ...
## $ Tahun : num 2023 2023 2023 2023 2023 ...
## $ Kategori_Umur: Factor w/ 4 levels "Remaja","Dewasa Awal",..: 2 2 1 2 2 2 2 2 2 2 ...
## $ Range : chr "80-89" "70-79" "90-100" "60-69" ...
## $ Nilai_Huruf : chr "B" "C" "A" "D" ...
Data digabungkan dengan tabel nilai huruf, sehingga setiap skor numerik dikonversi ke range dan nilai huruf (A-E). Hasilnya adalah dataset bersih dengan 100 siswa, termasuk informasi umur, gender, mata kuliah, tanggal ujian, skor UTS dan UAS, serta kategori umur dan nilai huruf.
Visualisasi Akhir Beberapa visualisasi dibuat untuk menggambarkan hasil preprocessing:
Boxplot Nilai per Nilai Huruf, yang menunjukkan sebaran nilai numerik di tiap kategori huruf. Hasilnya, terlihat bahwa kategori A memiliki median yang tinggi dan variasi lebih kecil dibanding kategori lainnya.
Histogram Nilai, yang memperlihatkan distribusi nilai mahasiswa. Sebagian besar nilai berada pada kategori B dan C.
Scatterplot UTS vs UAS, yang menunjukkan adanya hubungan positif antara kedua nilai tersebut, dengan pola linier yang cukup jelas.
library(ggplot2)
ggplot(data_gabungan_clean, aes(x = Nilai_Huruf, y = Nilai, fill = Nilai_Huruf)) +
geom_boxplot() +
labs(title = "Boxplot Nilai per Nilai Huruf", x = "Nilai Huruf", y = "Nilai")
Gambar boxplot diatas menunjukkan distribusi nilai berdasarkan kategori huruf A,B,C, dan D. Nilai A memiliki rentang yang paling tinggi dengan median sekitar 91, sedangkan nilai D paling rendah dengan median sekitar 65. Nilai B dan C berada di tengah dengan median sekitar 83 dan 76. Secara keseluruhan, terlihat bahwa semakin rendah kategori huruf, semakin rendah pula nilai median yang diperoleh
ggplot(data_gabungan_clean, aes(x = Nilai)) +
geom_histogram(binwidth = 5, fill = "skyblue", color = "black") +
labs(title = "Histogram Nilai", x = "Nilai", y = "Frekuensi")
Histogram pada gambar menunjukkan distribusi nilai mahasiswa. Mayoritas nilai berada pada rentang 75 hingga 90 dengan frekuensi tertinggi sekitar 30 orang pada nilai 80-85. sementara itu, hanya sedikit mahasiswa yang mendapatkan nilai di bawah 70 atau diatas 90. Hal ini menunjukkan bahwa sebagian besar nilai terkonsentrasi di kategori sedang hingga tinggi
suppressMessages(
ggplot(data_gabungan_clean, aes(x = UTS, y = UAS)) +
geom_point(color = "blue", size = 2) +
geom_smooth(method = "lm", se = FALSE, color = "red") +
labs(title = "Scatterplot Hubungan UTS vs UAS",
x = "Nilai UTS",
y = "Nilai UAS") +
theme_minimal()
)
## `geom_smooth()` using formula = 'y ~ x'
Scatterplot di atas menunjukkan hubungan antara nilai UTS dan UAS. Titik-titik tersebar cukup acak, namun garis tren merah sedikit menanjak, yang berarti ada hubungan positif lemah : semakin tinggi nilai UTS, cenderung nilai UAS juga ikut meningkat.
Secara Keseluruhan maka dapat disimpulkan
Hasil analisis data mengindikasikan bahwa dari 111 data yang ada, ditemui nilai yang hilang, duplikasi, dan satu data pencilan, sehingga setelah proses pembersihan, tersisa 99 data bersih yang lebih mencerminkan untuk dilakukan analisis. Distribusi data menunjukkan bahwa rata-rata usia orang yang berkuliah adalah 22 tahun dengan rentang antara 20 hingga 24 tahun. Sementara itu, skor ujian berada di antara 60 hingga 94, dengan mayoritas nilai terletak pada kisaran 75 sampai 90. Mayoritas mahasiswa menerima nilai huruf B dan C, sementara hanya sejumlah kecil yang berhasil mendapatkan kategori A. Penelitian mengenai keterkaitan antarvariabel menunjukkan bahwa total nilai berkorelasi dengan kuat dengan UTS (0,70) dan UAS (0,74), yang mengindikasikan bahwa kinerja mahasiswa pada ujian tengah dan akhir semester berperan signifikan dalam menentukan nilai akhir. Di sisi lain, usia mahasiswa tidak menunjukkan dampak yang signifikan terhadap prestasi akademik. Visualisasi menggunakan boxplot, histogram, dan scatterplot mempertegas temuan ini, yakni semakin rendah kategori huruf yang diperoleh, semakin rendah pula median nilainya, dengan distribusi nilai lebih terkonsentrasi pada tingkat menengah hingga tinggi, serta terdapat kecenderungan positif antara UTS dan UAS.
Manfaat Pre-Processing
Tahapan pre-processing yang dilakukan menunjukkan manfaat yang signifikan. Penghapusan data yang tidak lengkap, penghilangan duplikasi, serta penanganan outlier meningkatnya kualitas basis data sehingga hasil analisis menjadi lebih tepat dan tidak terdistorsi. Proses transformasi dan penggabungan data, seperti pengelompokan usia, peralihan dari angka ke huruf, dan penambahan unsur waktu, memberikan perspektif baru yang memperkaya pemahaman. Dengan kata lain, dataset yang telah disusun dengan baik dan konsisten ini tidak hanya mempermudah analisis deskriptif tetapi juga siap untuk digunakan dalam analisis lebih lanjut, termasuk dalam pemodelan prediktif atau pengambilan keputusan yang berhubungan dengan kinerja mahasiswa.