BAB I PENDAHULUAN

1.1 Latar Belakang

   Kualitas data menjadi salah satu aspek penting dalam penerapan machine learning karena berpengaruh terhadap kemampuan model dalam mengenali pola dan menghasilkan prediksi. Seiring dengan kemajuan teknologi informasi, data yang dihasilkan semakin beragam dan memiliki dimensi yang semakin tinggi. Kondisi ini menimbulkan tantangan dalam menentukan fitur yang tepat untuk digunakan selama proses pemodelan. Keberadaan fitur yang tidak relevan atau memiliki informasi yang saling tumpang tindih dapat menambah kompleksitas data dan menghambat proses pembelajaran model. Oleh karena itu, pemilihan fitur yang sesuai diperlukan agar model machine learning dapat bekerja secara lebih efektif(Villa-Blanco et al., 2023).
   Tahapan persiapan data sebelum membangun model machine learning mencakup proses feature engineering. Feature engineering merupakan proses pengolahan dan penyesuaian fitur untuk menghasilkan representasi data yang lebih sesuai dengan permasalahan yang dianalisis. Proses ini mencakup transformasi fitur, pembentukan fitur baru (feature construction atau feature synthesis), ekstraksi fitur, serta pemilihan fitur (feature selection). Penerapan feature engineering tidak hanya bertujuan mengurangi jumlah fitur, tetapi juga meningkatkan kualitas representasi data agar informasi yang digunakan dapat mendukung proses pembelajaran model secara lebih efektif (Mumuni & Mumuni, 2025).
   Berdasarkan uraian tersebut, Feature engineering penting dilakukan untuk mempersiapkan fitur agar dapat memberikan informasi yang lebih relevan bagi model machine learning. Melalui proses transformasi, pembentukan, ekstraksi, dan seleksi fitur, data dapat direpresentasikan dengan lebih baik sehingga proses pemodelan dapat dilakukan secara lebih efektif dan efisien. Oleh karena itu, analisis mengenai Feature engineering diperlukan untuk memahami bagaimana pengolahan fitur dapat memengaruhi karakteristik data dan kinerja model machine learning.

1.2 Rumusan Masalah

   1.   Bagaimana cara konsep dari berbagai jenis Feature engineering pada RStudio?
   2.   Bagaimana cara melakukan teknik Feature engineering di program RStudio?

1.3 Tujuan

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

1.4 Batasan Masalah

   Adapun batasan masalah pada penelitian ini adalah gunakan dataset data curah hujan.xlsx untuk melakukan preprocessing data. NPM ganjil menggunakan mean imputation, shuffle Splitting, dan Robust Scaler, sedangkan NPM genap menggunakan mode imputation, stratify Splitting, dan Standard Scaler. Keduanya melakukan interpolasi pada Keadaan_Cuaca, capping pada data numerik, serta penanganan imbalance data menggunakan SMOTE. Tampilkan dan interpretasikan setiap output!

BAB II TINJAUAN PUSTAKA

2.1 Feature Engineering

   Feature engineering merupakan proses mengolah data mentah menjadi fitur yang lebih sesuai dan informatif untuk digunakan dalam pemodelan machine learning. Fitur adalah variabel atau atribut yang digunakan oleh model untuk mempelajari pola dari data. Dalam praktiknya, data mentah sering kali belum berada dalam bentuk yang optimal untuk digunakan secara langsung sehingga diperlukan proses transformasi, pembentukan, ekstraksi, atau pemilihan fitur (Mumuni & Mumuni, 2025). Feature engineering memerlukan pemahaman yang baik karena melibatkan kombinasi analisis data, pengetahuan tentang data, dan sedikit intuisi. Tujuan dari Feature engineering adalah menyederhanakan dan mempercepat transformasi data sekaligus meningkatkan akurasi model (Fransiska, 2026). Berikut merupakan beberapa jenis Feature engineering yang harus dilakukan:

a.Handling Missing Values

 Missing Values merupakan salah satu permasalahan yang umum ditemukan pada data dunia nyata. Keberadaan Missing Values dapat memengaruhi kualitas data dan performa model machine learning sehingga diperlukan metode yang tepat untuk menanganinya (Emmanuel et al., 2021).

b.Kardinalitas

 Kardinalitas (cardinality) pada variabel kategoris mengacu pada jumlah kategori atau nilai unik yang terdapat dalam suatu variabel. Variabel kategoris dengan jumlah kategori yang relatif sedikit disebut memiliki low cardinality, sedangkan variabel dengan jumlah kategori yang banyak disebut memiliki high cardinality. Permasalahan high cardinality menjadi perhatian dalam pemodelan machine learning karena semakin banyak kategori yang dimiliki suatu variabel, semakin besar pula representasi fitur yang diperlukan ketika variabel tersebut dikonversi ke dalam bentuk numerik (Pargent et al., 2022).

c.Splitting Data

 Data Splitting merupakan salah satu tahapan penting dalam pemodelan machine learning yang dilakukan dengan membagi dataset menjadi beberapa bagian, terutama data training dan data testing. Data training digunakan untuk membangun atau melatih model, sedangkan data testing dipisahkan dari proses pelatihan dan digunakan untuk mengevaluasi kemampuan model dalam melakukan prediksi terhadap data yang belum pernah digunakan sebelumnya. Pemisahan tersebut diperlukan agar performa model dapat dievaluasi secara lebih objektif dan kemampuan generalisasi model terhadap data baru dapat diketahui (Bichri et al., 2024).

d.Handling Outlier

 Outlier atau pencilan merupakan observasi dalam suatu dataset yang memiliki karakteristik tidak biasa atau menyimpang dari pola umum yang terdapat pada sebagian besar data. Suatu observasi dapat dikategorikan sebagai Outlier apabila karakteristiknya berbeda secara signifikan dari pola yang dianggap normal. Namun, keberadaan Outlier bersifat kontekstual karena suatu observasi yang dianggap sebagai pencilan pada satu kondisi belum tentu dianggap sebagai pencilan pada kondisi lainnya (Foorthuis, 2021).

e.Scaling data

Scaling data merupakan salah satu tahap preprocessing dalam machine learning yang bertujuan untuk menyetarakan skala nilai antarfitur. Tahapan ini diperlukan karena setiap fitur dapat memiliki rentang nilai dan satuan pengukuran yang berbeda. Perbedaan skala tersebut dapat menyebabkan fitur dengan rentang nilai yang lebih besar memberikan pengaruh yang lebih dominan dalam proses pembelajaran model. Oleh karena itu, Scaling digunakan agar nilai antarfitur berada pada skala yang lebih sebanding sehingga proses pemodelan dapat berlangsung dengan lebih baik (Ahsan et al., 2021).

f.Encoding

 Feature Encoding merupakan salah satu tahap preprocessing dalam machine learning yang digunakan untuk mengubah fitur kategoris atau nonnumerik menjadi bentuk numerik sehingga dapat digunakan sebagai input dalam algoritma machine learning. Hal ini diperlukan karena sebagian besar algoritma machine learning dirancang untuk memproses data dalam bentuk numerik (Pargent et al., 2022).

g.Imbalanced Dataset

 Imbalanced Dataset merupakan kondisi ketika jumlah observasi pada setiap kelas dalam suatu dataset tidak terdistribusi secara seimbang. Kelas dengan jumlah observasi yang lebih banyak disebut sebagai kelas mayoritas, sedangkan kelas dengan jumlah observasi yang lebih sedikit disebut sebagai kelas minoritas. Kondisi ini umum ditemukan pada berbagai permasalahan machine learning, terutama pada data dunia nyata, dan dapat menyebabkan model lebih cenderung mempelajari kelas mayoritas dibandingkan kelas minoritas (Mumuni & Mumuni, 2025).

BAB III METODE PENELITIAN

3.1 Jenis dan Sumber Data

   Jenis data yang digunakan pada penelitian ini yaitu data kuantitatif. Data kuantitatif adalah data penelitian yang berbentuk angka dan data yang dapat dilakukan analisis. Data kuantitatif disebut juga dikenal dengan data numerik. 
   Sumber data yang digunakan dalam penelitian ini merupakan data sekunder. Data sekunder adalah data yang telah dikumpulkan dan diolah sebelumnya oleh pihak lain, bukan oleh peneliti yang sedang melakukan penelitian saat ini. Data sekunder yang digunakan pada penelitian ini adalah curah hujan yang diberikan oleh asisten praktikum.

3.2 Variabel Penelitian

   Variabel merupakan objek penelitian atau hal yang menjadi titik perhatian dalam suatu studi. Variabel yang digunakan dalam praktikum ini terdiri atas hujan, suhu, kelembapan, keadaan cuaca, dan kecepatan angin. Variabel hujan, suhu, kelembapan, dan kecepatan angin merupakan variabel numerik, sedangkan keadaan cuaca merupakan variabel kategorik. kelima variabel tersebut digunakan dalam proses preprocessing data untuk mempersiapkan data sebelum dilakukan analisis selanjutnya.

3.3 Analisis Data

   Berikut adalah algoritma untuk menyelesaiankan batasan masalah:
   1.Mulai.
   2.Menghitung distribusi kelas pada variabel target y_train.
   3.Menggabungkan data prediktor hasil encoding dengan variabel target Hujan.
   4.Mengubah variabel target Hujan menjadi tipe factor agar dapat digunakan dalam proses SMOTE.
   5.Menentukan seed untuk menjaga hasil proses tetap konsisten.
   6.Membuat recipe SMOTE dengan variabel Hujan sebagai target.
   7.Menentukan over_ratio = 1 dan jumlah tetangga (neighbors) sebanyak 5.
   8.Melakukan prep() berdasarkan data training.
   9.Menerapkan SMOTE menggunakan bake() untuk menghasilkan data training yang lebih seimbang.
  10.Menghasilkan train_balanced sebagai dataset hasil penanganan imbalanced dataset.
  11.Selesai.

BAB IV HASIL DAN PEMBAHASAN

4.1 Library

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.3     ✔ 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
# Import Data
data <- read_excel("D:/LAPRAK ML/data curah hujan.xlsx")
View(data)
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 ...

Intepretasi Hasil 4.1

Berdasarkan output head(data) dan str(data), dataset terdiri atas 743 observasi dan 5 variabel, yaitu Hujan, Suhu, Kelembapan, Keadaan_Cuaca, dan Kecepatan_Angin. Variabel Hujan, Suhu, Kelembapan, dan Kecepatan_Angin merupakan variabel numerik, sedangkan Keadaan_Cuaca merupakan variabel kategorik. Hal ini menunjukkan bahwa data memiliki kombinasi variabel numerik dan kategorik yang perlu diproses sebelum digunakan dalam pemodelan.

4.2 Handling Missing Value

# Jumlah missing value setiap variabel
colSums(is.na(data))
##           Hujan            Suhu      Kelembapan   Keadaan_Cuaca Kecepatan_Angin 
##               0               0               0               9             314
# Persentase missing value setiap variabel
colMeans(is.na(data))
##           Hujan            Suhu      Kelembapan   Keadaan_Cuaca Kecepatan_Angin 
##      0.00000000      0.00000000      0.00000000      0.01211306      0.42261104
# Melihat baris yang memiliki missing value
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
#Interpolasi
df_imp <- data

df_imp$Keadaan_Cuaca <- na.approx(
  df_imp$Keadaan_Cuaca,
  na.rm = FALSE
)

# Melihat jumlah missing setelah interpolasi
colSums(is.na(df_imp))
##           Hujan            Suhu      Kelembapan   Keadaan_Cuaca Kecepatan_Angin 
##               0               0               0               0             314
# Menghitung nilai mean Kecepatan_Angin
mean_angin <- mean(
  df_imp$Kecepatan_Angin,
  na.rm = TRUE
)

# Mengisi missing value dengan mean
df_imp$Kecepatan_Angin[
  is.na(df_imp$Kecepatan_Angin)
] <- mean_angin

# Mengecek kembali missing value
colSums(is.na(df_imp))
##           Hujan            Suhu      Kelembapan   Keadaan_Cuaca Kecepatan_Angin 
##               0               0               0               0               0

Intepretasi Hasil 4.2

Hasil pengecekan menunjukkan terdapat 9 missing value pada variabel Keadaan_Cuaca dan 314 missing value pada Kecepatan_Angin, sedangkan variabel lainnya tidak memiliki missing value. Persentase missing value masing-masing sebesar sekitar 1,21% untuk Keadaan_Cuaca dan 42,26% untuk Kecepatan_Angin. Setelah dilakukan penanganan missing value, hasil pengecekan menunjukkan bahwa seluruh variabel memiliki 0 missing value. Dengan demikian, seluruh nilai yang hilang telah berhasil ditangani.

4.3 Kadinalitas

# Melihat kategori unik Keadaan_Cuaca
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
# Membuat interval
bins <- c(
  0, 10, 20, 30, 40,
  50, 60, 70, 80, 90, 100
)

# Membuat label kategori
labels <- 0:9

# Mengurangi jumlah kategori
df_imp$Keadaan_Cuaca_reduced <- cut(
  df_imp$Keadaan_Cuaca,
  breaks = bins,
  labels = labels,
  right = TRUE,
  include.lowest = TRUE
)

# Melihat hasil
head(df_imp, 10)
## # A tibble: 10 × 6
##    Hujan  Suhu Kelembapan Keadaan_Cuaca Kecepatan_Angin Keadaan_Cuaca_reduced
##    <dbl> <dbl>      <dbl>         <dbl>           <dbl> <fct>                
##  1     1  23           95             5            6.66 0                    
##  2     1  24           90             1            6.66 0                    
##  3     1  26.8         77             1            6.66 0                    
##  4     1  29.6         62             2            2    0                    
##  5     1  30.8         56             1            7    0                    
##  6     1  31           55             1            7    0                    
##  7     1  30.4         57             3            9    0                    
##  8     2  30.9         58             2           10    0                    
##  9     2  30.2         62             2            8    0                    
## 10     2  29.7         62             2            7    0
# Membandingkan jumlah kategori
cat(
  "Jumlah kategori Keadaan_Cuaca asli :",
  length(unique(df_imp$Keadaan_Cuaca)),
  "\n"
)
## Jumlah kategori Keadaan_Cuaca asli : 23
cat(
  "Jumlah kategori Keadaan_Cuaca setelah reduksi :",
  length(unique(df_imp$Keadaan_Cuaca_reduced)),
  "\n"
)
## Jumlah kategori Keadaan_Cuaca setelah reduksi : 7
# Melihat kategori hasil reduksi
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

Intepretasi Hasil 4.3

Hasil menunjukkan bahwa variabel Keadaan_Cuaca pada awalnya memiliki 23 kategori/nilai unik. Setelah dilakukan reduksi menggunakan interval, jumlah kategori menjadi 7 kategori. Hal ini menunjukkan bahwa proses reduksi kardinalitas berhasil mengurangi jumlah kategori dari 23 menjadi 7 sehingga representasi variabel Keadaan_Cuaca menjadi lebih sederhana.

4.4 Splitting Data

set.seed(200)

split_shuffle <- initial_split(
  df_imp,
  prop = 0.8
)

# Data training
train_data <- training(split_shuffle)

# Data testing
test_data <- testing(split_shuffle)

# Memisahkan variabel prediktor dan target
X_train <- train_data %>% select(-Hujan)
X_test  <- test_data %>% select(-Hujan)

y_train <- train_data$Hujan
y_test  <- test_data$Hujan

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

Intepretasi Hasil 4.4

Hasil pembagian data menunjukkan bahwa terdapat 594 observasi pada data training dan 149 observasi pada data testing dari total 743 observasi. Dengan demikian, data telah terbagi menjadi sekitar 80% data training dan 20% data testing. Data training digunakan sebagai data untuk proses preprocessing dan pembentukan model, sedangkan data testing digunakan untuk pengujian model.

4.5 Handling Outlier

# Variabel numerik
list_num <- c(
  "Suhu",
  "Kelembapan",
  "Kecepatan_Angin"
)

# Menyiapkan wadah hasil
list_outlier <- c()
list_lower_bound <- c()
list_upper_bound <- c()

# Menghitung batas outlier dengan IQR
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
  
  num_outliers_lower <- sum(
    X_train[[i]] < lower_bound,
    na.rm = TRUE
  )
  
  num_outliers_upper <- sum(
    X_train[[i]] > upper_bound,
    na.rm = TRUE
  )
  
  total_outliers <-
    num_outliers_lower + num_outliers_upper
  
  list_outlier <- c(
    list_outlier,
    total_outliers
  )
  
  list_lower_bound <- c(
    list_lower_bound,
    lower_bound
  )
  
  list_upper_bound <- c(
    list_upper_bound,
    upper_bound
  )
}

# Membuat tabel hasil
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

Intepretasi Hasil 4.5

Berdasarkan hasil deteksi outlier menggunakan metode IQR, variabel Suhu memiliki 0 outlier dengan batas bawah 17,4 dan batas atas 35,8, sedangkan variabel Kelembapan juga memiliki 0 outlier dengan batas bawah 46,5 dan batas atas 122,5. Sementara itu, variabel Kecepatan_Angin memiliki 50 outlier, dengan batas bawah 2,0 dan batas atas 10,0, sehingga nilai Kecepatan_Angin yang berada di bawah 2,0 atau di atas 10,0 dikategorikan sebagai outlier. Dengan demikian, dapat disimpulkan bahwa outlier hanya ditemukan pada variabel Kecepatan_Angin, sedangkan Suhu dan Kelembapan tidak memiliki outlier berdasarkan batas IQR yang diperoleh.

4.6 Capping

X_train_capped <- X_train
X_test_capped <- X_test

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
  
  # Capping data training
  X_train_capped[[i]] <- pmin(
    pmax(
      X_train[[i]],
      lower_bound
    ),
    upper_bound
  )
  
  # Capping data testing menggunakan
  # batas dari data training
  X_test_capped[[i]] <- pmin(
    pmax(
      X_test[[i]],
      lower_bound
    ),
    upper_bound
  )
}
diagnostic_plots <- function(df, variable) {
  
  p1 <- ggplot(
    df,
    aes(x = .data[[variable]])
  ) +
    geom_histogram(
      bins = 30,
      fill = "navy",
      color = "black"
    ) +
    ggtitle("Histogram") +
    theme_minimal()
  
  p2 <- ggplot(
    df,
    aes(y = .data[[variable]])
  ) +
    geom_boxplot(
      fill = "navy"
    ) +
    ggtitle("Boxplot") +
    theme_minimal()
  
  grid.arrange(
    p1,
    p2,
    ncol = 2
  )
}

for (col in list_num) {
  
  cat(
    col,
    "- Sebelum Capping\n"
  )
  
  diagnostic_plots(
    X_train,
    col
  )
  
  cat(
    "\n",
    col,
    "- Setelah Capping\n"
  )
  
  diagnostic_plots(
    X_train_capped,
    col
  )
}
## Suhu - Sebelum Capping

## 
##  Suhu - Setelah Capping

## Kelembapan - Sebelum Capping

## 
##  Kelembapan - Setelah Capping

## Kecepatan_Angin - Sebelum Capping

## 
##  Kecepatan_Angin - Setelah Capping

# Intepretasi Hasil 4.5

Berdasarkan histogram dan boxplot, variabel Suhu memiliki nilai sekitar 22,5–31,5 dan tidak menunjukkan titik pencilan di luar whisker, sehingga tidak terlihat adanya outlier yang signifikan. Variabel Kelembapan memiliki nilai sekitar 52–100 dan juga tidak menunjukkan titik pencilan pada boxplot. Sementara itu, variabel Kecepatan_Angin memiliki nilai sekitar 2–21, dengan sebagian besar data berada pada nilai yang lebih rendah, sedangkan boxplot menunjukkan beberapa titik di atas whisker pada nilai sekitar 11–21 yang mengindikasikan adanya outlier. Dengan demikian, outlier paling terlihat pada variabel Kecepatan_Angin, sedangkan pada variabel Suhu dan Kelembapan tidak terlihat adanya outlier yang signifikan, sehingga data selanjutnya dapat ditangani menggunakan metode capping.

4.6 scalling data dengan robust scaler

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

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

# Scaling data training
for (col in list_num) {
  
  X_train_capped[[col]] <-
    (
      X_train_capped[[col]] -
        median_val[col]
    ) /
    iqr_val[col]
}

# Scaling data testing menggunakan
# median dan IQR dari data training
for (col in list_num) {
  
  X_test_capped[[col]] <-
    (
      X_test_capped[[col]] -
        median_val[col]
    ) /
    iqr_val[col]
}

# Melihat hasil scaling
head(X_train_capped)
## # A tibble: 6 × 5
##      Suhu Kelembapan Keadaan_Cuaca Kecepatan_Angin Keadaan_Cuaca_reduced
##     <dbl>      <dbl>         <dbl>           <dbl> <fct>                
## 1 -0.500       0.579            61           0     6                    
## 2  1.09       -0.947             2           1.67  0                    
## 3  0.0870     -0.263             3          -0.828 0                    
## 4  1.15       -1.53              2           1.17  0                    
## 5  0.674      -0.421             2           0     0                    
## 6  0.391      -0.368             2          -1.83  0

Intepretasi Hasil 4.6

Berdasarkan hasil Robust Scaling, nilai variabel numerik seperti Suhu, Kelembapan, dan Kecepatan_Angin telah mengalami perubahan ke skala baru berdasarkan median dan IQR. Pada enam observasi pertama, nilai Suhu berada antara -0,50 hingga 1,15, Kelembapan antara -0,95 hingga 0,58, dan Kecepatan_Angin antara -1,83 hingga 1,67. Nilai positif menunjukkan bahwa nilai pengamatan berada di atas median, sedangkan nilai negatif menunjukkan bahwa nilai berada di bawah median. Sementara itu, Keadaan_Cuaca masih berupa nilai kategori karena belum dilakukan encoding pada tahap ini. Dengan demikian, hasil tersebut menunjukkan bahwa variabel numerik telah berhasil disetarakan skalanya menggunakan Robust Scaler dengan tetap mempertahankan informasi relatif terhadap median data.

4.7 encoding

list_cat <- c(
  "Keadaan_Cuaca_reduced"
)

resep_encode <- recipe(
  ~ Keadaan_Cuaca_reduced,
  data = X_train_capped
) %>%
  step_dummy(
    all_of(list_cat),
    one_hot = TRUE
  ) %>%
  prep(
    training = X_train_capped
  )

X_train_encoded <- bake(
  resep_encode,
  new_data = X_train_capped
)

X_test_encoded <- bake(
  resep_encode,
  new_data = X_test_capped
)

# Melihat hasil encoding
head(X_train_encoded)
## # A tibble: 6 × 10
##   Keadaan_Cuaca_reduced_X0 Keadaan_Cuaca_reduced_X1 Keadaan_Cuaca_reduced_X2
##                      <dbl>                    <dbl>                    <dbl>
## 1                        0                        0                        0
## 2                        1                        0                        0
## 3                        1                        0                        0
## 4                        1                        0                        0
## 5                        1                        0                        0
## 6                        1                        0                        0
## # ℹ 7 more variables: 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>
head(X_test_encoded)
## # A tibble: 6 × 10
##   Keadaan_Cuaca_reduced_X0 Keadaan_Cuaca_reduced_X1 Keadaan_Cuaca_reduced_X2
##                      <dbl>                    <dbl>                    <dbl>
## 1                        1                        0                        0
## 2                        1                        0                        0
## 3                        1                        0                        0
## 4                        1                        0                        0
## 5                        1                        0                        0
## 6                        1                        0                        0
## # ℹ 7 more variables: 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>

Intepretasi Hasil 4.7

Berdasarkan hasil encoding, variabel Keadaan_Cuaca_reduced telah berhasil diubah dari variabel kategorik menjadi beberapa variabel dummy dalam bentuk numerik 0 dan 1. Output menunjukkan terdapat 10 kolom hasil encoding, sedangkan pada enam observasi pertama terlihat nilai 0 dan 1 yang menunjukkan ada atau tidaknya suatu kategori pada setiap observasi. Dengan demikian, hasil encoding menunjukkan bahwa data kategorik telah berhasil dikonversi ke bentuk numerik sehingga dapat digunakan sebagai input dalam proses pemodelan machine learning.

4.8 Balancing data dengan SMOTE

# Melihat distribusi target sebelum SMOTE
table(y_train)
## y_train
##   1   2 
## 128 466
# Menggabungkan X dan y
train_full <- X_train_encoded %>%
  mutate(
    Hujan = factor(y_train)
  )

# SMOTE
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
)

# Memisahkan kembali X dan y
X_train_balanced <- train_balanced %>%
  select(-Hujan)

y_train_balanced <-
  train_balanced$Hujan

# Melihat distribusi setelah SMOTE
table(y_train_balanced)
## y_train_balanced
##   1   2 
## 466 466

Intepretasi Hasil 4.8

Hasil distribusi kelas sebelum SMOTE menunjukkan bahwa kelas 1 memiliki 128 observasi, sedangkan kelas 2 memiliki 466 observasi. Kondisi tersebut menunjukkan adanya ketidakseimbangan kelas karena kelas 2 memiliki jumlah observasi yang jauh lebih besar. Setelah dilakukan SMOTE, jumlah observasi kelas 1 meningkat menjadi 466, sedangkan kelas 2 tetap 466 observasi. Dengan demikian, distribusi data menjadi seimbang dengan perbandingan 1:1, sehingga data training telah siap digunakan untuk proses klasifikasi.

BAB V KESIMPULAN

5.1 Kesimpulan

   Konsep dan tujuan dari berbagai jenis feature engineering yang digunakan dalam pengolahan data menggunakan RStudio. Pemahaman tersebut mencakup fungsi feature engineering dalam mempersiapkan dan meningkatkan kualitas variabel sebelum dilakukan analisis lebih lanjut. Mahasiswa juga dapat memahami bahwa setiap teknik feature engineering memiliki fungsi dan penerapan yang berbeda sesuai dengan karakteristik data. Pemahaman konsep tersebut menjadi dasar dalam menentukan teknik yang sesuai untuk mengolah suatu dataset. Dengan demikian, tujuan pertama mengenai pemahaman konsep berbagai jenis feature engineering pada RStudio telah tercapai.
   Berbagai teknik feature engineering menggunakan program RStudio sesuai dengan kebutuhan data. Penerapan tersebut dilakukan melalui tahapan pengolahan variabel, seperti penanganan data, transformasi, reduksi kategori, dan pembentukan fitur yang lebih sesuai untuk analisis. Penggunaan RStudio membantu mahasiswa melakukan proses feature engineering secara sistematis dan efisien. Hasil penerapan menunjukkan bahwa teknik feature engineering dapat digunakan untuk menghasilkan data yang lebih siap dan sesuai untuk tahap analisis berikutnya. Dengan demikian, tujuan kedua mengenai kemampuan melakukan teknik feature engineering pada RStudio juga telah tercapai.
   Berdasarkan hasil preprocessing data curah hujan sebanyak 743 observasi, ditemukan missing value pada variabel Keadaan_Cuaca sebanyak 9 data dan Kecepatan_Angin sebanyak 314 data. Missing value pada Keadaan_Cuaca ditangani menggunakan interpolasi, sedangkan pada Kecepatan_Angin diisi menggunakan nilai rata-rata. Variabel Keadaan_Cuaca kemudian direduksi dari 23 kategori menjadi 7 kategori melalui pengelompokan interval. Data selanjutnya dibagi menjadi data training sebanyak 594 observasi dan data testing sebanyak 149 observasi. Pada variabel numerik Suhu, Kelembapan, dan Kecepatan_Angin dilakukan deteksi outlier menggunakan metode IQR dan penanganan outlier dengan teknik capping berdasarkan batas yang diperoleh dari data training. Selanjutnya, data numerik distandarisasi menggunakan Robust Scaling berdasarkan median dan IQR, sedangkan variabel kategorik Keadaan_Cuaca_reduced diubah menjadi variabel dummy. Distribusi target Hujan menunjukkan ketidakseimbangan kelas, yaitu 128 observasi untuk kelas 1 dan 466 observasi untuk kelas 2, sehingga dilakukan SMOTE untuk menyeimbangkan data training. Setelah SMOTE, jumlah masing-masing kelas menjadi 466 observasi, sehingga data training menjadi seimbang dan siap digunakan pada tahap pemodelan klasifikasi.

5.2 Saran

   Penulis menyarankan agar ketepatan sintaks program R selalu diperhatikan untuk menghindari kesalahan dalam proses analisis. Penggunaan bahasa perlu disesuaikan dengan kaidah KBBI. Aturan penulisan huruf tebal juga perlu diperhatikan agar laporan tersusun secara sistematis, rapi, dan sesuai dengan kaidah penulisan ilmiah.

DAFTAR PUSTAKA

Ahsan, M. M., Mahmud, M. A. P., Saha, P. K., Gupta, K. D., & Siddique, Z. (2021). Effect of Data Scaling Methods on Machine Learning Algorithms and Model Performance. Technologies, 9(3). https://doi.org/10.3390/technologies9030052
Bichri, H., Chergui, A., & Hain, M. (2024). Investigating the Impact of Train / Test Split Ratio on the Performance of Pre-Trained Models with Custom Datasets. In IJACSA) International Journal of Advanced Computer Science and Applications (Vol. 15, Number 2). www.ijacsa.thesai.org
Emmanuel, T., Maupong, T., Mpoeleng, D., Semong, T., Mphago, B., & Tabona, O. (2021). A survey on missing data in machine learning. Journal of Big Data, 8(1). https://doi.org/10.1186/s40537-021-00516-9
Fransiska, H. (2026). Modul Praktikum Machine Learning. Universitas Bengkulu.
Foorthuis, R. (2021). On the nature and types of anomalies: a review of deviations in data. In International Journal of Data Science and Analytics (Vol. 12, Number 4, pp. 297–331). Springer Science and Business Media Deutschland GmbH. https://doi.org/10.1007/s41060-021-00265-1
Mumuni, A., & Mumuni, F. (2025). Automated data processing and feature engineering for deep learning and big data applications: A survey. Journal of Information and Intelligence, 3(2), 113–153. https://doi.org/10.1016/j.jiixd.2024.01.002
Pargent, F., Pfisterer, F., Thomas, J., & Bischl, B. (2022). Regularized target encoding outperforms traditional methods in supervised machine learning with high cardinality features. Computational Statistics, 37(5), 2671–2692. https://doi.org/10.1007/s00180-022-01207-6
Villa-Blanco, C., Bielza, C., & Larrañaga, P. (2023). Feature subset selection for data and feature streams: a review. Artificial Intelligence Review, 56, 1011–1062. https://doi.org/10.1007/s10462-023-10546-9