BAB I PENDAHULUAN

1.1 Latar Belakang Masalah

Perkembangan teknologi informasi dan ilmu data di era digital mendorong untuk memiliki kemampuan dalam mengolah data secara efektif dan sistematis. Dalam bidang data science dan machine learning, salah satu tahapan penting yang perlu dipahami adalah feature engineering, yaitu proses mengolah data mentah menjadi fitur yang lebih relevan dan informatif. Penerapan teknik ini dapat membantu meningkatkan kualitas data sehingga model yang dibangun mampu mengenali pola dengan lebih baik (Darmawan, Putra, dan Lestari, 2023).

Berbagai teknik feature engineering, seperti normalisasi, transformasi data, seleksi fitur, dan encoding, digunakan untuk menyesuaikan karakteristik data dengan kebutuhan analisis. Normalisasi dan transformasi membantu mengatur skala atau bentuk data, seleksi fitur digunakan untuk memilih variabel yang relevan, sedangkan encoding mengubah data kategorikal menjadi bentuk numerik agar dapat diproses oleh algoritma tertentu. Oleh karena itu, pemahaman terhadap teknik-teknik tersebut menjadi bekal penting bagi mahasiswa dalam mempersiapkan data sebelum melakukan pemodelan (Fauzi, Rahman, dan Hidayat, 2022).

Selain memahami konsep secara teoritis, perlu juga menguasai penerapan feature engineering melalui perangkat pemrograman, seperti RStudio, yang mendukung proses pengolahan, transformasi, dan analisis data melalui berbagai package yang tersedia. Namun, pemahaman teori tanpa praktik secara langsung dapat menyebabkan mahasiswa mengalami kesulitan ketika menerapkan teknik tersebut pada dataset nyata. Dengan demikian,analisis feature engineering menggunakan RStudio diperlukan agar mampu memahami berbagai teknik pengolahan fitur sekaligus menerapkannya secara sistematis untuk menghasilkan data yang lebih siap digunakan dalam analisis.

1.2 Rumusan Masalah

  1. Apa saja konsep dan jenis-jenis feature engineering yang dapat diterapkan menggunakan RStudio?
  2. Bagaimana cara melakukan teknik feature engineering menggunakan program RStudio?

1.3 Tujuan

  1. Mahasiswa memahami konsep dari berbagai jenis feature engineering pada RStudio.
  2. Mahasiswa dapat melakukan teknik feature engineering di program RStudio.

BAB II TINJAUAN PUSTAKA

2.1 Feature Engineering

Feature engineering merupakan proses penting dalam pengolahan data yang bertujuan untuk meningkatkan kualitas fitur sebelum digunakan dalam model machine learning. Proses ini mencakup transformasi data mentah menjadi bentuk yang lebih informatif dan relevan sehingga dapat membantu model dalam mengenali pola data. Dalam praktiknya, keberhasilan suatu model tidak hanya bergantung pada algoritma yang digunakan, tetapi juga pada kualitas fitur yang dibangun. Oleh karena itu, feature engineering menjadi salah satu tahap krusial dalam analisis data modern (Santoso, Wibowo, & Hakim, 2021).

Berikut merupakan beberapa jenis feature engineering yang harus dilakukan:

1. Handling Missing Value

Missing values atau missing data, terjadi ketika tidak ada data atau tidak ada nilai yang tersimpan untuk observasi tertentu dalam suatu variabel. Missing data adalah kejadian yang umum dan dapat berdampak signifikan pada pemodelan machine learning. Data yang tidak lengkap adalah masalah yang tidak terhindarkan dalam menangani sebagian besar sumber data (Fransiska, 2026).

2. Kardinalitas

Kardinalitas merujuk pada jumlah nilai unik, atau label, yang terdapat dalam suatu variabel kategoris. Konsep ini digunakan untuk mengukur granularitas atau keunikan data dalam sebuah fitur. Kardinalitas dapat diklasifikasikan dalam spektrum, namun umunya dibedakan menjadi karnalitas rendah (low cardinality) dan kardinalitas tinggi (high cardinality). Pengaruh kardinalitas, sangat krusial terhadap performa model dan efisiensi komputasi. Pertama, variabel high cardinality dapat menyebabkan curse of dimensionality jika ditransformasi menggunakan metode encoding standar seperti One-Hot Encoding. Metode ini akan menciptakan banyak fitur biner baru (sesuai jumlah label), membuat data menjadi sangar jarang dan secara dratis meningkatkan kompleksitas overfitting. Hal ini terjadi karena banyak label mungkin hanya muncul beberapa kali dalam set data latih, sehingga model cenderung menghafal pola spesifik yang terkait dengan label langka tersebut, alih-alih mempelajari pola umum yang dapat digeneralisasi ke data yang belum pernah terlihat (Fransiska, 2026).

3. Splitting Data

Splitting data merupakan strategi dalam machine learning untuk membagi himpunan data menjadi bagian terpisah: data training dan data testing. Pembagian ini krusial untuk membangun model yang robust dan dapat digeneralisasi dengan baik pada data baru (Muraina, 2022). Proporsi pembagian data bersifat subjektif dan fleksibel. Rasio yang umum digunakan adalah 80% untuk training dan 20% untuk testing (Woschnagg dan Cipan, 2004). Namun, seperti yang ditekankan oleh Geron (2019), rasio ini dapat disesuaikan tergantung pada ukuran dataset.

4. Handling Outlier

Outlier merupakan observasi yang memiliki nilai berbeda secara ekstrem dibandingkan sebagian besar observasi lainnya. Keberadaan outlier dapat disebabkan oleh kesalahan pengukuran, kesalahan pencatatan, atau kondisi tertentu yang memang terdapat pada objek pengamatan. Identifikasi outlier dapat dilakukan menggunakan metode statistik, seperti Interquartile Range (IQR), maupun secara visual menggunakan boxplot. Nilai IQR dapat dirumuskan sebagai berikut:

\[ IQR = Q_3 - Q_1 \]

Batas bawah dan batas atas untuk mengidentifikasi outlier dapat dirumuskan sebagai:

\[ Batas\;Bawah = Q_1 - 1,5(IQR) \]

\[ Batas\;Atas = Q_3 + 1,5(IQR) \]

5. Scaling

Scaling merupakan proses mengubah skala nilai suatu fitur agar perbedaan rentang antarvariabel tidak terlalu memengaruhi proses pembelajaran model. Salah satu metode yang umum digunakan adalah standardization, yaitu mengubah nilai suatu variabel berdasarkan rata-rata dan simpangan bakunya. Persamaan standardization dapat dituliskan sebagai berikut:

\[ z_i = \frac{x_i-\bar{x}}{s} \]

dengan \(z_i\) merupakan nilai hasil scaling, \(x_i\) merupakan nilai pengamatan, \(\bar{x}\) merupakan rata-rata variabel, dan \(s\) merupakan simpangan baku. Metode lain yang dapat digunakan adalah min-max normalization yang mengubah nilai ke dalam rentang tertentu, umumnya 0 sampai 1, dengan persamaan:

\[ x_i' = \frac{x_i-x_{\min}}{x_{\max}-x_{\min}} \]Metode scaling lainnya adalah Robust Scaler, yaitu metode transformasi yang menggunakan median dan Interquartile Range (IQR) sebagai dasar perhitungan. Metode ini menggunakan median sebagai ukuran pemusatan dan IQR sebagai ukuran penyebaran sehingga relatif tidak sensitif terhadap nilai ekstrem (Indini dkk., 2026). Persamaan transformasi Robust Scaler dapat dituliskan sebagai berikut (Izonin dkk., 2022):

\[ x_i^*=\frac{x_i-\operatorname{Median}(X)}{IQR(X)} \]

dengan \(x_i^*\) merupakan nilai hasil transformasi, \(x_i\) merupakan nilai pengamatan, dan \({Median}(X)\) merupakan median variabel, serta IQR merupakan selisih antara kuartil ketiga dan kuartil pertama.

Penerapan scaling terutama penting pada algoritma yang menggunakan perhitungan jarak karena perbedaan skala dapat menyebabkan fitur tertentu lebih dominan dibandingkan fitur lainnya. Teknik transformasi seperti normalisasi juga merupakan salah satu bentuk pengolahan fitur yang dapat memengaruhi hasil pemodelan prediktif (Santoso dan Priyadi, 2024).

Gambar 1. Perbandingan metode *scaling*

Gambar 1. Perbandingan metode scaling

6. Encoding

Feature encoding adalah proses mengubah fitur kategoris atau non-numerik menjadi format numerik yang dapat digunakan sebagai input untuk algoritma machine learning membutuhkan input numerik. Ada beberapa teknik umum untuk feature encoding, seperti One-Hot Encoding dan Ordinal Encoding.

Gambar 2. Contoh proses *encoding*

Gambar 2. Contoh proses encoding

7. Imbalanced Dataset

Imbalanced dataset merupakan kondisi ketika jumlah observasi pada setiap kelas dalam variabel target tidak seimbang sehingga terdapat kelas mayoritas dan kelas minoritas. Ketidakseimbangan tersebut dapat menyebabkan model lebih cenderung memprediksi kelas mayoritas dan kurang mampu mengenali kelas minoritas. Evaluasi model pada kondisi tersebut tidak cukup hanya menggunakan akurasi, tetapi dapat mempertimbangkan precision, recall, F1-score, dan matriks konfusi. Penanganan imbalanced dataset dapat dilakukan melalui oversampling untuk meningkatkan jumlah observasi kelas minoritas, undersampling untuk mengurangi jumlah observasi kelas mayoritas, maupun kombinasi keduanya. Indrawati (2021) menunjukkan bahwa teknik oversampling dan undersampling dapat digunakan untuk menangani ketidakseimbangan kelas pada data sebelum digunakan dalam pemodelan machine learning.

Salah satu metode oversampling untuk menangani ketidakseimbangan kelas adalah Synthetic Minority Over-sampling Technique (SMOTE). Metode ini membentuk observasi sintetis untuk kelas minoritas dengan memanfaatkan observasi minoritas dan tetangga terdekatnya. SMOTE telah diterapkan pada analisis klasifikasi data kemiskinan di Indonesia sebagai salah satu pendekatan untuk menangani ketidakseimbangan kelas (Pratama dan Oktora, 2023).

Pembentukan observasi sintetis dapat dinyatakan dengan persamaan berikut:

\[ x_{\text{baru}}=x_i+\lambda(x_{nn}-x_i) \]dengan \(x_{baru}\) merupakan observasi sintetis, \(x_i\) merupakan observasi kelas minoritas yang dipilih, \(x_{nn}\) merupakan salah satu tetangga terdekat dari observasi tersebut, dan \(\lambda\) merupakan bilangan acak dalam rentang 0 sampai 1. Nilai \(\lambda\) menentukan posisi observasi sintetis di antara kedua observasi tersebut.

BAB III METODE PENELITIAN

3.1 Sumber Data

Jenis data yang digunakan dalam penelitian ini berupa data kuantitatif. Data kuantitatif adalah jenis data yang berbentuk angka atau berskala numerik yang dapat dihitung secara langsung. Sumber data yang digunakan ialah data sekunder. Data sekunder adalah data yang diperoleh secara tidak langsung melalui perantara. Dalam penelitian ini data yang digunakan adalah data curah hujan yang diberikan dari Asisten Praktikum.

3.2 Variabel Penelitian

Pada penelitian ini terdapat 5 variabel yang digunakan. Variabel tersebut yaitu hujan, suhu, kelembapan, keadaan cuaca dan kecepatan angin dengan jumlah observasi sebanyak 743 observasi.

3.3 Langkah-langkah Analisis

  1. Mengimpor dataset.
  2. Melakukan pemeriksaan struktur data untuk mengetahui jumlah observasi, variabel, dan tipe data yang digunakan.
  3. Melakukan pemeriksaan missing value pada setiap variabel.
  4. Melakukan handling missing value pada variabel Kecepatan_Angin menggunakan metode mean imputation.
  5. Melakukan handling missing value pada variabel Keadaan_Cuaca menggunakan metode interpolasi.
  6. Melakukan pemeriksaan kembali untuk memastikan missing value telah ditangani.
  7. Melakukan pemeriksaan kardinalitas pada variabel Keadaan_Cuaca.
  8. Mengurangi kardinalitas variabel Keadaan_Cuaca dengan mengelompokkan nilai ke dalam beberapa kategori.
  9. Melakukan splitting data menjadi data training dan data testing dengan proporsi 80% data training dan 20% data testing.
  10. Melakukan identifikasi outlier pada variabel Suhu, Kelembapan, dan Kecepatan_Angin menggunakan metode Interquartile Range (IQR).
  11. Melakukan handling outlier menggunakan metode capping berdasarkan batas bawah dan batas atas yang diperoleh dari data training.
  12. Melakukan scaling pada variabel Suhu, Kelembapan, dan Kecepatan_Angin menggunakan metode robust scaling.
  13. Melakukan encoding pada variabel Keadaan_Cuaca yang telah dikelompokkan menggunakan metode one-ho encoding.
  14. Melakukan pemeriksaan distribusi kelas pada variabel Hujan untuk mengetahui apakah data mengalami ketidakseimbangan kelas atau imbalanced dataset.
  15. Melakukan penanganan imbalanced dataset pada data training menggunakan metode SMOTE (Synthetic Minority Over-sampling Technique).
  16. Melakukan pemeriksaan kembali terhadap data setelah seluruh tahapan feature engineering selesai dilakukan.
  17. Menampilkan hasil akhir pengolahan data yang selanjutnya dapat digunakan dalam proses pemodelan machine learning.

BAB IV HASIL DAN PEMBAHASAN

4.1 Library dan Statistik Deskriptif

Sebelum melakukan analisis lebih lanjut, tahap pertama yang dilakukan adalah mengaktifkan package atau library yang diperlukan untuk membantu proses analisis pada RStudiO. Selanjutnya, melaukuan proses import. Kemudian dilakukan pemeriksaan awal terhadap struktur dan karakteristik dataset.

Sintaks yang digunakan adalah sebagai berikut:

library(zoo)
library(readxl)
library(tidyverse)
library(rsample)
library(e1071)
library(ggplot2)
library(gridExtra)
library(recipes)
library(themis)
library(dplyr)
setwd("C:/Users/elyas/Downloads")
data <- read_excel("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 ...
summary(data)
##      Hujan            Suhu         Kelembapan     Keadaan_Cuaca  
##  Min.   :1.000   Min.   :22.60   Min.   : 52.00   Min.   : 1.00  
##  1st Qu.:2.000   1st Qu.:24.30   1st Qu.: 75.00   1st Qu.: 2.00  
##  Median :2.000   Median :26.00   Median : 86.00   Median : 2.00  
##  Mean   :1.779   Mean   :26.54   Mean   : 83.88   Mean   :15.11  
##  3rd Qu.:2.000   3rd Qu.:28.90   3rd Qu.: 94.00   3rd Qu.:15.00  
##  Max.   :2.000   Max.   :32.00   Max.   :100.00   Max.   :97.00  
##                                                   NAs    :9      
##  Kecepatan_Angin 
##  Min.   : 2.000  
##  1st Qu.: 4.000  
##  Median : 6.000  
##  Mean   : 6.655  
##  3rd Qu.: 9.000  
##  Max.   :21.000  
##  NAs    :314

Statistik deskriptif merupakan langkah awal untuk memahami karakteristik dataset sebelum dilakukan data preprocessing. Tahap ini menyajikan ringkasan data melalui beberapa ukuran, seperti nilai minimum, kuartil pertama (Q1), median, mean, kuartil ketiga (Q3), maksimum, serta jumlah missing value.

Nilai minimum dan maksimum menunjukkan batas terendah dan tertinggi suatu variabel. Mean menggambarkan nilai rata-rata, sedangkan median merupakan nilai tengah dari data yang telah diurutkan. Q1 menunjukkan batas 25% data terbawah, sementara Q3 menunjukkan batas 75% data. Kedua kuartil tersebut digunakan untuk menghitung Interquartile Range (IQR), yang dapat membantu mengidentifikasi outlier. Sementara itu, pemeriksaan missing value bertujuan mengetahui keberadaan data yang hilang dan perlu ditangani.

Oleh karena itu, statistik deskriptif berperan dalam memberikan gambaran umum sekaligus membantu menentukan langkah data preprocessing yang diperlukan. Hasil analisis dapat menunjukkan adanya data hilang, outlier, perbedaan skala antarvariabel, kategori yang perlu disesuaikan, maupun ketidakseimbangan kelas. Temuan tersebut menjadi pertimbangan dalam memilih teknik preprocessing yang tepat sebelum data digunakan untuk pemodelan.

Berdasarkan hasil summary(data), diperoleh statistik deskriptif sebagai berikut.

Variabel Min Q1 Median Mean Q3 Max Missing Value
Hujan 1,00 2,00 2,00 1,779 2,00 2,00 0
Suhu 22,60 24,30 26,00 26,54 28,90 32,00 0
Kelembapan 52,00 75,00 86,00 83,88 94,00 100,00 0
Keadaan_Cuaca 1,00 2,00 2,00 15,11 15,00 97,00 9
Kecepatan_Angin 2,00 4,00 6,00 6,655 9,00 21,00 314

Berdasarkan hasil tersebut, dataset terdiri atas 743 observasi dan lima variabel, yaitu Hujan, Suhu, Kelembapan, Keadaan_Cuaca, dan Kecepatan_Angin. Variabel Hujan memiliki nilai minimum 1 dan maksimum 2 sehingga menunjukkan bahwa variabel tersebut terdiri atas dua kelas. Variabel Suhu memiliki nilai antara 22,60 hingga 32,00 dengan rata-rata 26,54. Variabel Kelembapan memiliki nilai antara 52,00 hingga 100,00 dengan rata-rata 83,88. Sementara itu, Keadaan_Cuaca memiliki nilai minimum 1 dan maksimum 97 dengan rata-rata 15,11 serta terdapat 9 missing value. Variabel Kecepatan_Angin memiliki nilai minimum 2,00 dan maksimum 21,00 dengan rata-rata 6,655 serta memiliki 314 missing value.

Hasil tersebut menunjukkan bahwa dataset memerlukan beberapa tahapan data preprocessing. Adanya missing value pada Keadaan_Cuaca dan Kecepatan_Angin menunjukkan perlunya dilakukan handling missing value. Rentang nilai pada variabel numerik perlu diperiksa untuk mengetahui keberadaan outlier, sehingga dilakukan handling outlier. Selanjutnya, perbedaan skala variabel numerik menjadi pertimbangan untuk melakukan scaling. Variabel Keadaan_Cuaca perlu diperiksa kardinalitasnya dan diubah ke bentuk numerik melalui encoding. Selain itu, distribusi kelas pada Hujan perlu diperiksa untuk mengetahui apakah terdapat imbalanced dataset. Oleh karena itu, statistik deskriptif menjadi dasar untuk menentukan tahapan data preprocessing yang dilakukan pada bagian selanjutnya.

4.2 Handling Missing Value

Missing value adalah kondisi ketika suatu variabel memiliki data yang kosong atau tidak bernilai. Berdasarkan hasil statistik deskriptif, variabel Hujan, Suhu, dan Kelembapan tidak memiliki missing value. Namun, terdapat 9 data kosong pada Keadaan_Cuaca dan 314 data kosong pada Kecepatan_Angin. Sesuai ketentuan praktikum untuk NPM ganjil, missing value pada Kecepatan_Angin ditangani menggunakan metode mean imputation, sedangkan data kosong pada Keadaan_Cuaca diatasi menggunakan metode interpolasi.

Sintaks yang digunakan adalah sebagai berikut:

# 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
data %>% filter(if_any(everything(), is.na)) 
## # A tibble: 319 × 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  25           89             2              NA
##  5     1  24.6         90             2              NA
##  6     2  24.2         90             2              NA
##  7     2  23.9         90             2              NA
##  8     2  23.7         91             2              NA
##  9     2  23.5         92             2              NA
## 10     2  23.3         92             2              NA
## # ℹ 309 more rows
# Mean Imputation (Kecepatan_Angin)
df_imp <- data

df_imp$Kecepatan_Angin[is.na(df_imp$Kecepatan_Angin)] <- mean(
  df_imp$Kecepatan_Angin,
  na.rm = TRUE
)

colSums(is.na(df_imp))
##           Hujan            Suhu      Kelembapan   Keadaan_Cuaca Kecepatan_Angin 
##               0               0               0               9               0
# Interpolasi (Keadaan_Cuaca)
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               0

Hasil pemeriksaan awal menunjukkan bahwa terdapat 9 missing value pada Keadaan_Cuaca dan 314 missing value pada Kecepatan_Angin. Selain itu, terdapat 319 observasi yang memiliki setidaknya satu missing value. Proporsi missing value pada Keadaan_Cuaca sebesar 0,0121 atau sekitar 1,21%, sedangkan pada Kecepatan_Angin sebesar 0,4226 atau sekitar 42,26%. Selanjutnya, dilakukan mean imputation pada Kecepatan_Angin. Setelah proses tersebut dilakukan, seluruh missing value pada Kecepatan_Angin berhasil ditangani. Untuk Keadaan_Cuaca, dilakukan interpolasi. Interpolasi digunakan untuk memperkirakan nilai yang hilang berdasarkan nilai pengamatan yang tersedia di sekitarnya. Setelah dilakukan mean imputation dan interpolasi, hasil menunjukkan bahwa seluruh variabel sudah tidak memiliki missing value. Dengan demikian, permasalahan data hilang telah berhasil ditangani.

4.3 Kardinalitas

Kardinalitas menunjukkan jumlah nilai unik yang terdapat pada suatu variabel. Pemeriksaan kardinalitas dilakukan pada variabel Keadaan_Cuaca untuk mengetahui banyaknya nilai berbeda sebelum dilakukan pengelompokan.

Sintaks yang digunakan adalah sebagai berikut:

## Reduksi Kardinalitas

# Melihat 10 data pertama
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            6.66
##  2     1  24           90             1            6.66
##  3     1  26.8         77             1            6.66
##  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
# Melihat kategori unik variabel asli
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
# Menentukan interval dan label kategori baru
bins <- c(0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100)
labels <- 0:9

# Melakukan reduksi kardinalitas
df_imp$Keadaan_Cuaca_reduced <- cut(
  df_imp$Keadaan_Cuaca,
  breaks = bins,
  labels = labels,
  right = TRUE,
  include.lowest = TRUE
)

# Membandingkan data asli dan hasil reduksi
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  31.1         64             3           10    0                    
##  2     2  25.3         80             2            6.66 0                    
##  3     2  31.6         60             2           10    0                    
##  4     1  27.9         83             2            3    0                    
##  5     2  26.7         83             1            7    0                    
##  6     2  29.8         69             2            3    0                    
##  7     1  23.2         97            61            4    6                    
##  8     2  23.1         92             2            6.66 0                    
##  9     2  23.6         96            61            6.66 6                    
## 10     1  26           90             2            3    0
# Memeriksa kardinalitas
cat("\n--- Pengecekan Kardinalitas ---\n")
## 
## --- Pengecekan Kardinalitas ---
cat("Jumlah kategori unik asli:",
    length(unique(na.omit(df_imp$Keadaan_Cuaca))),"\n")
## Jumlah kategori unik asli: 23
cat("Jumlah kategori teramati setelah reduksi:",
    length(unique(na.omit(df_imp$Keadaan_Cuaca_reduced))),"\n")
## Jumlah kategori teramati setelah reduksi: 7
cat( "Jumlah level faktor setelah reduksi:",
     nlevels(df_imp$Keadaan_Cuaca_reduced),"\n")
## Jumlah level faktor setelah reduksi: 10
# Menampilkan kategori unik secara berurutan
cat("\nKategori unik yang baru (reduced):\n")
## 
## Kategori unik yang baru (reduced):
print(sort(unique(na.omit(df_imp$Keadaan_Cuaca_reduced))))
## [1] 0 1 2 4 5 6 9
## Levels: 0 1 2 3 4 5 6 7 8 9
# Menampilkan frekuensi setiap kategori
cat("\nTabel frekuensi kategori hasil reduksi:\n")
## 
## Tabel frekuensi kategori hasil reduksi:
print(table(df_imp$Keadaan_Cuaca_reduced, useNA = "ifany"))
## 
##   0   1   2   3   4   5   6   7   8   9 
## 523  48  46   0   1  28  71   0   0  26

Hasil pemeriksaan menunjukkan bahwa variabel Keadaan_Cuaca memiliki 23 nilai unik. Selanjutnya, nilai tersebut dikelompokkan menjadi interval 0–10, 10–20, dan seterusnya hingga 90–100. Setelah dilakukan pengelompokan, terbentuk 7 kategori yang memiliki observasi. Berdasarkan hasil table(), kategori 0 memiliki 523 observasi, kategori 1 sebanyak 48 observasi, kategori 2 sebanyak 46 observasi, kategori 4 sebanyak 1 observasi, kategori 5 sebanyak 28 observasi, kategori 6 sebanyak 71 observasi, dan kategori 9 sebanyak 26 observasi. Sementara itu, kategori 3, 7, dan 8 tidak memiliki observasi. Pengelompokan tersebut dilakukan untuk menyederhanakan representasi nilai Keadaan_Cuaca sehingga variabel lebih mudah digunakan pada tahap encoding.

4.4 Splitting Data

Splitting data merupakan proses membagi dataset menjadi data training dan data testing. Data training digunakan untuk proses pembelajaran model, sedangkan data testing digunakan untuk mengevaluasi kemampuan model pada data yang tidak digunakan selama proses pembelajaran.Sesuai dengan ketentuan praktikum untuk NPM ganjil, metode yang digunakan adalah shuffle splitting. Data dibagi dengan proporsi 80% untuk data training dan 20% untuk data testing.

Sintaks yang digunakan adalah sebagai berikut:

## Splitting Data (Shuffle)
set.seed(200)

split_shuffle <- initial_split(
  df_imp,
  prop = 0.8
)

X_train <- training(split_shuffle) %>%
  dplyr::select(-Hujan)

X_test <- testing(split_shuffle) %>%
  dplyr::select(-Hujan)

y_train <- training(split_shuffle)$Hujan
y_test <- testing(split_shuffle)$Hujan

dim(X_train)
## [1] 594   5
dim(X_test)
## [1] 149   5

Hasil pembagian menunjukkan bahwa data training terdiri atas 594 observasi dengan 5 variabel prediktor, sedangkan data testing terdiri atas 149 observasi dengan 5 variabel prediktor.

Variabel Hujan dipisahkan dari variabel prediktor dan disimpan sebagai y_train dan y_test. Variabel selain Hujan digunakan sebagai prediktor dan disimpan dalam X_train dan X_test.

4.5 Handling Outlier

Outlier merupakan nilai yang memiliki jarak relatif jauh dari sebagian besar data. Keberadaan outlier perlu diperiksa karena nilai ekstrem dapat memengaruhi hasil analisis dan proses pemodelan.

Identifikasi outlier dilakukan pada variabel numerik, yaitu Suhu, Kelembapan, dan Kecepatan_Angin. Metode yang digunakan adalah Interquartile Range (IQR).

## Handling Outlier
list_num <- c(
  "Suhu",
  "Kelembapan",
  "Kecepatan_Angin"
)

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)
  
  total_outliers <- sum(
    X_train[[i]] < lower_bound,
    na.rm = TRUE
  ) +
    sum(
      X_train[[i]] > upper_bound,
      na.rm = TRUE
    )
  
  list_outlier <- c(list_outlier, total_outliers)
}

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.4        35.8
## 2      Kelembapan              0        46.5       122.5
## 3 Kecepatan_Angin             50         2.0        10.0

Batas outlier ditentukan berdasarkan:

\[ IQR=Q3-Q1 \] \[ Batas\;Bawah=Q1-1,5(IQR) \] \[ Batas\;Atas=Q3+1,5(IQR) \] Berdasarkan hasil identifikasi, variabel Suhu memiliki 0 outlier dengan batas bawah 17,4 dan batas atas 35,8. Variabel Kelembapan juga memiliki 0 outlier, dengan batas bawah 46,5 dan batas atas 122,5. Sementara itu, Kecepatan_Angin memiliki 50 outlier, dengan batas bawah 2 dan batas atas 10.

Selanjutnya dilakukan capping pada variabel numerik menggunakan batas yang diperoleh dari data training. Nilai yang berada di bawah batas bawah disesuaikan menjadi batas bawah, sedangkan nilai yang berada di atas batas atas disesuaikan menjadi batas atas.

## Capping pada variabel numerik terpilih
X_train_capped <- X_train
X_test_capped <- X_test

for (k in seq_along(list_num)) {
  col <- list_num[k]
  
  X_train_capped[[col]] <- pmin(
    pmax(X_train[[col]], list_lower_bound[k]),
    list_upper_bound[k]
  )
  
  X_test_capped[[col]] <- pmin(
    pmax(X_test[[col]], list_lower_bound[k]),
    list_upper_bound[k]
  )
}

summary(X_train[list_num])
##       Suhu         Kelembapan  Kecepatan_Angin 
##  Min.   :22.60   Min.   : 52   Min.   : 2.000  
##  1st Qu.:24.30   1st Qu.: 75   1st Qu.: 5.000  
##  Median :26.00   Median : 86   Median : 6.655  
##  Mean   :26.54   Mean   : 84   Mean   : 6.642  
##  3rd Qu.:28.90   3rd Qu.: 94   3rd Qu.: 7.000  
##  Max.   :31.60   Max.   :100   Max.   :21.000
summary(X_train_capped[list_num])
##       Suhu         Kelembapan  Kecepatan_Angin 
##  Min.   :22.60   Min.   : 52   Min.   : 2.000  
##  1st Qu.:24.30   1st Qu.: 75   1st Qu.: 5.000  
##  Median :26.00   Median : 86   Median : 6.655  
##  Mean   :26.54   Mean   : 84   Mean   : 6.447  
##  3rd Qu.:28.90   3rd Qu.: 94   3rd Qu.: 7.000  
##  Max.   :31.60   Max.   :100   Max.   :10.000

Hasil perbandingan sebelum dan sesudah capping menunjukkan bahwa nilai maksimum Kecepatan_Angin berubah dari 21 menjadi 10. Rata-rata Kecepatan_Angin juga berubah dari 6,642 menjadi 6,447. Sementara itu, Suhu dan Kelembapan tidak mengalami perubahan karena tidak memiliki outlier berdasarkan batas IQR. Untuk melihat perubahan distribusi data secara visual, digunakan histogram dan boxplot sebelum dan sesudah dilakukan capping.

diagnostic_plots <- function(df, variable) {
  p1 <- ggplot(df, aes(x = .data[[variable]])) +
    geom_histogram(
      bins = 30,
      fill = "#008080",
      color = "pink2"
    ) +
    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)
}

for (col in list_num) {
  cat(col, "- Before Capping\n")
  diagnostic_plots(X_train, col)
  
  cat(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

Hasil visualisasi menunjukkan bahwa perubahan paling terlihat pada variabel Kecepatan_Angin. Setelah dilakukan capping, nilai-nilai yang sebelumnya berada di atas batas atas sebesar 10 dibatasi menjadi 10. Dengan demikian, nilai ekstrem dapat dikendalikan tanpa menghapus observasi dari dataset.

4.6 Scaling Data

Scaling merupakan proses mengubah skala variabel numerik agar perbedaan rentang antarvariabel dapat dikurangi. Sesuai dengan ketentuan praktikum untuk NPM ganjil, metode scaling yang digunakan adalah Robust Scaler. Robust Scaler menggunakan median dan IQR sehingga lebih tahan terhadap pengaruh nilai ekstrem. Rumus transformasi yang digunakan adalah:

\[ X^*=\frac{X-\text{Median}(X)}{IQR(X)} \]

Sintaks yang digunakan adalah sebagai berikut:

## Scaling (Robust Scaler)
median_val <- sapply(
  X_train_capped[list_num],
  median,
  na.rm = TRUE
)

iqr_val <- sapply(
  X_train_capped[list_num],
  IQR,
  na.rm = TRUE
)

X_train_scale <- X_train_capped
X_test_scale <- X_test_capped

for (col in list_num) {
  X_train_scale[[col]] <-
    (X_train_capped[[col]] - median_val[col]) /
    iqr_val[col]
  
  X_test_scale[[col]] <-
    (X_test_capped[[col]] - median_val[col]) /
    iqr_val[col]
}

summary(X_train_scale[list_num])
##       Suhu           Kelembapan      Kecepatan_Angin  
##  Min.   :-0.7391   Min.   :-1.7895   Min.   :-2.3275  
##  1st Qu.:-0.3696   1st Qu.:-0.5789   1st Qu.:-0.8275  
##  Median : 0.0000   Median : 0.0000   Median : 0.0000  
##  Mean   : 0.1177   Mean   :-0.1053   Mean   :-0.1041  
##  3rd Qu.: 0.6304   3rd Qu.: 0.4211   3rd Qu.: 0.1725  
##  Max.   : 1.2174   Max.   : 0.7368   Max.   : 1.6725

Median dan IQR dihitung berdasarkan data training. Nilai tersebut kemudian digunakan untuk melakukan transformasi terhadap data training dan data testing. Pendekatan tersebut dilakukan agar parameter transformasi tidak diperoleh dari data testing. Berdasarkan hasil transformasi, median ketiga variabel numerik menjadi 0. Variabel Suhu memiliki nilai minimum -0,7391 dan maksimum 1,2174. Variabel Kelembapan memiliki nilai minimum -1,7895 dan maksimum 0,7368. Sementara itu, Kecepatan_Angin memiliki nilai minimum -2,3275 dan maksimum 1,6725. Hasil tersebut menunjukkan bahwa ketiga variabel numerik telah ditransformasikan ke skala yang relatif sebanding dengan menggunakan median dan IQR sebagai dasar transformasi.

4.7 Encoding

Encoding merupakan proses mengubah variabel kategorik menjadi bentuk numerik sehingga dapat digunakan oleh algoritma machine learning. Pada tahap ini digunakan metode one-hot encoding terhadap variabel Keadaan_Cuaca_reduced.

Sintaks yang digunakan adalah sebagai berikut:

## Encoding (One Hot)
resep_encode <- recipe(
  ~ Keadaan_Cuaca_reduced,
  data = X_train_scale
) %>%
  step_dummy(
    Keadaan_Cuaca_reduced,
    one_hot = TRUE
  ) %>%
  prep(training = X_train_scale)

X_train_encoded <- bake(
  resep_encode,
  new_data = NULL
)

X_test_encoded <- bake(
  resep_encode,
  new_data = X_test_scale
)

# Gabungkan fitur numerik + hasil one-hot
X_train_final <- bind_cols(
  X_train_scale[, list_num],
  X_train_encoded
)

X_test_final <- bind_cols(
  X_test_scale[, list_num],
  X_test_encoded
)

head(X_train_final)
## # A tibble: 6 × 13
##      Suhu Kelembapan Kecepatan_Angin Keadaan_Cuaca_reduced_X0
##     <dbl>      <dbl>           <dbl>                    <dbl>
## 1 -0.500       0.579           0                            0
## 2  1.09       -0.947           1.67                         1
## 3  0.0870     -0.263          -0.828                        1
## 4  1.15       -1.53            1.17                         1
## 5  0.674      -0.421           0                            1
## 6  0.391      -0.368          -1.83                         1
## # ℹ 9 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>
dim(X_train_final)
## [1] 594  13

Hasil encoding menghasilkan 10 kolom indikator, yaitu Keadaan_Cuaca_reduced_X0 sampai Keadaan_Cuaca_reduced_X9. Meskipun hanya terdapat 7 kategori yang memiliki observasi, seluruh 10 level tetap direpresentasikan karena faktor Keadaan_Cuaca_reduced memiliki level 0 sampai 9. Selanjutnya, variabel hasil encoding digabungkan dengan tiga variabel numerik yang telah melalui Robust Scaler, yaitu Suhu, Kelembapan, dan Kecepatan_Angin. Berdasarkan hasil, diperoleh 594 observasi dan 13 variabel prediktor. Dengan demikian, data training telah memiliki bentuk numerik yang dapat digunakan pada tahap berikutnya.

4.8 Handling Imbalanced Dataset dengan SMOTE

Imbalanced dataset merupakan kondisi ketika jumlah observasi pada setiap kelas tidak seimbang. Pemeriksaan distribusi kelas dilakukan pada variabel target Hujan setelah data training melalui tahapan preprocessing sebelumnya.

Sintaks untuk melihat distribusi kelas adalah sebagai berikut:

## Balancing Data (SMOTE)
table(y_train)
## y_train
##   1   2 
## 128 466

Hasil pemeriksaan menunjukkan bahwa kelas 1 memiliki 128 observasi, sedangkan kelas 2 memiliki 466 observasi. Perbedaan jumlah tersebut menunjukkan bahwa data training mengalami ketidakseimbangan kelas. Kelas 1 merupakan kelas minoritas, sedangkan kelas 2 merupakan kelas mayoritas.

Ketidakseimbangan kelas dapat menyebabkan model lebih cenderung mempelajari kelas mayoritas. Oleh karena itu, sesuai dengan ketentuan praktikum dilakukan penanganan imbalanced dataset menggunakan SMOTE (Synthetic Minority Over-sampling Technique).

Sintaks yang digunakan adalah sebagai berikut:

train_full <- X_train_final %>%
  mutate(Hujan = factor(y_train))

set.seed(42)

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
)

X_train_balanced <- train_balanced %>%
  dplyr::select(-Hujan)

y_train_balanced <- train_balanced$Hujan

table(y_train_balanced)
## y_train_balanced
##   1   2 
## 466 466
dim(train_balanced)
## [1] 932  14

Hasil setelah SMOTE menunjukkan bahwa kelas 1 meningkat dari 128 menjadi 466 observasi, sedangkan kelas 2 tetap sebanyak 466 observasi.

Kelas Hujan Sebelum SMOTE Sesudah SMOTE
1 128 466
2 466 466
Total 594 932

Dengan demikian, jumlah data training setelah proses SMOTE menjadi 932 observasi dengan distribusi kelas yang seimbang. Data tersebut terdiri atas 13 variabel prediktor dan satu variabel target Hujan.

Proses SMOTE diterapkan hanya pada data training. Data testing tidak diseimbangkan menggunakan SMOTE sehingga tetap merepresentasikan kondisi data yang sebenarnya dan dapat digunakan untuk mengevaluasi performa model secara lebih objektif.

Secara keseluruhan, tahapan data preprocessing pada dataset dilakukan berdasarkan kondisi yang ditemukan melalui pemeriksaan awal dan statistik deskriptif. Tahapan tersebut meliputi mean imputation, interpolasi, reduksi kardinalitas, shuffle splitting, handling outlier menggunakan capping, Robust Scaling, one-hot encoding, dan SMOTE. Hasil akhir menunjukkan bahwa data training telah memiliki prediktor dalam bentuk numerik, nilai hilang telah ditangani, nilai ekstrem telah dikendalikan, skala numerik telah ditransformasi, dan distribusi kelas telah diseimbangkan sehingga data siap digunakan untuk tahap pemodelan.

BAB V KESIMPULAN

5.1 Kesimpulan

Feature engineering menggunakan RStudio merupakan tahapan pengolahan data yang bertujuan meningkatkan kualitas data sebelum diterapkan dalam pemodelan machine learning. Teknik yang digunakan dalam praktikum mencakup penanganan missing value melalui mean imputation dan interpolasi, reduksi kardinalitas, data splitting, penanganan outlier dengan capping, scaling, encoding, serta penyeimbangan kelas menggunakan SMOTE. Setiap teknik diterapkan sesuai dengan permasalahan data agar data lebih siap untuk dianalisis dan dimodelkan.

Penerapan feature engineering dilakukan secara bertahap, mulai dari pemeriksaan dataset hingga penanganan ketidakseimbangan kelas. Pada praktikum dengan NPM ganjil, teknik yang digunakan meliputi mean imputation, interpolasi pada variabel Keadaan_Cuaca, shuffle splitting, Robust Scaler, capping pada variabel numerik, one-hot encoding, dan SMOTE pada data latih. Seluruh proses dilakukan dengan memanfaatkan fungsi dan paket yang tersedia di RStudio.

Hasil pengolahan menunjukkan bahwa seluruh missing value berhasil ditangani. Kardinalitas Keadaan_Cuaca berkurang dari 23 nilai unik menjadi 10 kategori, dengan 7 kategori yang memiliki observasi. Pembagian data menghasilkan 594 observasi untuk data latih dan 149 observasi untuk data uji. Selain itu, ditemukan 50 outlier pada Kecepatan_Angin yang ditangani menggunakan capping dengan batas atas 10. Proses Robust Scaling diterapkan pada variabel numerik, sedangkan one-hot encoding menghasilkan 13 variabel prediktor. Penanganan ketidakseimbangan kelas menggunakan SMOTE meningkatkan jumlah kelas 1 dari 128 menjadi 466 observasi, sementara kelas 2 tetap berjumlah 466 observasi. Dengan demikian, data latih setelah SMOTE berjumlah 932 observasi dengan distribusi kelas yang seimbang.

DAFTAR PUSTAKA

Darmawan, A., Putra, R., dan Lestari, D. (2023). Analisis Pengaruh Feature Engineering terhadap Performa Model Machine Learning. Jurnal Teknologi Informasi Indonesia, 8(2), 120–128.

Fauzi, M., Rahman, A., dan Hidayat, T. (2022). Peningkatan Akurasi Klasifikasi Menggunakan Teknik Feature Engineering. Jurnal Informatika, 9(1), 45–53.

Fransiska, H. (2026). Modul Praktikum Machine Learning and Modern Prediction. Laboratorium Matematika Universitas Bengkulu.

Indini, D. P., Ariza, S., & Sitorus, Z. (2026). Optimasi algoritma K-Means terhadap data outlier menggunakan robust dalam segmentasi pelanggan Biznet Medan. Journal of Science and Social Research, 9(3), 4505–4515. https://doi.org/10.54314/jssr.v9i3.6568

Indrawati, A. (2021). Penerapan teknik kombinasi oversampling dan undersampling untuk mengatasi permasalahan imbalanced dataset. JIKO (Jurnal Informatika dan Komputer), 4(1), 38–43. https://doi.org/10.33387/jiko.v4i1.2561

Izonin, I., Tkachenko, R., Shakhovska, N., Ilchyshyn, B., & Singh, K. K. (2022). A two-step data normalization approach for improving classification accuracy in the medical diagnosis domain. Mathematics, 10(11), 1942. https://doi.org/10.3390/math10111942

Pratama, F. R. A., & Oktora, S. I. (2023). Synthetic minority over-sampling technique (SMOTE) for handling imbalanced data in poverty classification. Statistical Journal of the IAOS, 39(1), 233–239. https://doi.org/10.3233/SJI-220080

Santoso, L., & Priyadi. (2024). Comparative study of feature engineering techniques for predictive data analytics. Journal of Technology Informatics and Engineering, 3(2), 417–435. https://doi.org/10.51903/jtie.v3i2.225

Santoso, B., Wibowo, A., dan Hakim, L. (2021). Feature Engineering dalam Meningkatkan Performa Model Klasifikasi. Jurnal Teknologi Informasi, 12(2), 101–110.