Perkembangan teknologi informasi telah mendorong peningkatan penggunaan data dalam berbagai bidang, sehingga diperlukan teknik pengolahan data yang tepat untuk menghasilkan informasi yang bermanfaat. Dalam analisis data dan pembelajaran mesin (machine learning), kualitas data serta pemilihan variabel yang digunakan memiliki peran penting dalam menentukan kinerja model. Data yang diperoleh dari berbagai sumber sering kali belum siap digunakan secara langsung karena mengandung nilai yang hilang, format yang tidak sesuai, atau variabel yang belum merepresentasikan informasi secara optimal. Oleh karena itu, diperlukan tahapan pengolahan dan pembentukan fitur untuk meningkatkan kualitas data sebelum dilakukan analisis lebih lanjut.
Salah satu tahapan penting dalam proses tersebut adalah feature engineering, feature engineering adalah proses menggunakan pengetahuan domain untuk mengekstrak atau membuat fitur-fitur baru dari data mentah (Darmawan et al., 2024). Teknik feature engineering dapat mencakup penanganan nilai yang hilang, pengodean variabel kategorik (encoding), normalisasi dan standardisasi, transformasi variabel, pembentukan fitur baru (feature creation), serta seleksi fitur (feature selection). Pemilihan teknik yang tepat perlu disesuaikan dengan karakteristik data dan tujuan analisis karena fitur yang relevan dapat membantu model mengenali pola dalam data secara lebih efektif.
Salah satu perangkat lunak yang dapat digunakan untuk menerapkan
teknik feature engineering adalah RStudio, yaitu lingkungan
pengembangan yang mendukung penggunaan bahasa pemrograman R untuk
pengolahan, analisis, dan visualisasi data. Melalui RStudio, pengguna
dapat memanfaatkan berbagai fungsi dan paket, seperti dplyr
untuk manipulasi data, tidyr untuk penataan data, serta
recipes untuk menyusun tahapan prapemrosesan fitur secara
sistematis. Penggunaan perangkat tersebut memungkinkan proses
pembentukan dan transformasi fitur dilakukan secara terstruktur,
sehingga data dapat dipersiapkan sebelum digunakan dalam analisis
statistik maupun pemodelan machine learning.
Berdasarkan latar belakang di atas, adapun rumusan masalah yang dapat disimpulkan sebagai berikut: 1.Bagaimana konsep dari berbagai jenis feature engineering yang dapat diterapkan pada RStudio? 2.Bagaimana penerapan teknik feature engineering menggunakan program RStudio?
Adapun tujuan penelitian ini yaitu: 1. Praktikan memahami konsep dari berbagai jenis feature engineering pada RStudio. 2. Praktikan dapat melakukan teknik feature engineering di program RStudio.
Feature engineering adalah tahap penting dalam pengembangan model prediktif, yang melibatkan transformasi variabel-variabel data menjadi bentuk yang lebih representatif untuk meningkatkan kinerja model (Herdian et al., 2024). Tahap feature engineering dilakukan untuk mengekstraksi pola kritis dari data proses. Feature egineering dirancang berdasarkan hubungan fisik antar variabel dan potensi mekanisme. Pendekatan ini didukung oleh penelitian terbaru yang menunjukkan bahwa teknik feature engineering dapat meningkatkan kinerja model prediksi secara signifikan (Winata et al., 2026).
Data dapat dikelompokkan menjadi data numerik dan data kategorik. Data numerik terdiri atas data numerik diskrit dan kontinu, sedangkan data kategorik terdiri atas data kategorik nominal dan ordinal. Data numerik diskrit merupakan data yang nilainya berupa bilangan bulat dan terpisah, sedangkan data numerik kontinu merupakan data yang nilainya berada dalam suatu rentang tertentu. Data kategorik nominal merupakan data yang tidak memiliki urutan, sedangkan data kategorik ordinal merupakan data yang memiliki tingkatan atau urutan tertentu (Fransiska, 2026).
Kardinalitas merujuk pada jumlah nilai unik atau label yang terdapat dalam suatu variabel kategorik yang dapat diklasifikasikan menjadi kardinalitas rendah (low cardinality) dan kardinalitas tinggi (high cardinality). Variabel dengan kardinalitas tinggi dapat menyebabkan curse of dimensionality jika ditransformasi menggunakan metode encoding standar seperti One-Hot Encoding, karena metode ini akan menciptakan banyak fitur biner baru sesuai jumlah label. Kardinalitas juga secara signifikan meningkatkan risiko overfitting karena banyak label mungkin hanya muncul beberapa kali dalam set data training (Fransiska, 2026).
1. Missing Value Handling Penanganan nilai yang hilang merupakan proses mengatasi data yang tidak memiliki nilai pada variabel tertentu. Nilai yang hilang dapat ditangani dengan menghapus observasi tertentu atau mengganti nilai yang hilang menggunakan metode imputasi, seperti rata-rata (mean), median, atau modus. Pemilihan metode harus mempertimbangkan jenis variabel dan karakteristik data agar tidak menimbulkan bias pada hasil analisis (Hr et al., 2022).
2. Normalisasi dan Standardisasi Normalisasi dan standardisasi merupakan teknik transformasi untuk menyamakan atau menyesuaikan skala variabel numerik. Normalisasi Min-Max mengubah nilai ke rentang tertentu, umumnya 0 sampai 1, sedangkan standardisasi Z-score mengubah data berdasarkan rata-rata dan simpangan baku. Kedua teknik ini penting bagi algoritma yang menggunakan perhitungan jarak, seperti KNN, karena perbedaan skala variabel dapat memengaruhi hasil pemodelan (Hadi et al., 2024).
3. Min-Max Scaling Min-Max Scaling merupakan salah satu teknik scaling data yang digunakan dalam feature engineering. Min-Max Scaling mengubah distribusi data sehingga nilai-nilai berada dalam rentang tertentu, biasanya antara 0 dan 1. Teknik ini berbeda dengan Robust Scaling dan Standard Scaling yang juga digunakan untuk menormalkan data dengan pendekatan yang berbeda (Fransiska, 2026).
4. Label Encoding Label Encoding merupakan teknik feature encoding yang mengubah fitur kategoris atau non-numerik menjadi format numerik yang dapat digunakan sebagai input untuk algoritma machine learning. Label encoder digunakan agar tidak menambah jumlah fitur pada data, berbeda dengan One-Hot Encoding yang akan menambah jumlah fitur sesuai dengan jumlah kategori (Fauzi et al.., 2025). Feature encoding diperlukan karena banyak algoritma machine learning membutuhkan input numerik (Fransiska, 2026).
5. One-Hot Encoding One-Hot Encoding dalam pemrosesan data dan machine learning adalah metode yang digunakan untuk merepresentasikan variabel kategorikal sebagai vektor biner. Setiap kategori atau label dalam metode encoding ini diubah menjadi vektor biner dengan panjang yang sama dengan jumlah total kategori yang berbeda dalam variabel tersebut, di mana semua nilai vektor adalah nol kecuali indeks yang sesuai dengan kategori yang ditandai dengan angka 1. One-Hot Encoding dapat menghasilkan ruang fitur berdimensi tinggi, terutama pada dataset dengan banyak kategori, sehingga perlu pertimbangan hati-hati untuk menyeimbangkan keuntungan representasi dengan kemungkinan peningkatan kompleksitas komputasi (Herdian et al.., 2024).
6. Diskretisasi atau Binning Diskretisasi atau binning merupakan teknik feature engineering yang mengubah data kontinu menjadi data interval (Herdian et al., 2024). Diskretisasi dilakukan dengan membagi rentang nilai kontinu menjadi beberapa interval atau bin berdasarkan kriteria tertentu. Transformasi ini bertujuan untuk menyederhanakan data dan memberikan informasi yang lebih eksplisit kepada model mengenai kategori nilai tertentu (Darmawan et al.., 2026).
7. Feature Creation Feature creation merupakan proses menciptakan fitur-fitur baru yang lebih representatif dari data yang ada. Feature engineering dilakukan untuk membuat fitur baru seperti rasio antara dua variabel, jarak, dan variabel turunan lainnya yang dapat meningkatkan representasi data (Sihombing, 2024). Fitur turunan dibuat sebagai bagian dari strategi feature engineering yang menggabungkan berbagai informasi dari data mentah. Feature creation juga mencakup pembuatan fitur interaksi untuk meningkatkan representasi data (Darmawan et al.., 2026).
8. Feature Selection Seleksi fitur merupakan proses pemilihan fitur yang tepat dalam proses klasifikasi, dengan tujuan untuk mengurangi tingkat kompleksitas dan meningkatkan akurasi dari suatu algoritma klasifikasi serta mampu mengetahui fitur-fitur apa saja yang paling berkontribusi terhadap tingkat akurasi (Budianita, 2023). Information gain adalah metode seleksi fitur dengan memberikan bobot setiap fitur berdasarkan kelas tertentu dengan memaksimalkan nilai entropy (Putri et al.., 2023).
Proses pemodelan machine learning dalam RStudio didukung
oleh berbagai package yang menyediakan fungsi untuk setiap
tahapan analisis data. Package tidyverse digunakan
untuk memanipulasi data melalui fungsi drop_na(),
fill(), dan is.na() untuk menangani
missing value, sedangkan package zoo menyediakan
fungsi na.approx() untuk interpolasi data yang hilang.
Package rsample menyediakan fungsi initial_split()
dan initial_time_split() untuk membagi data, package
DescTools menyediakan fungsi Winsorize(),
quantile(), dan IQR() untuk menangani
outlier, serta package e1071 menyediakan fungsi
skewness() untuk mengukur kemencengan distribusi data.
Package recipes dan themis digunakan untuk melakukan
encoding dan penyeimbangan data melalui fungsi
step_dummy() dan step_smote(), sementara
package dplyr menyediakan fungsi mutate(),
filter(), dan select() untuk manipulasi data.
Package ggplot2 dan gridExtra digunakan untuk
visualisasi distribusi data, dan package caret digunakan untuk
mendukung proses pemodelan dan evaluasi (Fransiska, 2026).
Jenis data yang digunakan pada penelitian ini adalah data numerik dan data kategorik. Data numerik merupakan data berbentuk angka yang dapat dianalisis secara statistik, yaitu suhu, kelembapan, dan kecepatan angin. Data kategorik merupakan data yang menyatakan kelompok atau kelas suatu pengamatan, yaitu status hujan dan kode keadaan cuaca.
Sumber data yang digunakan dalam penelitian ini adalah data sekunder. Data sekunder merupakan data yang telah dikumpulkan dan diolah terlebih dahulu oleh pihak lain. Data curah hujan diperoleh dari modul praktikum Machine Learning and Modern Prediction. Dataset tersebut terdiri atas 743 observasi dan 5 variabel.
Variabel merupakan karakteristik atau atribut yang dapat diukur
maupun diamati dalam suatu penelitian. Penelitian ini menggunakan lima
variabel, yaitu Hujan, Suhu,
Kelembapan, Keadaan Cuaca, dan
Kecepatan Angin. Variabel Hujan berperan
sebagai variabel target yang bertipe kategorik dengan dua kelas, yaitu 1
dan 2. Variabel Suhu, Kelembapan, dan
Kecepatan Angin bertipe numerik, sedangkan
Keadaan Cuaca bertipe kategorik berupa kode keadaan cuaca
yang ditulis dalam bentuk angka. Keempat variabel selain
Hujan berperan sebagai fitur.
Berikut merupakan algoritma penelitian pada batasan masalah:
library(zoo)
##
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
library(readxl)
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.2.1 ✔ readr 2.2.0
## ✔ forcats 1.0.1 ✔ stringr 1.6.0
## ✔ ggplot2 4.0.2 ✔ tibble 3.3.1
## ✔ lubridate 1.9.5 ✔ tidyr 1.3.2
## ✔ purrr 1.2.2
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(rsample)
library(e1071)
##
## Attaching package: 'e1071'
##
## The following object is masked from 'package:rsample':
##
## permutations
##
## The following object is masked from 'package:ggplot2':
##
## element
library(DescTools)
library(dplyr)
library(ggplot2)
library(gridExtra)
##
## Attaching package: 'gridExtra'
##
## The following object is masked from 'package:dplyr':
##
## combine
library(recipes)
##
## Attaching package: 'recipes'
##
## The following object is masked from 'package:stringr':
##
## fixed
##
## The following object is masked from 'package:stats':
##
## step
library(themis)
library(caret)
## Loading required package: lattice
##
## Attaching package: 'caret'
##
## The following objects are masked from 'package:DescTools':
##
## MAE, RMSE
##
## The following object is masked from 'package:rsample':
##
## calibration
##
## The following object is masked from 'package:purrr':
##
## lift
data<- read_excel("D:/SEMESTER 7/MACHINE LEARNING/LAPRAK/data curah hujan.xlsx")
head(data)
## # A tibble: 6 × 5
## Hujan Suhu Kelembapan Keadaan_Cuaca Kecepatan_Angin
## <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1 23 95 5 NA
## 2 1 24 90 1 NA
## 3 1 26.8 77 1 NA
## 4 1 29.6 62 2 2
## 5 1 30.8 56 1 7
## 6 1 31 55 1 7
str(data)
## tibble [743 × 5] (S3: tbl_df/tbl/data.frame)
## $ Hujan : num [1:743] 1 1 1 1 1 1 1 2 2 2 ...
## $ Suhu : num [1:743] 23 24 26.8 29.6 30.8 31 30.4 30.9 30.2 29.7 ...
## $ Kelembapan : num [1:743] 95 90 77 62 56 55 57 58 62 62 ...
## $ Keadaan_Cuaca : num [1:743] 5 1 1 2 1 1 3 2 2 2 ...
## $ Kecepatan_Angin: num [1:743] NA NA NA 2 7 7 9 10 8 7 ...
Tahapan dimulai dengan memanggil paket yang diperlukan untuk membaca,
memanipulasi, menganalisis, memvisualisasikan, dan melakukan
prapemrosesan data. Selanjutnya, dataset data curah hujan.xlsx
diimpor menggunakan fungsi read_excel(). Fungsi
head() digunakan untuk memeriksa enam baris pertama,
sedangkan str() digunakan untuk mengetahui struktur dan
tipe data setiap variabel. Tahap ini penting sebelum menerapkan
feature engineering, karena karakteristik data perlu diketahui
terlebih dahulu agar teknik pengolahan yang dipilih sesuai dengan
kebutuhan analisis.
# 2. Cek Missing Value
colSums(is.na(data))
## Hujan Suhu Kelembapan Keadaan_Cuaca Kecepatan_Angin
## 0 0 0 9 314
colMeans(is.na(data))
## Hujan Suhu Kelembapan Keadaan_Cuaca Kecepatan_Angin
## 0.00000000 0.00000000 0.00000000 0.01211306 0.42261104
# Lihat baris yang kosong di Keadaan_Cuaca
data %>% filter(is.na(Keadaan_Cuaca))
## # A tibble: 9 × 5
## Hujan Suhu Kelembapan Keadaan_Cuaca Kecepatan_Angin
## <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 2 26 92 NA NA
## 2 1 23.8 98 NA 5
## 3 1 23.3 97 NA NA
## 4 2 28.8 79 NA 12
## 5 2 24.6 92 NA NA
## 6 1 22.8 98 NA 4
## 7 2 25.5 96 NA NA
## 8 2 27 80 NA 4
## 9 2 31 57 NA 6
# 3. Penanganan Missing Value
df_imp <- data
# 3.1 Interpolasi pada Keadaan_Cuaca
# rule = 2 agar NA di awal/akhir data tetap terisi
df_imp$Keadaan_Cuaca <- na.approx(df_imp$Keadaan_Cuaca, na.rm = FALSE, rule = 2)
colSums(is.na(df_imp))
## Hujan Suhu Kelembapan Keadaan_Cuaca Kecepatan_Angin
## 0 0 0 0 314
# 3.2 Mode Imputation pada Kecepatan_Angin
mode_value <- Mode(df_imp$Kecepatan_Angin, na.rm = TRUE)[1]
mode_value
## [1] 3
df_imp$Kecepatan_Angin[is.na(df_imp$Kecepatan_Angin)] <- mode_value
# Verifikasi tidak ada missing value tersisa
colSums(is.na(df_imp))
## Hujan Suhu Kelembapan Keadaan_Cuaca Kecepatan_Angin
## 0 0 0 0 0
Berdasarkan batasan masalah, penanganan missing value
dilakukan menggunakan metode interpolasi pada variabel
Keadaan Cuaca dan mode imputation pada variabel
Kecepatan Angin. Hasil pemeriksaan awal menunjukkan bahwa
nilai yang hilang hanya ditemukan pada kedua variabel tersebut. Variabel
Keadaan Cuaca memiliki 9 nilai hilang, sedangkan variabel
Kecepatan Angin memiliki 314 nilai hilang. Sementara itu,
variabel Hujan, Suhu, dan
Kelembapan tidak memiliki nilai yang hilang.
Penanganan missing value pada variabel
Keadaan Cuaca dilakukan menggunakan fungsi
na.approx melalui metode interpolasi linear, yaitu
memperkirakan nilai yang hilang berdasarkan nilai di sekitarnya.
Penggunaan argumen rule = 2 memungkinkan nilai yang hilang
pada bagian awal maupun akhir data tetap diisi berdasarkan nilai
terdekat yang tersedia. Setelah proses interpolasi dilakukan, seluruh 9
nilai hilang berhasil ditangani sehingga tidak tersisa missing
value pada variabel tersebut. Namun, variabel
Kecepatan Angin masih memiliki 314 nilai yang hilang
sebelum dilakukan imputasi.
Selanjutnya, penanganan nilai hilang pada variabel
Kecepatan Angin dilakukan menggunakan metode mode
imputation, yaitu mengganti nilai yang hilang dengan nilai yang
paling sering muncul dalam data. Berdasarkan hasil perhitungan, nilai
modus variabel tersebut adalah 3. Dengan demikian, sebanyak 314 nilai
yang hilang digantikan dengan angka 3 sehingga seluruh missing
value berhasil diatasi. Metode imputasi ini dipilih karena proporsi
nilai hilang pada variabel Kecepatan Angin mencapai 42,26%.
Penghapusan baris yang mengandung nilai hilang berpotensi mengurangi
jumlah observasi secara signifikan, sehingga imputasi digunakan untuk
mempertahankan jumlah data. Meskipun demikian, penggantian seluruh nilai
yang hilang dengan angka 3 menyebabkan nilai tersebut semakin dominan
dalam distribusi variabel Kecepatan Angin.
# 4. Kardinalitas (Reduksi Kategori Keadaan_Cuaca)
head(df_imp, 10)
## # A tibble: 10 × 5
## Hujan Suhu Kelembapan Keadaan_Cuaca Kecepatan_Angin
## <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1 23 95 5 3
## 2 1 24 90 1 3
## 3 1 26.8 77 1 3
## 4 1 29.6 62 2 2
## 5 1 30.8 56 1 7
## 6 1 31 55 1 7
## 7 1 30.4 57 3 9
## 8 2 30.9 58 2 10
## 9 2 30.2 62 2 8
## 10 2 29.7 62 2 7
unique(df_imp$Keadaan_Cuaca)
## [1] 5.0 1.0 2.0 3.0 14.0 60.0 61.0 21.0 29.0 10.0 16.0 62.0 63.0 65.0 15.0
## [16] 17.0 13.0 95.0 91.0 49.0 97.0 56.0 1.5
# 4.1 Tentukan batas bin
bins <- c(0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100)
# 4.2 Tentukan label untuk setiap bin (10 label: 0 s/d 9)
labels <- 0:9
# 4.3 Terapkan cut()
df_imp$Keadaan_Cuaca_reduced <- cut(
df_imp$Keadaan_Cuaca,
breaks = bins,
labels = labels,
right = TRUE, # interval (a, b]
include.lowest = TRUE # nilai batas paling bawah (0) tetap terhitung
)
# 4.4 Verifikasi
cat("--- Hasil Perbandingan ---\n")
## --- Hasil Perbandingan ---
print(df_imp[sample(nrow(df_imp), 10), ])
## # A tibble: 10 × 6
## Hujan Suhu Kelembapan Keadaan_Cuaca Kecepatan_Angin Keadaan_Cuaca_reduced
## <dbl> <dbl> <dbl> <dbl> <dbl> <fct>
## 1 2 27.4 86 2 4 0
## 2 1 30 64 2 3 0
## 3 2 27.6 83 2 10 0
## 4 2 23.3 98 1 3 0
## 5 2 25.6 78 1 3 0
## 6 2 24.8 94 2 3 0
## 7 2 31.2 63 2 10 0
## 8 2 29.9 69 2 9 0
## 9 2 27.3 82 2 2 0
## 10 2 24.8 92 2 4 0
cat("\n--- Pengecekan Kardinalitas ---\n")
##
## --- Pengecekan Kardinalitas ---
cat('Jumlah kategori di "Keadaan_Cuaca" asli :', length(unique(df_imp$Keadaan_Cuaca)), "\n")
## Jumlah kategori di "Keadaan_Cuaca" asli : 23
cat('Jumlah kategori di "Keadaan_Cuaca_reduced" :', length(unique(df_imp$Keadaan_Cuaca_reduced)), "\n")
## Jumlah kategori di "Keadaan_Cuaca_reduced" : 7
cat("\nKategori unik yang baru (reduced):\n")
##
## Kategori unik yang baru (reduced):
print(unique(df_imp$Keadaan_Cuaca_reduced))
## [1] 0 1 5 6 2 9 4
## Levels: 0 1 2 3 4 5 6 7 8 9
Berdasarkan batasan masalah, variabel Keadaan Cuaca
diolah menggunakan metode interpolasi yang menghasilkan nilai dengan
variasi cukup tinggi, sehingga perlu dilakukan pemeriksaan kardinalitas.
Kardinalitas merupakan jumlah nilai atau kategori unik yang terdapat
dalam suatu variabel. Hasil pemeriksaan menunjukkan bahwa variabel
Keadaan Cuaca memiliki 23 nilai unik, di antaranya 1; 1,5;
2; 5; 14; 60; 95; dan 97. Jumlah kategori yang cukup banyak dapat
menyulitkan proses pengodean karena teknik one-hot encoding
berpotensi menghasilkan banyak kolom tambahan, yang sebagian besar
berisi nilai nol dan dapat meningkatkan kompleksitas model.
Untuk mengurangi jumlah kategori tersebut, dilakukan pengelompokan
nilai (binning) menggunakan fungsi cut(). Nilai
variabel dibagi ke dalam 10 interval dengan lebar masing-masing 10
satuan, menggunakan format interval (a,b](a,b](a,b], kemudian diberi
label kategori 0 hingga 9. Penggunaan argumen
include.lowest = TRUE bertujuan memastikan nilai terkecil,
yaitu 0, tetap termasuk dalam interval pertama. Hasil pengelompokan
tersebut disajikan pada Tabel 4.3.
Setelah proses binning, jumlah kategori yang teramati berkurang dari 23 menjadi 7, yaitu kategori 0, 1, 2, 4, 5, 6, dan 9. Kategori 0 mendominasi data karena nilai asli seperti 1, 2, dan 3 banyak ditemukan dalam pengamatan. Variabel hasil pengelompokan memiliki tipe data factor dengan 10 level yang tetap tersimpan, meskipun beberapa kategori tidak muncul dalam data. Penyimpanan seluruh level tersebut dapat membantu menjaga konsistensi kategori antara data latih dan data uji ketika dilakukan proses pengodean fitur.
set.seed(46)
split_stratify <- initial_split(df_imp, prop = 0.8, strata = Hujan)
X_train <- training(split_stratify) %>% select(-Hujan)
X_test <- testing(split_stratify) %>% select(-Hujan)
y_train <- training(split_stratify)$Hujan
y_test <- testing(split_stratify)$Hujan
dim(X_train)
## [1] 594 5
dim(X_test)
## [1] 149 5
# Cek proporsi kelas pada data latih dan data uji
prop.table(table(y_train))
## y_train
## 1 2
## 0.2205387 0.7794613
prop.table(table(y_test))
## y_test
## 1 2
## 0.2214765 0.7785235
Berdasarkan batasan masalah, pembagian data dilakukan menggunakan
metode stratified splitting dengan perbandingan 80% untuk data
latih (training data) dan 20% untuk data uji (testing
data). Penggunaan set.seed(46) bertujuan agar proses
pembagian data menghasilkan hasil yang konsisten ketika dijalankan
kembali. Hasil pembagian menunjukkan bahwa data latih terdiri atas 594
observasi, sedangkan data uji terdiri atas 149 observasi, dengan
masing-masing memiliki 5 kolom. Selanjutnya, variabel Hujan
ditetapkan sebagai variabel target yang dipisahkan ke dalam objek
y_train dan y_test.
Metode stratified splitting membagi data dengan mempertahankan proporsi setiap kelas pada variabel target agar distribusi kelas pada data latih dan data uji tetap mendekati distribusi data awal. Berdasarkan hasil, kelas 1 memiliki proporsi sebesar 22,05% pada data latih dan 22,15% pada data uji, sedangkan kelas 2 masing-masing sebesar 77,95% dan 77,85%. Perbedaan proporsi yang relatif kecil menunjukkan bahwa distribusi kelas pada kedua subset data cukup konsisten. Namun, distribusi tersebut juga menunjukkan adanya ketidakseimbangan kelas karena jumlah observasi kelas 2 sekitar empat kali lebih banyak dibandingkan kelas 1. Kondisi ini perlu diperhatikan pada tahap pemodelan dan evaluasi karena model berpotensi lebih cenderung memprediksi kelas mayoritas.
# 6.1 Daftar fitur numerik
list_num <- c("Suhu", "Kelembapan", "Kecepatan_Angin")
# 6.2 Hitung batas IQR untuk setiap kolom (berdasarkan data latih)
list_outlier <- c()
list_lower_bound <- c()
list_upper_bound <- c()
for (i in list_num) {
Q1 <- quantile(X_train[[i]], 0.25, na.rm = TRUE)
Q3 <- quantile(X_train[[i]], 0.75, na.rm = TRUE)
IQR_val <- Q3 - Q1
lower_bound <- Q1 - 1.5 * IQR_val
upper_bound <- Q3 + 1.5 * IQR_val
list_lower_bound <- c(list_lower_bound, lower_bound)
list_upper_bound <- c(list_upper_bound, upper_bound)
num_outliers_lower <- sum(X_train[[i]] < lower_bound, na.rm = TRUE)
num_outliers_upper <- sum(X_train[[i]] > upper_bound, na.rm = TRUE)
list_outlier <- c(list_outlier, num_outliers_lower + num_outliers_upper)
}
outliers <- data.frame(
Kolom = list_num,
Jumlah_Outlier = list_outlier,
Lower_Bound = list_lower_bound,
Upper_Bound = list_upper_bound
)
outliers
## Kolom Jumlah_Outlier Lower_Bound Upper_Bound
## 1 Suhu 0 17.5 35.9
## 2 Kelembapan 0 44.0 124.0
## 3 Kecepatan_Angin 5 -3.0 13.0
# 6.3 Capping (Winsorize) untuk setiap fitur numerik
# Batas dihitung dari data latih, lalu diterapkan ke data latih dan data uji
X_train_capped <- X_train
X_test_capped <- X_test
for (i in list_num) {
batas <- outliers %>% filter(Kolom == i)
lower <- batas$Lower_Bound
upper <- batas$Upper_Bound
X_train_capped[[i]] <- Winsorize(X_train[[i]], val = c(lower, upper))
X_test_capped[[i]] <- Winsorize(X_test[[i]], val = c(lower, upper))
}
# 6.4 Fungsi plot diagnostik
diagnostic_plots <- function(df, variable) {
p1 <- ggplot(df, aes(x = .data[[variable]])) +
geom_histogram(bins = 30, fill = "yellow", color = "black") +
ggtitle("Histogram") +
theme_minimal()
p2 <- ggplot(df, aes(y = .data[[variable]])) +
geom_boxplot(fill = "#008080") +
ggtitle("Boxplot") +
theme_minimal()
grid.arrange(p1, p2, ncol = 2)
}
# 6.5 Bandingkan sebelum dan sesudah capping
for (col in list_num) {
cat(col, "- Before Capping\n")
diagnostic_plots(X_train, col)
cat("\n", col, "- After Capping\n")
diagnostic_plots(X_train_capped, col)
}
## Suhu - Before Capping
##
## Suhu - After Capping
## Kelembapan - Before Capping
##
## Kelembapan - After Capping
## Kecepatan_Angin - Before Capping
##
## Kecepatan_Angin - After Capping
diagnostic_plots(X_train, "Suhu")
Gambar 4.1 Histogram dan boxplot Suhu sebelum capping
diagnostic_plots(X_train_capped, "Suhu")
Gambar 4.2 Histogram dan boxplot Suhu setelah capping
diagnostic_plots(X_train, "Kelembapan")
Gambar 4.3 Histogram dan boxplot Kelembapan sebelum capping
diagnostic_plots(X_train_capped, "Kelembapan")
Gambar 4.4 Histogram dan boxplot Kelembapan setelah capping
diagnostic_plots(X_train, "Kecepatan_Angin")
Gambar 4.5 Histogram dan boxplot Kecepatan_Angin sebelum capping
diagnostic_plots(X_train_capped, "Kecepatan_Angin")
Gambar 4.6 Histogram dan boxplot Kecepatan_Angin setelah capping
Berdasarkan batasan masalah, penanganan outlier pada
variabel numerik dilakukan menggunakan metode capping dengan
pendekatan Interquartile Range (IQR). Suatu nilai dikategorikan
sebagai outlier apabila berada di bawah batas \[Q1−1,5×IQR\] atau di atas batas \[Q3+1,5×IQR\]. Perhitungan batas dilakukan
berdasarkan data latih untuk menghindari kebocoran informasi (data
leakage) dari data uji. Berdasarkan hasil, variabel Suhu
dan Kelembapan tidak memiliki outlier, sedangkan
variabel Kecepatan Angin memiliki 5 outlier.
Pada variabel Suhu pada gambar 4.1 dan 4.2, nilai
pengamatan berkisar antara 22,5 hingga 31 dengan median sekitar 26.
Histogram menunjukkan distribusi data tanpa puncak yang ekstrem,
sedangkan boxplot tidak memperlihatkan titik di luar
whisker. Karena tidak ditemukan outlier, proses
capping tidak mengubah nilai pengamatan sehingga grafik sebelum
dan sesudah penanganan tetap sama.
Variabel Kelembapan pada gambar 4.3 dan 4.4 memiliki
rentang nilai sekitar 52 hingga 100 dengan median sekitar 86.
Distribusinya menceng ke kiri (left-skewed), dengan frekuensi
tertinggi berada pada kisaran 95–97. Nilai minimum masih berada di atas
batas bawah IQR, yaitu 44, sehingga tidak ditemukan outlier.
Oleh karena itu, penerapan capping tidak mengubah data dan
menghasilkan grafik yang identik dengan kondisi sebelum penanganan.
Sementara itu, variabel Kecepatan Angin sebelum
capping pada gambar 4.5 menunjukkan adanya 5 outlier
pada bagian atas distribusi, yang terlihat pada boxplot di
sekitar nilai 14 dan 15. Histogram juga memperlihatkan frekuensi yang
sangat tinggi pada nilai 3, yaitu sekitar 290 observasi. Kondisi
tersebut terjadi karena sebagian besar nilai yang hilang sebelumnya
digantikan menggunakan metode mode imputation. Akibatnya,
distribusi data menjadi terkonsentrasi pada satu nilai.
Setelah dilakukan capping menggunakan fungsi Winsorize
pada gambar 4.6, nilai yang melampaui batas atas 13 dibatasi menjadi 13
sehingga titik outlier tidak lagi terlihat pada
boxplot. Sementara itu, batas bawah sebesar −3 tidak
memengaruhi data karena nilai minimum pengamatan berada di sekitar 2.
Metode capping dipilih karena dapat membatasi nilai ekstrem
tanpa menghapus observasi, sehingga jumlah data latih tetap sebanyak 594
observasi. Batas capping yang diperoleh dari data latih
selanjutnya diterapkan pada data uji agar proses penanganan
outlier tetap konsisten dan tidak menimbulkan kebocoran
data.
# Parameter mean dan sd dihitung dari data latih saja
mean_val <- sapply(X_train_capped[list_num], mean, na.rm = TRUE)
sd_val <- sapply(X_train_capped[list_num], sd, na.rm = TRUE)
X_train_scale <- X_train_capped
X_test_scale <- X_test_capped
# fit_transform pada data latih
for (col in list_num) {
X_train_scale[[col]] <- (X_train_capped[[col]] - mean_val[col]) / sd_val[col]
}
# transform pada data uji (memakai parameter data latih)
for (col in list_num) {
X_test_scale[[col]] <- (X_test_capped[[col]] - mean_val[col]) / sd_val[col]
}
# Verifikasi: mean data latih ~ 0 dan sd ~ 1
round(sapply(X_train_scale[list_num], mean), 4)
## Suhu Kelembapan Kecepatan_Angin
## 0 0 0
round(sapply(X_train_scale[list_num], sd), 4)
## Suhu Kelembapan Kecepatan_Angin
## 1 1 1
Berdasarkan batasan masalah, penerapan Standard Scaler
dilakukan pada data dengan NPM genap untuk menyeragamkan skala variabel
numerik, yaitu Suhu, Kelembapan, dan
Kecepatan Angin. Metode ini mentransformasikan setiap nilai
menjadi skor standar dengan mengurangi nilai pengamatan menggunakan
rata-rata, kemudian membaginya dengan simpangan baku data latih.
Penskalaan ini bertujuan menyamakan skala ketiga variabel yang
sebelumnya memiliki rentang nilai berbeda, sehingga variabel dengan
nilai numerik lebih besar tidak secara otomatis mendominasi proses
analisis, khususnya pada algoritma yang sensitif terhadap skala
data.
Berdasarkan hasil verifikasi, rata-rata ketiga variabel pada data latih setelah proses standardisasi bernilai mendekati 0, sedangkan simpangan bakunya mendekati 1. Hasil tersebut menunjukkan bahwa proses Standard Scaler telah berjalan dengan baik. Parameter rata-rata dan simpangan baku dihitung berdasarkan data latih, kemudian digunakan untuk mentransformasikan data uji. Prosedur ini memastikan bahwa data uji diperlakukan sebagai data baru dan mencegah kebocoran informasi dari data uji ke proses pelatihan model.
list_cat <- c("Keadaan_Cuaca_reduced")
all_levels <- levels(df_imp$Keadaan_Cuaca_reduced)
# Samakan level kategori pada data latih dan data uji
X_train_scale$Keadaan_Cuaca_reduced <- factor(X_train_scale$Keadaan_Cuaca_reduced, levels = all_levels)
X_test_scale$Keadaan_Cuaca_reduced <- factor(X_test_scale$Keadaan_Cuaca_reduced, levels = all_levels)
# Buat resep encoding (fit dari data latih)
resep_encode <- recipe(~ ., data = X_train_scale[, c(list_num, list_cat)]) %>%
step_unknown(all_of(list_cat)) %>%
step_dummy(all_of(list_cat), one_hot = TRUE)
resep_encode_prep <- prep(resep_encode, training = X_train_scale[, c(list_num, list_cat)])
# Terapkan encoding (fit_transform pada data latih, transform pada data uji)
X_train_encoded <- bake(resep_encode_prep, new_data = X_train_scale[, c(list_num, list_cat)])
X_test_encoded <- bake(resep_encode_prep, new_data = X_test_scale[, c(list_num, list_cat)])
head(X_train_encoded)
## # A tibble: 6 × 14
## Suhu Kelembapan Kecepatan_Angin Keadaan_Cuaca_reduced_X0
## <dbl> <dbl> <dbl> <dbl>
## 1 -1.39 0.963 -0.701 1
## 2 0.0906 -0.581 -0.701 1
## 3 1.18 -1.87 -1.04 1
## 4 1.73 -2.47 0.654 1
## 5 1.49 -2.30 1.33 1
## 6 -0.143 -0.0660 -0.701 1
## # ℹ 10 more variables: Keadaan_Cuaca_reduced_X1 <dbl>,
## # Keadaan_Cuaca_reduced_X2 <dbl>, Keadaan_Cuaca_reduced_X3 <dbl>,
## # Keadaan_Cuaca_reduced_X4 <dbl>, Keadaan_Cuaca_reduced_X5 <dbl>,
## # Keadaan_Cuaca_reduced_X6 <dbl>, Keadaan_Cuaca_reduced_X7 <dbl>,
## # Keadaan_Cuaca_reduced_X8 <dbl>, Keadaan_Cuaca_reduced_X9 <dbl>,
## # Keadaan_Cuaca_reduced_unknown <dbl>
dim(X_train_encoded)
## [1] 594 14
dim(X_test_encoded)
## [1] 149 14
Berdasarkan batasan masalah, variabel
Keadaan Cuaca_reduced yang telah melalui proses reduksi
kategori selanjutnya dikonversi menggunakan metode one-hot
encoding. Proses ini diperlukan karena variabel tersebut bertipe
factor, sehingga kategori diubah menjadi kolom biner
agar dapat digunakan dalam pemodelan. Setiap kolom mewakili satu
kategori, dengan nilai 1 menunjukkan bahwa observasi termasuk dalam
kategori tersebut dan nilai 0 menunjukkan sebaliknya.
Pada enam observasi pertama, kolom
Keadaan_Cuaca_reduced_X0 bernilai 1, yang menunjukkan bahwa
observasi tersebut berada pada kategori 0, yaitu rentang nilai asli
0–10. Penggunaan levels = all_levels memastikan kategori
yang tersedia pada data latih dan data uji tetap konsisten. Sementara
itu, step_unknown menambahkan kolom untuk mengakomodasi
kategori yang tidak dikenal. Kolom unknown bernilai 0 pada
seluruh observasi karena tidak terdapat nilai yang masuk ke kategori
tersebut.
Hasil pengodean menghasilkan 14 kolom fitur, yang terdiri atas 3
variabel numerik hasil standardisasi, 10 kolom dummy untuk kategori 0–9,
dan 1 kolom unknown. Data latih memiliki ukuran 594 × 14,
sedangkan data uji berukuran 149 × 14. Kesamaan jumlah kolom menunjukkan
bahwa struktur fitur kedua data telah konsisten. Resep pengodean
terlebih dahulu dipelajari melalui fungsi prep menggunakan
data latih, kemudian diterapkan pada data latih dan data uji dengan
fungsi bake.
# 9. Balancing Data (SMOTE)
# Distribusi kelas sebelum SMOTE
table(y_train)
## y_train
## 1 2
## 131 463
prop.table(table(y_train))
## y_train
## 1 2
## 0.2205387 0.7794613
# Gabungkan fitur dan target (SMOTE membutuhkan target bertipe factor)
train_full <- X_train_encoded %>%
mutate(Hujan = factor(y_train))
set.seed(46)
resep_smote <- recipe(Hujan ~ ., data = train_full) %>%
step_smote(Hujan, over_ratio = 1, neighbors = 5)
resep_smote_prep <- prep(resep_smote, training = train_full)
train_balanced <- bake(resep_smote_prep, new_data = NULL)
# Distribusi kelas setelah SMOTE
table(train_balanced$Hujan)
##
## 1 2
## 463 463
prop.table(table(train_balanced$Hujan))
##
## 1 2
## 0.5 0.5
dim(train_balanced)
## [1] 926 15
# Data uji tidak di-SMOTE, hanya disiapkan targetnya
test_final <- X_test_encoded %>%
mutate(Hujan = factor(y_test, levels = levels(train_full$Hujan)))
Berdasarkan batasan masalah, penanganan ketidakseimbangan kelas dilakukan menggunakan metode SMOTE (Synthetic Minority Over-sampling Technique). Sebelum penerapan SMOTE, data latih terdiri atas 131 observasi kelas 1 sebagai kelas minoritas dan 463 observasi kelas 2 sebagai kelas mayoritas, sebagaimana ditunjukkan pada hsil sintak. Ketidakseimbangan ini berpotensi menyebabkan model lebih cenderung mengenali kelas mayoritas dibandingkan kelas minoritas.
Metode SMOTE mengatasi permasalahan tersebut dengan menghasilkan
observasi sintetis pada kelas minoritas melalui interpolasi antara
observasi minoritas dan salah satu dari lima tetangga terdekatnya
(neighbors = 5). Parameter over_ratio = 1
digunakan untuk mencapai jumlah observasi yang seimbang antara kedua
kelas, sedangkan set.seed(46) memastikan proses dapat
direproduksi dengan hasil yang konsisten.
Setelah penerapan SMOTE, jumlah observasi pada kelas 1 dan kelas 2
masing-masing menjadi 463, dengan proporsi sebesar 50% untuk setiap
kelas. Sebanyak 332 observasi sintetis berhasil dibangkitkan sehingga
ukuran data latih meningkat dari 594 menjadi 926 observasi. Data
tersebut terdiri atas 14 fitur dan 1 variabel target, yaitu
Hujan. Penerapan SMOTE hanya dilakukan pada data latih,
sedangkan data uji tetap dipertahankan pada distribusi aslinya. Hal ini
bertujuan agar evaluasi model dapat menggambarkan kinerja pada data yang
tidak mengalami penyeimbangan sintetis. Selanjutnya, variabel target
Hujan pada data uji diubah menjadi tipe factor
agar sesuai dengan kebutuhan tahap pemodelan.
Konsep berbagai jenis feature engineering meliputi penanganan nilai yang hilang, normalisasi dan standardisasi, pengodean variabel kategorik, transformasi variabel, pembentukan fitur baru, ekstraksi fitur, serta seleksi fitur. Setiap teknik memiliki fungsi yang berbeda dalam meningkatkan kualitas dan relevansi data sesuai dengan karakteristik serta tujuan analisis.
Penerapan teknik feature engineering menggunakan RStudio dapat dilakukan melalui bahasa pemrograman R dan berbagai paket pendukung untuk mengolah, mentransformasi, membentuk, serta menyeleksi fitur. Penerapan teknik yang tepat diharapkan dapat menghasilkan data yang lebih terstruktur dan mendukung proses analisis statistik maupun pemodelan machine learning secara efektif.
Berdasarkan hasil penerapan metode SMOTE, data latih yang awalnya
tidak seimbang, yaitu 131 observasi pada kelas 1 dan 463 observasi pada
kelas 2, berhasil diseimbangkan menjadi masing-masing 463 observasi
dengan proporsi 50% : 50%. Proses ini menghasilkan 332 observasi
sintetis sehingga jumlah data latih meningkat dari 594 menjadi 926
observasi, yang terdiri atas 14 fitur dan 1 variabel target
Hujan. Penerapan SMOTE hanya dilakukan pada data latih,
sedangkan data uji tetap dipertahankan pada distribusi aslinya agar
evaluasi model dapat mencerminkan kinerja pada data yang tidak mengalami
penyeimbangan sintetis.
Laporan praktikum ini melakukan pemograman R. Dalam hal ini perlu memahami sintak yang diperlukan dalam hal pengerjaannya ini agar tidak terjadi error pada programnya. Dan juga sangat perlu memahami bagaimana machine learning beropasi dan bagaimana cara kerja feature learning dan teknik apa saja yang digunakan kedalam analisis tersebut.
Budianita, A. (2023). Information Gain Berbasis Algoritma Naive Bayes Classifier Pada Pemodelan Prediksi Kelulusan Information Gain Based on Naive Bayes Classifier Algorithm in Graduation Prediction Modeling. Jurnal Ilmiah Intech: Information Technology Journal of UMUS, 5(1), 1–10.
Darmawan, R., Yut, I. V., Hernando, A., Handayani, R. I., Pratiwi, L., & Widanengsih, E. (2024). ANALISIS PERAN FEATURE ENGINEERING PADA KINERJA MODEL MACHINE LEARNING UNTUK KLASIFIKASI POTENSI TSUNAMI. 14(1).
Fauzi, N. P. N., Khomsah, S., & Wicaksono, A. D. P. (2025). Penerapan Feature Engineering dan Hyperparameter Tuning untuk Meningkatkan Akurasi Model Random Forest pada Klasifikasi Risiko Kredit. Jurnal Teknologi Informasi dan Ilmu Komputer, 12(2), 251–262. https://doi.org/10.25126/jtiik.2025128472
Fransiska, H. (2026). Modul Praktikum Machine Learning and Modern Prediction. Bengkulu: Laboratorium Matematika Fakultas Matematika dan Ilmu Pengetahuan Alam Universitas Bengkulu.
Hadi, R., Suwirmayanti, N. L. G. P., Kusuma, I. G. N. A., Saryanti, I. G. A. D., & Novayanti, P. D. (2024). Implementasi Metode Normalisasi dan Seleksi Fitur dalam Optimasi Algoritma K-Nearest Neighbor ( KNN ) untuk Klasifikasi Data Bank. 7(5), 1064–1071.
Herdian, C., Kamila, A., Tampinongkol, F. F., Kembau, A. S., & Budidarma, I. G. A. M. (2024). ONE-HOT ENCODING FEATURE ENGINEERING UNTUK LABEL-BASED DATA STUDI KASUS PREDIKSI HARGA MOBIL BEKAS One-Hot Encoding ke dalam prediksi harga. 9, 10–16.
Hr, S. Z., Aziz, A., & Harianto, W. (2022). Optimasi algoritma k-nearest neighbor (knn) dengan normalisasi dan seleksi fitur untuk klasifikasi penyakit liver. 6(2), 439–445.
Putri, D. F. A., Masjkur, M., & Indahwati. (2023). Penerapan Bernoulli Naïve Bayes untuk Analisis Sentimen Pengguna Twitter Terhadap Layanan Online Food Delivery di Indonesia. Xplore: Journal of Statistics, 12(1), 50–62. https://doi.org/10.29244/xplore.v12i1.1110
Sihombing, D. J. C. (2024). Application of Feature Engineering Techniques and Machine Learning Algorithms for Property Price Prediction. JITSI: Jurnal Ilmiah Teknologi Sistem Informasi, 5(2), 72–76. https://doi.org/10.62527/jitsi.5.2.241
Winata, F., Ilham, M., Tresnawan, A., & Wijaya, G. (2026). Integrasi Feature Engineering dan SMOTE pada Algoritma Random Forest untuk Prediksi Kerusakan Chip RFID di Industri Sel Surya. 7(2), 599–609. https://doi.org/10.47065/josh.v7i2.9038