Data merupakan sumber informasi utama dalam analisis, dan setiap data tersusun atas variabel atau fitur yang menggambarkan karakteristik objek yang diamati. Kualitas fitur menentukan seberapa baik informasi dalam data dapat dimanfaatkan untuk analisis maupun pemodelan. Data mentah umumnya memiliki skala beragam, tipe berbeda, dan nilai yang hilang. Penyiapan fitur yang tepat diperlukan agar data dapat digunakan secara optimal.
Feature engineering adalah proses mengubah, membentuk, dan memilih fitur dari data mentah agar lebih representatif bagi kebutuhan analisis. Tujuan utamanya adalah meningkatkan kualitas data sehingga model dapat mengenali pola dengan lebih baik. Proses ini mencakup berbagai teknik, seperti transformasi variabel, penskalaan, pengodean data kategorik, dan pembentukan fitur baru. Pemilihan teknik bergantung pada karakteristik data dan tujuan analisis (Sihombing, 2024).
Pemahaman terhadap berbagai teknik feature engineering perlu diiringi kemampuan menerapkannya pada data. RStudio sebagai lingkungan pengembangan terpadu bagi bahasa R menyediakan beragam fungsi dan package untuk mengolah serta membentuk fitur. Pemrograman di dalamnya memungkinkan setiap tahapan dilakukan secara sistematis dan dapat diulang pada data yang berbeda. Penerapan melalui RStudio menjadikan konsep feature engineering dapat diwujudkan sebagai proses pengolahan data yang terarah.
Berdasarkan latar belakang di atas, adapun rumusan masalah yang dapat disimpulkan sebagai berikut:
Adapun tujuan penelitian ini yaitu:
Feature engineering merupakan tahap penting dalam pengembangan model prediktif yang melibatkan transformasi variabel-variabel data menjadi bentuk yang lebih representatif untuk meningkatkan kinerja model (Herdian dkk., 2024). Proses ini menggunakan pengetahuan domain untuk mengekstrak atau membuat fitur-fitur baru dari data mentah, dan langkah ini penting karena performa model machine learning sangat bergantung pada kualitas fitur input (Darmawan dkk., 2026). Feature engineering memungkinkan penggalian informasi yang lebih dalam dari data yang ada, seperti variabel lingkungan, tren pasar, dan preferensi konsumen (Sihombing, 2024).
Tujuan dari feature engineering adalah menyederhanakan dan mempercepat transformasi data sekaligus meningkatkan akurasi model, di mana kualitas fitur jauh lebih penting daripada seberapa canggih algoritma yang dipilih (Fransiska, 2026). Feature engineering diperlukan untuk menciptakan representasi data yang sesuai bagi model machine learning, terutama dalam menangani data yang berbentuk label kategori atau non-numerik (Herdian dkk., 2024). Feature engineering yang tepat lebih berdampak daripada pemilihan model, sehingga pemahaman domain dan penciptaan fitur yang cerdas menjadi faktor penentu keberhasilan pemodelan (Darmawan dkk., 2026).
Fitur atau variabel dalam machine learning merujuk pada atribut atau karakteristik yang digunakan sebagai input untuk model prediktif. Fitur merupakan representasi dari karakteristik atau properti yang melekat pada objek data yang akan dianalisis (Herdian dkk., 2024). Dalam pemodelan machine learning, fitur berperan sebagai variabel prediktor yang digunakan untuk memprediksi variabel target (Sihombing, 2024).
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).
Teknik feature engineering mencakup berbagai metode yang digunakan untuk mengubah data mentah menjadi fitur yang lebih informatif dan siap digunakan dalam pemodelan machine learning. Beberapa teknik feature engineering meliputi penanganan missing value, transformasi variabel, standardisasi, scaling, encoding, diskretisasi, pembuatan fitur baru, dan seleksi fitur. Berikut merupakan teknik-teknik feature engineering yang digunakan dalam proses pengolahan data:
1. Missing Value Imputation
Missing values atau data hilang terjadi ketika tidak ada nilai yang tersimpan untuk observasi tertentu dalam suatu variabel dan merupakan kejadian umum yang dapat berdampak signifikan pada pemodelan machine learning (Fransiska, 2026). Metode imputasi meliputi metode konvensional dengan mean dan nilai maksimum, serta metode data mining menggunakan KNN dan Neural Network (Prasetya dkk., 2023).
2. Transformasi Variabel
Transformasi variabel merupakan teknik feature engineering yang mengubah skala atau distribusi data untuk meningkatkan representasi data dalam pemodelan. Feature engineering juga mencakup pembuatan fitur turunan seperti rasio antara dua variabel untuk menangkap hubungan yang tidak terlihat pada data mentah (Darmawan dkk., 2026).
3. Standardization
Standardization atau standardisasi merupakan teknik feature engineering yang diterapkan untuk menormalkan distribusi data. Standardisasi menggunakan Robust Scaler dengan rumus:
\[ x' = \frac{x - Q_2}{Q_3 - Q_1} \]
di mana \(x'\) merupakan hasil standardisasi, \(x\) adalah nilai asli, \(Q_2\) adalah nilai tengah data, dan \(Q_3 - Q_1\) merupakan Interquartile Range (IQR). Standardisasi bertujuan untuk menyetarakan skala antar fitur sehingga model tidak berat sebelah terhadap fitur dengan nilai yang lebih besar (Fauzi dkk., 2025).
4. 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).
5. 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 dkk., 2025). Feature encoding diperlukan karena banyak algoritma machine learning membutuhkan input numerik (Fransiska, 2026).
6. 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 dkk., 2024).
7. Diskretisasi atau Binning
Diskretisasi atau binning merupakan teknik feature engineering yang mengubah data kontinu menjadi data interval (Herdian dkk., 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 dkk., 2026).
8. 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 dkk., 2026).
9. 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 dkk., 2023). Rumus entropy dan information gain adalah sebagai berikut:
\[ Entropy(S) = -\sum_{i=1}^{c} p_i \log_2(p_i) \]
\[ Gain(S,A) = Entropy(S) - \sum_{v \in Values(A)} \frac{|S_v|}{|S|} \times Entropy(S_v) \]
di mana \(Entropy(S)\) adalah nilai entropy keseluruhan, \(c\) adalah jumlah label sentimen, \(p_i\) adalah rasio label ke-\(i\) pada seluruh tweet, \(Gain(S,A)\) adalah nilai information gain tiap fitur, \(A\) adalah fitur, \(v\) adalah kemungkinan nilai fitur \(A\), \(S_v\) adalah jumlah tweet untuk nilai \(v\), dan \(Entropy(S_v)\) adalah nilai entropy setelah dipartisi dengan fitur \(A\). Penetapan nilai threshold dalam pemilihan fitur dengan information gain dapat ditentukan dengan nilai 0,05, di mana fitur dengan nilai information gain < 0,05 akan direduksi (Putri dkk., 2023). Correlation-based feature selection merupakan teknik seleksi fitur yang memperhitungkan suatu fitur yang memiliki korelasi yang baik dan relevan dengan kelasnya dan tidak memiliki korelasi berlebihan dengan fitur lainnya (Asmoro dkk., 2021).
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
library(zoo)
library(readxl)
library(tidyverse)
library(rsample)
library(e1071)
library(DescTools)
library(dplyr)
library(ggplot2)
library(gridExtra)
library(recipes)
library(themis)
library(caret)
# Import Data
data <- read_excel("C:/Users/Andini Putri Aria/Documents/UNIB/Statistics 23/Semester 7/Machine Learning and Modern Prediction/Laporan Praktikum/Pt 1/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
## 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 ...
Tabel 4.1 Fungsi library dalam preprocessing
| Library | Fungsi |
|---|---|
readxl |
Membaca data dari berkas Excel |
tidyverse, dplyr |
Manipulasi dan penyaringan data |
zoo |
Interpolasi nilai hilang (na.approx) |
DescTools |
Perhitungan modus (Mode) dan capping
(Winsorize) |
rsample |
Pembagian data latih dan data uji |
e1071 |
Perhitungan skewness |
ggplot2, gridExtra |
Visualisasi histogram dan boxplot |
recipes |
Pengodean variabel kategorik |
themis |
Penyeimbangan kelas dengan SMOTE |
caret |
Pendukung pemodelan dan evaluasi |
Pada batasan masalah diminta penggunaan data curah hujan untuk melakukan preprocessing data. Tahap awal yang dikerjakan adalah memuat library yang dibutuhkan dan mengimpor data ke RStudio. Sebelas library berhasil dimuat tanpa kesalahan. Fungsi masing-masing library tersaji pada Tabel 4.1.
Fungsi head() menampilkan enam observasi pertama dari
dataset, sedangkan fungsi str() memperlihatkan
struktur data secara keseluruhan. Dataset terdiri atas 743
observasi dan 5 variabel yang seluruhnya bertipe numerik. Variabel
Hujan bernilai 1 dan 2 sehingga berperan sebagai variabel
target. Empat variabel lainnya, yaitu Suhu,
Kelembapan, Keadaan Cuaca, dan
Kecepatan Angin berperan sebagai fitur.
Keluaran head() dan str() menghasilkan
empat temuan yang menentukan langkah selanjutnya. Variabel
Keadaan Cuaca dan Kecepatan Angin memiliki
nilai NA sehingga memerlukan penanganan missing
value. Variabel Keadaan Cuaca bertipe numerik tetapi
sebenarnya berupa kode kategori dengan nilai yang sangat beragam,
sehingga memerlukan reduksi kardinalitas dan pengodean. Satuan dan
rentang variabel numerik berbeda serta proporsi kelas Hujan
belum diketahui, sehingga diperlukan pemeriksaan outlier,
penskalaan, dan pengecekan keseimbangan data.
## Hujan Suhu Kelembapan Keadaan_Cuaca Kecepatan_Angin
## 0 0 0 9 314
## Hujan Suhu Kelembapan Keadaan_Cuaca Kecepatan_Angin
## 0.00000000 0.00000000 0.00000000 0.01211306 0.42261104
## # 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
# Penanganan Missing Value
df_imp <- data
# 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
# 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
Tabel 4.2 Jumlah dan persentase missing value sebelum penanganan
| Variabel | Jumlah missing value | Persentase |
|---|---|---|
Hujan |
0 | 0,00% |
Suhu |
0 | 0,00% |
Kelembapan |
0 | 0,00% |
Keadaan Cuaca |
9 | 1,21% |
Kecepatan Angin |
314 | 42,26% |
Pada batasan masalah diminta penanganan missing value dengan
interpolasi pada Keadaan Cuaca dan mode imputation
pada Kecepatan Angin. Pemeriksaan awal menunjukkan bahwa
nilai kosong hanya terdapat pada dua variabel, sebagaimana tersaji pada
Tabel 4.2. Variabel Keadaan Cuaca memiliki 9 nilai kosong,
sedangkan Kecepatan Angin memiliki 314 nilai kosong.
Variabel Hujan, Suhu, dan
Kelembapan tidak memiliki nilai kosong.
Interpolasi pada Keadaan Cuaca dilakukan dengan fungsi
na.approx, yang mengisi nilai kosong berdasarkan estimasi
linear dari nilai di sekitarnya. Argumen rule = 2
memastikan nilai kosong di awal atau akhir data tetap terisi. Sembilan
nilai kosong pada variabel ini berhasil diisi sehingga jumlahnya menjadi
nol. Variabel Kecepatan_Angin masih memiliki 314 nilai
kosong pada tahap ini.
Mode imputation pada Kecepatan Angin mengisi
nilai kosong dengan nilai yang paling sering muncul. Perhitungan
menunjukkan bahwa modus variabel tersebut adalah 3. Seluruh 314 nilai
kosong diganti dengan angka 3 sehingga tidak ada lagi missing
value pada dataset. Proporsi nilai kosong pada
Kecepatan Angin mencapai 42,26% sehingga penghapusan baris
akan membuang hampir separuh data. Imputasi dipilih agar jumlah
observasi tetap terjaga. Angka 3 menjadi sangat dominan pada variabel
ini sebagai konsekuensinya.
## # 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
## [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
# Tentukan batas bin
bins <- c(0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100)
# Tentukan label untuk setiap bin (10 label: 0 s/d 9)
labels <- 0:9
# 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
)
# Verifikasi
cat("--- Hasil Perbandingan ---\n")## --- Hasil Perbandingan ---
## # A tibble: 10 × 6
## Hujan Suhu Kelembapan Keadaan_Cuaca Kecepatan_Angin Keadaan_Cuaca_reduced
## <dbl> <dbl> <dbl> <dbl> <dbl> <fct>
## 1 2 27.2 85 1 2 0
## 2 2 27.7 88 13 3 1
## 3 2 27 87 2 3 0
## 4 1 23.7 98 60 3 5
## 5 2 29.7 61 2 8 0
## 6 2 24.3 93 3 3 0
## 7 2 23.4 94 2 3 0
## 8 1 25.1 90 2 3 0
## 9 2 30.3 67 2 9 0
## 10 2 24.3 90 60 4 5
##
## --- Pengecekan Kardinalitas ---
## 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
##
## Kategori unik yang baru (reduced):
## [1] 0 1 5 6 2 9 4
## Levels: 0 1 2 3 4 5 6 7 8 9
Tabel 4.3 Hasil pengelompokan nilai
Keadaan_Cuaca
| Nilai asli | Interval | Kategori baru |
|---|---|---|
| 1; 1,5; 2; 3; 5; 10 | 0–10 | 0 |
| 13; 14; 15; 16; 17 | 10–20 | 1 |
| 21; 29 | 20–30 | 2 |
| 49 | 40–50 | 4 |
| 56; 60 | 50–60 | 5 |
| 61; 62; 63; 65 | 60–70 | 6 |
| 91; 95; 97 | 90–100 | 9 |
Pada batasan masalah diminta interpolasi pada
Keadaan Cuaca, yang menghasilkan variabel dengan nilai
beragam sehingga kardinalitasnya perlu diperiksa. Kardinalitas adalah
jumlah kategori unik pada suatu variabel. Variabel
Keadaan Cuaca memiliki 23 nilai unik, misalnya 1; 1,5; 2;
5; 14; 60; 95; dan 97. Kardinalitas setinggi ini menyulitkan pengodean
karena one hot encoding akan menghasilkan banyak kolom yang
sebagian besar bernilai nol dan berisiko memicu
overfitting.
Reduksi kardinalitas dilakukan dengan binning menggunakan
fungsi cut(). Nilai dikelompokkan ke dalam 10 interval yang
masing-masing selebar 10 dengan format (a, b], lalu diberi label 0
sampai 9. Argumen include.lowest = TRUE memastikan nilai
batas bawah, yaitu 0, tetap tercakup pada interval pertama. Hasil
pengelompokan tersaji pada Tabel 4.3.
Jumlah kategori turun dari 23 menjadi 7, yaitu kategori 0, 1, 2, 4, 5, 6, dan 9. Sebagian besar observasi masuk kategori 0 karena nilai asli 1, 2, dan 3 paling sering muncul. Variabel hasil reduksi bertipe factor dengan 10 level, sehingga seluruh level tetap tersimpan meskipun sebagian tidak muncul pada data. Struktur ini menjaga kesamaan kategori antara data latih dan data uji saat pengodean.
# Splitting Data (Stratify)
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
## [1] 149 5
## y_train
## 1 2
## 0.2205387 0.7794613
## y_test
## 1 2
## 0.2214765 0.7785235
Tabel 4.4 Ukuran data dan proporsi kelas hasil stratify splitting
| Data | Jumlah observasi | Proporsi kelas 1 | Proporsi kelas 2 |
|---|---|---|---|
| Data latih | 594 | 22,05% | 77,95% |
| Data uji | 149 | 22,15% | 77,85% |
Pada batasan masalah diminta stratify splitting untuk NPM
genap. Data dibagi dengan perbandingan 80% untuk data latih dan 20%
untuk data uji, dengan set.seed(46) agar hasil pembagian
dapat direproduksi. Data latih berisi 594 observasi dan data uji berisi
149 observasi, masing-masing dengan 5 kolom. Variabel Hujan
dipisahkan sebagai target dalam objek y_train dan
y_test.
Stratify splitting membagi data per kelas target sehingga proporsi kelas pada kedua subset tetap mendekati data asli. Kelas 1 menempati 22,05% pada data latih dan 22,15% pada data uji, sedangkan kelas 2 menempati 77,95% dan 77,85% sebagaimana tersaji pada Tabel 4.4. Selisih proporsi yang sangat kecil menunjukkan bahwa data uji merepresentasikan data latih dengan baik. Proporsi tersebut sekaligus menunjukkan bahwa data tidak seimbang karena kelas 2 berjumlah sekitar empat kali lipat kelas 1. Kondisi ini berpotensi membuat model condong pada kelas mayoritas.
# Daftar fitur numerik
list_num <- c("Suhu", "Kelembapan", "Kecepatan_Angin")
# 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
# 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))
}
# Fungsi plot diagnostik
diagnostic_plots <- function(df, variable) {
p1 <- ggplot(df, aes(x = .data[[variable]])) +
geom_histogram(bins = 30, fill = "#008080", 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)
}Tabel 4.5 Jumlah outlier dan batas IQR pada data latih
| Variabel | Jumlah outlier | Batas bawah | Batas atas |
|---|---|---|---|
Suhu |
0 | 17,5 | 35,9 |
Kelembapan |
0 | 44,0 | 124,0 |
Kecepatan_Angin |
5 | −3,0 | 13,0 |
Gambar 4.1 Histogram dan boxplot Suhu sebelum capping
Gambar 4.2 Histogram dan boxplot Suhu setelah capping
Gambar 4.3 Histogram dan boxplot Kelembapan sebelum capping
Gambar 4.4 Histogram dan boxplot Kelembapan setelah capping
Gambar 4.5 Histogram dan boxplot Kecepatan_Angin sebelum capping
Gambar 4.6 Histogram dan boxplot Kecepatan_Angin setelah capping
Pada batasan masalah diminta capping pada data numerik.
Deteksi outlier memakai metode IQR, yaitu nilai di bawah \(Q1 − 1,5×IQR\) atau di atas \(Q3 + 1,5×IQR\) dikategorikan sebagai
outlier. Batas dihitung dari data latih saja agar tidak terjadi
kebocoran data dari data uji. Hasilnya tersaji pada Tabel 4.5, yaitu
Suhu dan Kelembapan tidak memiliki
outlier, sedangkan Kecepatan Angin memiliki 5
outlier.
Variabel Suhu (Gambar 4.1 dan 4.2) berkisar sekitar 22,5
sampai 31 dengan median sekitar 26. Histogramnya menyebar tanpa puncak
yang ekstrem, dan boxplot tidak menampilkan titik di luar
whisker. Capping tidak mengubah data karena tidak ada
outlier. Grafik sebelum dan sesudah capping menjadi
identik.
Variabel Kelembapan (Gambar 4.3 dan 4.4) berkisar
sekitar 52 sampai 100 dengan median sekitar 86. Histogramnya menceng ke
kiri dengan frekuensi tertinggi di sekitar nilai 95 sampai 97. Nilai
terendahnya masih berada di atas batas bawah 44 sehingga tidak ada
outlier. Grafik sebelum dan sesudah capping pun
identik.
Variabel Kecepatan Angin sebelum capping
(Gambar 4.5) memiliki 5 outlier pada sisi atas, tampak sebagai
titik di sekitar nilai 14 dan 15 pada boxplot. Histogramnya
menunjukkan lonjakan sangat tinggi pada nilai 3, yaitu sekitar 290
observasi, yang berasal dari mode imputation. Lonjakan ini
membuat distribusi terpusat pada satu nilai. Pola tersebut menjadi
konsekuensi dari besarnya proporsi nilai kosong yang diisi dengan
modus.
Setelah capping dengan Winsorize (Gambar 4.6),
nilai yang melebihi 13 diganti menjadi 13 sehingga boxplot
tidak lagi menampilkan titik outlier. Batas bawah −3,0 tidak
berpengaruh karena nilai minimum data sekitar 2. Capping
dipilih karena mempertahankan seluruh observasi dan hanya membatasi
nilai ekstrem, sehingga ukuran data latih tetap 594 observasi. Batas
yang sama dari data latih juga diterapkan pada data uji.
# Standard Scaler
# 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
## Suhu Kelembapan Kecepatan_Angin
## 1 1 1
Tabel 4.6 Rata-rata dan simpangan baku data latih setelah Standard Scaler
| Variabel | Rata-rata | Simpangan baku |
|---|---|---|
Suhu |
0 | 1 |
Kelembapan |
0 | 1 |
Kecepatan Angin |
0 | 1 |
Pada batasan masalah diminta penggunaan Standard Scaler
untuk NPM genap. Metode ini mengubah setiap nilai menjadi
z-score dengan rumus \(z = \frac{x -
\mu}{\sigma}\), dengan \(\mu\)
adalah rata-rata dan \(\sigma\) adalah
simpangan baku data latih. Penskalaan menyamakan skala
Suhu, Kelembapan, dan
Kecepatan Angin yang semula berbeda satuan dan rentang.
Skala yang seragam mencegah satu variabel mendominasi hanya karena
nilainya besar, terutama pada algoritma yang sensitif terhadap
skala.
Verifikasi pada Tabel 4.6 menunjukkan bahwa rata-rata ketiga variabel pada data latih sama dengan 0 dan simpangan bakunya sama dengan 1. Hasil ini menandakan bahwa proses penskalaan berhasil. Parameter \(\mu\) dan \(\sigma\) dihitung dari data latih, lalu dipakai untuk mentransformasi data uji. Cara ini memperlakukan data uji sebagai data baru sehingga tidak terjadi kebocoran informasi.
# One Hot Encoder
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>
## [1] 594 14
## [1] 149 14
Pada batasan masalah diminta interpolasi pada
Keadaan Cuaca, yang kemudian direduksi menjadi
Keadaan Cuaca_reduced sehingga perlu diubah ke bentuk
numerik melalui pengodean. Variabel ini bertipe factor sehingga
belum dapat diproses langsung oleh sebagian besar algoritma pemodelan.
One hot encoding mengubahnya menjadi kolom biner, satu kolom
untuk setiap kategori. Nilai 1 menandakan observasi termasuk kategori
pada kolom tersebut, sedangkan nilai 0 menandakan sebaliknya.
Pada enam observasi pertama, kolom
Keadaan_Cuaca_reduced_X0 bernilai 1 yang berarti seluruhnya
termasuk kategori 0, yaitu nilai asli 0 sampai 10. Penyamaan
level dengan levels = all_levels memastikan data
latih dan data uji memiliki kolom yang sama. Tahap
step_unknown menambahkan kolom
Keadaan_Cuaca_reduced_unknown untuk menampung kategori yang
hilang atau tidak dikenal. Kolom ini seluruhnya bernilai 0 karena data
sudah tidak memiliki missing value.
Hasil akhir pengodean memiliki 14 kolom, yaitu 3 fitur numerik
terskala, 10 kolom dummy untuk level 0 sampai 9, dan 1
kolom unknown. Data latih berukuran 594 × 14 dan data uji
berukuran 149 × 14. Jumlah kolom yang sama pada kedua data menandakan
struktur fitur yang konsisten. Resep pengodean dipelajari dari data
latih (prep), lalu diterapkan pada kedua data
(bake).
## y_train
## 1 2
## 131 463
## 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
##
## 1 2
## 0.5 0.5
## [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)))Tabel 4.7 Distribusi kelas data latih sebelum dan sesudah SMOTE
| Kondisi | Kelas 1 | Kelas 2 | Total | Proporsi kelas 1 : kelas 2 |
|---|---|---|---|---|
| Sebelum SMOTE | 131 | 463 | 594 | 22,05% : 77,95% |
| Sesudah SMOTE | 463 | 463 | 926 | 50% : 50% |
Pada batasan masalah diminta penanganan data tidak seimbang menggunakan SMOTE. Sebelum SMOTE, data latih tidak seimbang karena kelas 1 sebagai kelas minoritas hanya berjumlah 131 observasi, sedangkan kelas 2 sebagai kelas mayoritas berjumlah 463 observasi. Kondisi tersebut tersaji pada Tabel 4.7. Model yang dilatih pada data seperti ini cenderung memprediksi kelas mayoritas dan kurang peka terhadap kelas minoritas.
SMOTE (Synthetic Minority Over-sampling Technique)
menyeimbangkan kelas dengan membangkitkan observasi sintetis untuk kelas
minoritas. Titik baru dibentuk dengan menginterpolasi antara suatu
observasi minoritas dan salah satu dari 5 tetangga terdekatnya
(neighbors = 5). Argumen over_ratio = 1
menargetkan jumlah kelas minoritas sama dengan kelas mayoritas.
Pembangkitan data memakai set.seed(46) agar hasilnya dapat
direproduksi.
Sesudah SMOTE, kedua kelas masing-masing berjumlah 463 observasi
dengan proporsi 50% : 50%. Sebanyak 332 observasi sintetis dibangkitkan
(463 − 131) sehingga ukuran data latih bertambah dari 594 menjadi 926
observasi. Jumlah kolom menjadi 15, yaitu 14 fitur ditambah variabel
target Hujan.
SMOTE hanya diterapkan pada data latih. Data uji dibiarkan pada
distribusi aslinya agar evaluasi model mencerminkan kondisi data yang
sebenarnya. Pada data uji hanya ditambahkan variabel target
Hujan dalam bentuk factor sehingga siap digunakan
pada tahap pemodelan.
Feature engineering adalah proses mentransformasi variabel data menjadi bentuk yang lebih representatif untuk meningkatkan kinerja model prediktif. Konsep ini mencakup berbagai teknik, yaitu imputasi missing value, transformasi variabel, standardisasi, scaling, Label Encoding, One-Hot Encoding, diskretisasi, pembuatan fitur baru, dan seleksi fitur. Masing-masing teknik dipilih sesuai jenis data, yaitu numerik atau kategorik, serta tingkat kardinalitas variabel.
Penerapan teknik feature engineering di RStudio didukung
oleh berbagai package yang menyediakan fungsi pada setiap tahap
pengolahan data. Penanganan missing value memakai
tidyverse dan zoo, pembagian data memakai
rsample, dan penanganan outlier memakai
DescTools. Pengodean dan penyeimbangan data memakai
recipes dan themis, sedangkan visualisasi
distribusi memakai ggplot2 dan gridExtra.
Rangkaian fungsi tersebut membuat tahapan pengolahan data berjalan
secara sistematis dan dapat diulang.
Pada batasan masalah, preprocessing data curah hujan
menggunakan mode imputation, stratify splitting, dan
Standard Scaler, dilengkapi interpolasi pada
Keadaan Cuaca, capping pada data numerik, dan
SMOTE. Seluruh missing value berhasil ditangani, kardinalitas
Keadaan Cuaca berkurang dari 23 menjadi 7 kategori, dan
proporsi kelas data latih serta data uji tetap serupa. Penskalaan
menghasilkan rata-rata 0 dan simpangan baku 1, sedangkan SMOTE
menyeimbangkan kelas data latih menjadi 463 observasi pada masing-masing
kelas.
Penelitian selanjutnya disarankan membandingkan beberapa metode pada
tahap yang sama, misalnya mean, median, dan mode
imputation pada penanganan missing value, atau
Standard Scaler dan Robust Scaler pada penskalaan.
Perbandingan tersebut dapat dinilai melalui kinerja model sehingga
pemilihan teknik memiliki dasar yang lebih kuat. Proporsi missing
value yang besar pada Kecepatan Angin juga sebaiknya
ditangani dengan metode yang tidak memusatkan nilai pada satu angka,
seperti KNN. Selain itu, pengaruh feature engineering terhadap
hasil pemodelan perlu diuji agar manfaatnya dapat dibuktikan secara
langsung.
Asmoro, A. S. B., Irianto, W. S. G., & Pujianto, U. (2021). JEPIN (Jurnal Edukasi dan Penelitian Informatika) Perbandingan Kinerja Hasil Seleksi Fitur pada Prediksi Kinerja Akademik Siswa Berbasis Pohon Keputusan. JEPIN: Jurnal Edukasi dan Penelitian Informatika, 4(2), 84–89. www.kaggle.com/aljarah/xAPI-Edu-Data
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, R. L., & Widanengsih, E. (2026). Analisis Peran Feature Engineering pada Kinerja Model Machine Learning untuk Klasifikasi Potensi Tsunami. Jurnal Informatika dan Teknik Elektro Terapan, 14(1), 236–249. https://doi.org/10.23960/jitet.v14i1.8303
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.
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. Jurnal Informasi Interaktif, 9(1), 10–16.
Prasetya, M. R. A., Priyatno, A. M., & Nurhaeni. (2023). Penanganan Imputasi Missing Values pada Data Time Series dengan Menggunakan Metode Data Mining. Jurnal Informasi dan Teknologi, 5(2), 56–62. https://doi.org/10.37034/jidt.v5i1.324
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