BAB I PENDAHULUAN

1.1 Latar Belakang Masalah

Latar Belakang

Perkembangan teknologi dan meningkatnya ketersediaan data mendorong penggunaan machine learning dalam berbagai bidang untuk membantu proses analisis, prediksi, dan klasifikasi. Dalam penerapannya, keberhasilan model machine learning tidak hanya dipengaruhi oleh algoritma yang digunakan, tetapi juga oleh kualitas data dan fitur yang menjadi masukan model. Oleh karena itu, diperlukan tahapan pengolahan data yang tepat agar informasi dalam data dapat digunakan secara optimal dalam proses pemodelan.

Salah satu tahapan penting dalam pengolahan data adalah feature engineering, yaitu proses mengubah dan menyiapkan data mentah menjadi fitur yang sesuai untuk digunakan dalam algoritma machine learning. Feature engineering dapat dilakukan melalui beberapa teknik, seperti handling missing value, pemeriksaan kardinalitas, splitting data, handling outlier, scaling, encoding, dan penanganan imbalanced dataset. Penerapan feature engineering yang tepat dapat memberikan pengaruh yang besar terhadap kinerja model machine learning, bahkan meningkatkan kemampuan klasifikasi secara signifikan (Darmawan dkk., 2026) .

Oleh karena itu, praktikum feature engineering dilakukan untuk memahami konsep dan penerapan berbagai teknik feature engineering menggunakan RStudio. Melalui praktikum ini, praktikan diharapkan mampu melakukan pengolahan dan penyiapan fitur, mulai dari menangani data yang hilang hingga mengatasi permasalahan skala, data kategorik, pencilan, dan ketidakseimbangan kelas. Sehingga, praktikan dapat memahami bahwa kualitas fitur merupakan salah satu bagian penting dalam mempersiapkan data sebelum digunakan pada proses pemodelan machine learning.

1.2 Rumusan Masalah

Berdasarkan latar belakang di atas, rumusan masalah yang dapat disimpulkan yaitu:

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

1.3 Tujuan

Berdasarkan rumusan masalah di atas, tujuan yang dapat disimpulkan yaitu:

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

1.4 Manfaat Penelitian

Adapun manfaat dari praktikum ini yaitu:

  1. Bagi penulis, yaitu dapat memberikan informasi dan pengetahuan serta menerapkan ilmu pengetahuan mengenai mengenai teknik feature engineering dengan R.
  2. Bagi Pembaca, yaitu dapat menambah ilmu pengetahuan dan pemahaman mengenai teknik feature engineering dengan R.

1.5 Batasan Masalah

Adapun batasan masalah dari praktikum ini, yaitu gunakan dataset data curah hujan.xlsx untuk melakukan preprocessing data, menggunakan mode imputation, stratify splitting, dan standard scaler. Lakukan 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 Machine Learning

Machine learning merupakan salah satu bagian penting dalam bidang kecerdasan buatan yang digunakan untuk menyelesaikan berbagai permasalahan. Teknologi ini memungkinkan komputer untuk mempelajari suatu pola dari data tanpa harus diberikan instruksi atau aturan secara eksplisit untuk setiap permasalahan. Machine learning dapat melakukan pembelajaran berdasarkan pola dan informasi yang terdapat dalam data dengan memanfaatkan algoritma dan model statistik. Tujuan penerapan machine learning adalah membuat sistem mampu mengolah data secara efektif serta mengenali pola sehingga dapat digunakan untuk memahami karakteristik objek dan menghasilkan prediksi terhadap data yang belum diketahui (Nurhalizah dkk., 2024).

Penerapan machine learning dapat membantu mengurangi pekerjaan yang sebelumnya dilakukan secara manual. Algoritma machine learning mampu mempelajari hubungan dan pola yang kompleks dalam data sehingga tidak hanya bergantung pada aturan yang telah ditentukan sebelumnya. Hal tersebut memungkinkan sistem untuk digunakan dalam berbagai proses, seperti prediksi, klasifikasi, dan pengambilan keputusan. Meskipun demikian, penerapan machine learning juga memiliki beberapa tantangan, salah satunya berkaitan dengan keamanan sistem yang dapat menghadapi serangan atau manipulasi data. Selain itu, ketidakseimbangan data juga dapat memengaruhi kinerja model karena model cenderung lebih baik dalam mengenali kelas dengan jumlah data yang lebih banyak dibandingkan kelas minoritas (Nuhalizah dkk., 2024).

Berdasarkan proses pembelajarannya, machine learning secara umum terdiri atas tiga paradigma utama, yaitu sebagai berikut (Nurhalizah dkk., 2024):

  1. Supervised Learning, yaitu metode pembelajaran yang menggunakan data yang telah memiliki label atau target. Model mempelajari hubungan antara data masukan dan label untuk menghasilkan prediksi atau melakukan klasifikasi pada data baru.
  2. Unsupervised Learning, yaitu menggunakan data yang tidak memiliki label atau target. Model bertugas menemukan pola, struktur, atau kelompok yang terdapat dalam data secara mandiri, misalnya melalui proses klasterisasi.
  3. Reinforcement Learning, yaitu metode pembelajaran yang melibatkan agen untuk melakukan tindakan berdasarkan kondisi tertentu. Agen memperoleh umpan balik berupa penghargaan (reward) atau penalti dari tindakan yang dilakukan, kemudian menggunakan informasi tersebut untuk menentukan tindakan yang lebih optimal.

2.2 Feature Engneering

Feature Engineering merupakan proses mengolah data mentah menjadi fitur yang sesuai dan dapat digunakan dalam algoritma machine learning. Proses ini mencakup pemilihan serta pengolahan fitur yang dianggap relevan dan memiliki pengaruh terhadap model. Penerapan feature engineering membutuhkan pemahaman terhadap karakteristik data karena melibatkan analisis data, pengetahuan mengenai data, serta pertimbangan dalam menentukan fitur yang tepat. Tujuan utama feature engineering adalah menghasilkan data yang lebih sederhana dan efisien untuk diproses, sekaligus meningkatkan kinerja model. Sehingga, kualitas fitur yang digunakan dapat menjadi faktor penting dalam menentukan hasil pemodelan, bahkan dapat lebih berpengaruh dibandingkan pemilihan algoritma yang kompleks. Berikut beberapa jenis feature engineering yang dapat diterapkan (Fransiska, 2026):

  1. Handling Missing Value, yaitu suatu kondisi ketika terdapat data yang tidak tersedia pada suatu observasi. Penanganan missing value diperlukan agar data dapat digunakan secara optimal dalam proses pemodelan, misalnya dengan menghapus data atau melakukan imputasi menggunakan nilai tertentu seperti rata-rata, median, atau modus.
  2. Kardinalitas, hal ini menunjukkan jumlah nilai atau kategori unik dalam suatu variabel kategorik. Kardinalitas yang tinggi dapat meningkatkan jumlah fitur setelah proses encoding, memperbesar kompleksitas data, serta meningkatkan risiko overfitting apabila beberapa kategori hanya memiliki sedikit observasi.
  3. Splitting Data, yaitu proses membagi dataset menjadi data training dan testing. Data training digunakan untuk membangun model, sedangkan data testing digunakan untuk mengevaluasi kemampuan model dalam melakukan prediksi terhadap data yang belum digunakan saat pelatihan.
  4. Handling Outlier, yaitu observasi yang memiliki nilai sangat berbeda dari sebagian besar data lainnya. Keberadaan outlier perlu diperiksa dan ditangani karena dapat memengaruhi hasil analisis dan kinerja model machine learning.
  5. Scaling Data, yaitu proses mengubah skala variabel numerik agar berada pada rentang atau skala yang sebanding. Proses ini bertujuan mencegah fitur dengan nilai yang lebih besar mendominasi proses pembelajaran, terutama pada algoritma yang sensitif terhadap skala.
  6. Encoding, yaitu proses mengubah data kategorik atau non-numerik menjadi bentuk numerik agar dapat digunakan oleh algoritma machine learning. Teknik yang umum digunakan antara lain One-Hot Encoding dan Ordinal Encoding.
  7. Imbalanced Dataset, yaitu suatu kondisi ketika jumlah observasi pada setiap kelas tidak seimbang. Kondisi ini dapat menyebabkan model lebih cenderung memprediksi kelas mayoritas sehingga kemampuan model dalam mengenali kelas minoritas menjadi kurang optimal.

BAB III METODE PENELITIAN

3.1 Sumber Data

Jenis data yang digunakan pada penelitian ini adalah data numerik. Data numerik merupakan data yang berbentuk angka atau bersifat kuantitatif yang dapat dianalisis. Data yang digunakan merupakan dataset curah hujan. Sumber data yang digunakan dalam penelitian ini yaitu data sekunder yang diperoleh oleh asisten praktikum Machine Learning 2026.

3.2 Variabel Penelitian

Penelitian ini menggunakan lima variabel, yaitu satu variabel kategorik dan empat variabel numerik. Variabel hujan (menunjukkan nilai curah hujan), suhu (menunjukkan kondisi suhu), kelembapan (menunjukkan tingkat kelembapan udara), keadaan cuaca (variabel kategorik yang menunjukkan kondisi cuaca), dan kecepatan angin (menunjukkan kecepatan angin).

3.3 Langkah-langkah Analisis

Berikut adalah langkah-langkah yang dilakukan dalam analisis:

  1. Membaca dan memeriksa dataset data curah hujan.
  2. Menangani missing value menggunakan metode mode imputation.
  3. Melakukan interpolasi pada variabel Keadaan_Cuaca.
  4. Menangani outlier pada data numerik menggunakan metode capping.
  5. Membagi data menjadi data training dan testing menggunakan stratify splitting.
  6. Melakukan scaling pada data numerik menggunakan standard scaler.
  7. Menangani ketidakseimbangan data pada data training menggunakan metode SMOTE.
  8. Menampilkan dan menginterpretasikan output dari setiap tahapan preprocessing.

BAB IV HASIL DAN PEMBAHASAN

4.1 Hasil Penanganan Missing Value

library(readxl)
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(zoo)
## 
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
library(caret)
## Loading required package: ggplot2
## Loading required package: lattice
library(rsample)
## 
## Attaching package: 'rsample'
## The following object is masked from 'package:caret':
## 
##     calibration
library(recipes)
## 
## Attaching package: 'recipes'
## The following object is masked from 'package:stats':
## 
##     step
library(themis)
library(moments)
library(ggplot2)
library(gridExtra)
## 
## Attaching package: 'gridExtra'
## The following object is masked from 'package:dplyr':
## 
##     combine
data <- read_excel("C:/Users/chesa/Downloads/data curah hujan (1).xlsx")
# Memeriksa struktur dan ukuran data
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 ...
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
dim(data)
## [1] 743   5
# Memeriksa missing value
missing_value <- data.frame(
  Variabel = names(data),
  Jumlah_NA = sapply(data, function(x) sum(is.na(x))),
  Persentase_NA = round(
    sapply(data, function(x) mean(is.na(x))) * 100, 2
  )
)
missing_value
##                        Variabel Jumlah_NA Persentase_NA
## Hujan                     Hujan         0          0.00
## Suhu                       Suhu         0          0.00
## Kelembapan           Kelembapan         0          0.00
## Keadaan_Cuaca     Keadaan_Cuaca         9          1.21
## Kecepatan_Angin Kecepatan_Angin       314         42.26
sum(!complete.cases(data))
## [1] 319

Berdasarkan hasil pemeriksaan dataset, data curah hujan terdiri atas 743 observasi dan 5 variabel, yaitu Hujan, Suhu, Kelembapan, Keadaan_Cuaca, dan Kecepatan_Angin. Pemeriksaan missing value dilakukan untuk mengetahui jumlah data yang hilang pada setiap variabel sebelum proses preprocessing dilaksanakan. Hasil pemeriksaan menunjukkan bahwa variabel Kecepatan_Angin memiliki 314 missing value, sedangkan variabel Keadaan_Cuaca memiliki 9 missing value. Kondisi tersebut menunjukkan bahwa data yang hilang perlu ditangani agar dapat digunakan pada tahapan analisis selanjutnya.

# Fungsi untuk menghitung modus
get_mode <- function(x) {
  x_non_na <- x[!is.na(x)]
  ux <- unique(x_non_na)
  ux[which.max(tabulate(match(x_non_na, ux)))]
}

# Mode imputation pada Kecepatan_Angin
na_angin_sebelum <- sum(is.na(data$Kecepatan_Angin))
mode_angin <- get_mode(data$Kecepatan_Angin)

cat("Missing value sebelum imputasi:",
    na_angin_sebelum, "\n")
## Missing value sebelum imputasi: 314
cat("Modus Kecepatan_Angin:",
    mode_angin, "\n")
## Modus Kecepatan_Angin: 3
data$Kecepatan_Angin[
  is.na(data$Kecepatan_Angin)
] <- mode_angin

cat("Missing value setelah imputasi:",
    sum(is.na(data$Kecepatan_Angin)), "\n")
## Missing value setelah imputasi: 0
# Interpolasi linear pada Keadaan_Cuaca
na_cuaca_sebelum <- sum(is.na(data$Keadaan_Cuaca))

data$Keadaan_Cuaca <- zoo::na.approx(
  data$Keadaan_Cuaca,
  na.rm = FALSE
)

cat("Missing value Keadaan_Cuaca sebelum interpolasi:",
    na_cuaca_sebelum, "\n")
## Missing value Keadaan_Cuaca sebelum interpolasi: 9
cat("Missing value Keadaan_Cuaca setelah interpolasi:",
    sum(is.na(data$Keadaan_Cuaca)), "\n")
## Missing value Keadaan_Cuaca setelah interpolasi: 0
# Memeriksa missing value setelah preprocessing
sapply(data, function(x) sum(is.na(x)))
##           Hujan            Suhu      Kelembapan   Keadaan_Cuaca Kecepatan_Angin 
##               0               0               0               0               0

Penanganan missing value dilakukan menggunakan dua metode, yaitu mode imputation dan interpolasi linear. Pada variabel Kecepatan_Angin, nilai yang hilang digantikan dengan modus atau nilai yang paling sering muncul dalam variabel tersebut. Berdasarkan hasil pengolahan data, modus Kecepatan_Angin adalah 3. Metode ini digunakan untuk mengisi data yang hilang berdasarkan nilai yang memiliki frekuensi kemunculan tertinggi. Sementara itu, variabel Keadaan_Cuaca ditangani menggunakan interpolasi linear melalui fungsi na.approx() dari paket zoo. Metode tersebut memperkirakan nilai yang hilang berdasarkan hubungan linear antara nilai pengamatan sebelum dan sesudahnya. Pemeriksaan kembali dilakukan untuk mengetahui jumlah missing value setelah kedua metode diterapkan. Nilai yang masih hilang perlu diperhatikan karena interpolasi linear tidak secara otomatis mengisi nilai kosong yang berada pada bagian awal atau akhir data. Selain itu, interpolasi linear pada variabel yang merepresentasikan kategori cuaca perlu ditafsirkan secara hati-hati karena kode kategori tidak selalu memiliki makna numerik yang kontinu.

4.2 Hasil Penanganan Outlier dengan Capping

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

# Salinan data untuk proses capping
data_capped <- data

# Menghitung batas outlier menggunakan IQR
hasil_outlier <- data.frame()

for (i in list_num) {

  Q1 <- quantile(data[[i]], 0.25, na.rm = TRUE)
  Q3 <- quantile(data[[i]], 0.75, na.rm = TRUE)
  IQR_val <- Q3 - Q1

  lower_bound <- Q1 - 1.5 * IQR_val
  upper_bound <- Q3 + 1.5 * IQR_val

  jumlah_outlier <- sum(
    data[[i]] < lower_bound |
      data[[i]] > upper_bound,
    na.rm = TRUE
  )

  hasil_outlier <- rbind(
    hasil_outlier,
    data.frame(
      Variabel = i,
      Q1 = Q1,
      Q3 = Q3,
      IQR = IQR_val,
      Batas_Bawah = lower_bound,
      Batas_Atas = upper_bound,
      Jumlah_Outlier = jumlah_outlier
    )
  )
}

hasil_outlier
##             Variabel   Q1   Q3  IQR Batas_Bawah Batas_Atas Jumlah_Outlier
## 25%             Suhu 24.3 28.9  4.6        17.4       35.8              0
## 25%1      Kelembapan 75.0 94.0 19.0        46.5      122.5              0
## 25%2 Kecepatan_Angin  3.0  7.0  4.0        -3.0       13.0             15

Pemeriksaan outlier dilakukan pada variabel Suhu, Kelembapan, dan Kecepatan_Angin menggunakan metode Interquartile Range (IQR). Metode ini menentukan batas bawah dan batas atas berdasarkan kuartil pertama (Q1), kuartil ketiga (Q3), serta nilai IQR yang diperoleh dari selisih Q3 dan Q1. Pengamatan yang berada di bawah batas bawah atau di atas batas atas dikategorikan sebagai outlier berdasarkan kriteria tersebut. Hasil perhitungan pada tabel menunjukkan jumlah outlier pada setiap variabel yang diperiksa. Keberadaan nilai yang berada di luar batas IQR tidak selalu berarti bahwa data tersebut salah, tetapi menunjukkan adanya pengamatan yang relatif ekstrem dibandingkan sebagian besar data. Oleh karena itu, penanganan dilakukan dengan capping agar nilai ekstrem dibatasi tanpa menghapus observasi dari dataset.

# Melakukan capping berdasarkan batas IQR
for (i in list_num) {

  Q1 <- quantile(data[[i]], 0.25, na.rm = TRUE)
  Q3 <- quantile(data[[i]], 0.75, na.rm = TRUE)
  IQR_val <- Q3 - Q1

  lower_bound <- Q1 - 1.5 * IQR_val
  upper_bound <- Q3 + 1.5 * IQR_val

  data_capped[[i]] <- pmin(
    pmax(data[[i]], lower_bound),
    upper_bound
  )
}

# Membandingkan ringkasan sebelum dan sesudah capping
for (i in list_num) {

  cat("\nVariabel:", i, "\n")

  cat("Sebelum capping:\n")
  print(summary(data[[i]]))

  cat("Sesudah capping:\n")
  print(summary(data_capped[[i]]))
}
## 
## Variabel: Suhu 
## Sebelum capping:
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   22.60   24.30   26.00   26.54   28.90   32.00 
## Sesudah capping:
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   22.60   24.30   26.00   26.54   28.90   32.00 
## 
## Variabel: Kelembapan 
## Sebelum capping:
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   52.00   75.00   86.00   83.88   94.00  100.00 
## Sesudah capping:
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   52.00   75.00   86.00   83.88   94.00  100.00 
## 
## Variabel: Kecepatan_Angin 
## Sebelum capping:
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    2.00    3.00    3.00    5.11    7.00   21.00 
## Sesudah capping:
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   2.000   3.000   3.000   5.074   7.000  13.000

Proses capping dilakukan dengan membatasi nilai yang berada di bawah batas bawah menjadi sama dengan batas bawah dan nilai yang melebihi batas atas menjadi sama dengan batas atas. Nilai yang masih berada dalam rentang tersebut tetap dipertahankan. Perbandingan statistik deskriptif sebelum dan sesudah capping digunakan untuk mengetahui perubahan nilai minimum, maksimum, median, dan kuartil pada setiap variabel. Metode ini mempertahankan jumlah observasi karena tidak ada baris data yang dihapus. Perubahan terutama terjadi pada nilai yang berada di luar batas IQR. Variabel yang tidak memiliki outlier berdasarkan batas tersebut tidak mengalami perubahan nilai akibat proses capping.

# Membuat boxplot sebelum dan sesudah capping
plot_before <- list()
plot_after <- list()

for (i in list_num) {

  plot_before[[i]] <- ggplot(
    data,
    aes(y = .data[[i]])
  ) +
    geom_boxplot() +
    labs(
      title = paste("Sebelum Capping -", i),
      y = i
    ) +
    theme_minimal()

  plot_after[[i]] <- ggplot(
    data_capped,
    aes(y = .data[[i]])
  ) +
    geom_boxplot() +
    labs(
      title = paste("Sesudah Capping -", i),
      y = i
    ) +
    theme_minimal()
}

gridExtra::grid.arrange(
  plot_before$Suhu,
  plot_after$Suhu,
  plot_before$Kelembapan,
  plot_after$Kelembapan,
  plot_before$Kecepatan_Angin,
  plot_after$Kecepatan_Angin,
  ncol = 2
)

Berdasarkan perbandingan boxplot, perubahan sebaran data dapat diamati sebelum dan sesudah capping. Nilai yang sebelumnya berada di luar batas IQR dibatasi sesuai dengan nilai ambang yang telah dihitung. Perubahan tersebut dapat terlihat pada bagian ujung sebaran data, terutama apabila variabel memiliki pengamatan ekstrem. Hasil visualisasi melengkapi tabel statistik deskriptif sehingga perubahan akibat capping dapat diamati secara lebih jelas.

4.3 Hasil Stratified Splitting

library(rsample)

# Membagi data dengan proporsi 80:20
set.seed(200)

split_stratify <- initial_split(
  data_capped,
  prop = 0.80,
  strata = Hujan
)

train_data <- training(split_stratify)
test_data <- testing(split_stratify)

# Ukuran data training dan testing
cat("Ukuran data awal:", dim(data_capped), "\n")
## Ukuran data awal: 743 5
cat("Ukuran data training:", dim(train_data), "\n")
## Ukuran data training: 594 5
cat("Ukuran data testing:", dim(test_data), "\n")
## Ukuran data testing: 149 5
# Distribusi kelas pada data awal
cat("\nDistribusi kelas data awal:\n")
## 
## Distribusi kelas data awal:
print(table(data_capped$Hujan))
## 
##   1   2 
## 164 579
print(round(prop.table(table(data_capped$Hujan)) * 100, 2))
## 
##     1     2 
## 22.07 77.93
# Distribusi kelas pada data training
cat("\nDistribusi kelas training:\n")
## 
## Distribusi kelas training:
print(table(train_data$Hujan))
## 
##   1   2 
## 131 463
print(round(prop.table(table(train_data$Hujan)) * 100, 2))
## 
##     1     2 
## 22.05 77.95
# Distribusi kelas pada data testing
cat("\nDistribusi kelas testing:\n")
## 
## Distribusi kelas testing:
print(table(test_data$Hujan))
## 
##   1   2 
##  33 116
print(round(prop.table(table(test_data$Hujan)) * 100, 2))
## 
##     1     2 
## 22.15 77.85
# Memisahkan prediktor dan target
X_train <- dplyr::select(train_data, -Hujan)
X_test <- dplyr::select(test_data, -Hujan)

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

Pembagian data dilakukan menggunakan metode stratified splitting dengan proporsi 80:20. Metode ini membagi dataset menjadi data training sebesar 80% dan data testing sebesar 20% dengan mempertimbangkan distribusi kelas pada variabel target Hujan. Penggunaan strata = Hujan bertujuan agar proporsi kelas pada kedua bagian data relatif mendekati proporsi kelas pada dataset awal. Berdasarkan hasil pembagian, data awal yang terdiri atas 743 observasi dibagi menjadi 594 observasi pada data training dan 149 observasi pada data testing. Data training digunakan untuk tahapan pengolahan fitur dan penyeimbangan kelas sebelum pemodelan, sedangkan data testing disimpan untuk mengevaluasi kemampuan model pada pengamatan yang tidak digunakan selama proses pelatihan. Variabel Hujan ditetapkan sebagai variabel target, sementara variabel lainnya digunakan sebagai prediktor.

4.4 Hasil Reduksi Kategori Keadaan_Cuaca

# Mengelompokkan Keadaan_Cuaca ke dalam interval 10 satuan
bins <- seq(0, 100, by = 10)
labels <- 0:9

X_train$Keadaan_Cuaca_reduced <- cut(
  X_train$Keadaan_Cuaca,
  breaks = bins,
  labels = labels,
  right = TRUE,
  include.lowest = TRUE
)

X_test$Keadaan_Cuaca_reduced <- cut(
  X_test$Keadaan_Cuaca,
  breaks = bins,
  labels = labels,
  right = TRUE,
  include.lowest = TRUE
)

# Menghapus variabel Keadaan_Cuaca asli
X_train$Keadaan_Cuaca <- NULL
X_test$Keadaan_Cuaca <- NULL

# Memeriksa hasil reduksi kategori
cat("Distribusi kategori training:\n")
## Distribusi kategori training:
print(table(X_train$Keadaan_Cuaca_reduced, useNA = "ifany"))
## 
##   0   1   2   3   4   5   6   7   8   9 
## 422  35  39   0   0  18  56   0   0  24
cat("\nDistribusi kategori testing:\n")
## 
## Distribusi kategori testing:
print(table(X_test$Keadaan_Cuaca_reduced, useNA = "ifany"))
## 
##   0   1   2   3   4   5   6   7   8   9 
## 101  13   7   0   1  10  15   0   0   2

Reduksi kategori dilakukan pada variabel Keadaan_Cuaca dengan mengelompokkan nilai numerik ke dalam interval 10 satuan. Pengelompokan tersebut menghasilkan kategori berlabel 0 sampai 9. Tahapan ini bertujuan menyederhanakan representasi nilai Keadaan_Cuaca agar dapat diproses sebagai fitur kategorik dalam tahapan encoding berikutnya. Variabel Keadaan_Cuaca yang asli kemudian dihapus dan digantikan dengan Keadaan_Cuaca_reduced pada data training dan testing. Distribusi kategori digunakan untuk mengetahui jumlah pengamatan pada setiap kelompok. Nilai yang berada di luar rentang interval 0 sampai 100 atau masih memiliki missing value akan menghasilkan kategori kosong, sehingga perlu diperiksa sebelum proses encoding dilakukan.

4.5 Hasil Scaling dengan Standard Scaler

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

# Menghitung parameter dari data training
mean_train <- sapply(
  X_train[list_num],
  mean,
  na.rm = TRUE
)

sd_train <- sapply(
  X_train[list_num],
  sd,
  na.rm = TRUE
)

# Memeriksa standar deviasi
if (any(!is.finite(sd_train)) || any(sd_train == 0)) {
  stop("Terdapat standar deviasi nol atau tidak valid.")
}

# Scaling data training
X_train_scaled <- X_train

for (i in list_num) {
  X_train_scaled[[i]] <-
    (X_train[[i]] - mean_train[i]) / sd_train[i]
}

# Scaling data testing dengan parameter training
X_test_scaled <- X_test

for (i in list_num) {
  X_test_scaled[[i]] <-
    (X_test[[i]] - mean_train[i]) / sd_train[i]
}

# Memeriksa hasil scaling
cat("Rata-rata training setelah scaling:\n")
## Rata-rata training setelah scaling:
print(sapply(X_train_scaled[list_num], mean))
##            Suhu      Kelembapan Kecepatan_Angin 
##   -7.045562e-17    5.923146e-16   -7.005936e-17
cat("\nStandar deviasi training setelah scaling:\n")
## 
## Standar deviasi training setelah scaling:
print(sapply(X_train_scaled[list_num], sd))
##            Suhu      Kelembapan Kecepatan_Angin 
##               1               1               1
# Melihat beberapa hasil transformasi
head(X_train_scaled[list_num])
## # A tibble: 6 × 3
##      Suhu Kelembapan Kecepatan_Angin
##     <dbl>      <dbl>           <dbl>
## 1 -1.39        0.973          -0.693
## 2 -1.00        0.540          -0.693
## 3  0.0947     -0.585          -0.693
## 4  1.19       -1.88           -1.03 
## 5  1.66       -2.40            0.646
## 6  1.50       -2.32            1.32

Standard Scaler diterapkan pada variabel Suhu, Kelembapan, dan Kecepatan_Angin untuk menyetarakan skala pengukuran antarvariabel numerik. Metode ini mengubah nilai setiap variabel dengan mengurangi nilai rata-rata dan membaginya dengan standar deviasi. Hasil transformasi menghasilkan variabel dengan rata-rata mendekati 0 dan standar deviasi mendekati 1 pada data training. Parameter rata-rata dan standar deviasi dihitung hanya dari data training, kemudian digunakan kembali untuk mentransformasi data testing. Pendekatan tersebut dilakukan agar informasi dari data testing tidak digunakan dalam penentuan parameter scaling. Nilai hasil transformasi yang positif menunjukkan pengamatan berada di atas rata-rata data training, sedangkan nilai negatif menunjukkan pengamatan berada di bawah rata-rata. Standard Scaler menyetarakan skala data, tetapi tidak menghilangkan outlier secara langsung.

4.6 Hasil Encoding Keadaan_Cuaca

library(recipes)

# Mengubah hasil reduksi menjadi factor
X_train_scaled$Keadaan_Cuaca_reduced <- factor(
  X_train_scaled$Keadaan_Cuaca_reduced,
  levels = labels
)

X_test_scaled$Keadaan_Cuaca_reduced <- factor(
  X_test_scaled$Keadaan_Cuaca_reduced,
  levels = labels
)

# Membuat recipe encoding
resep_encode <- recipe(
  ~ .,
  data = X_train_scaled
) %>%
  step_unknown(
    Keadaan_Cuaca_reduced,
    new_level = "unknown"
  ) %>%
  step_dummy(
    Keadaan_Cuaca_reduced,
    one_hot = TRUE
  )

# Melatih recipe dengan data training
resep_encode_prep <- prep(
  resep_encode,
  training = X_train_scaled
)

# Menerapkan encoding
X_train_encoded <- bake(
  resep_encode_prep,
  new_data = X_train_scaled
)

X_test_encoded <- bake(
  resep_encode_prep,
  new_data = X_test_scaled
)

# Memeriksa ukuran dan missing value
cat("Ukuran data training setelah encoding:",
    dim(X_train_encoded), "\n")
## Ukuran data training setelah encoding: 594 14
cat("Ukuran data testing setelah encoding:",
    dim(X_test_encoded), "\n")
## Ukuran data testing setelah encoding: 149 14
cat("Missing value training:",
    sum(is.na(X_train_encoded)), "\n")
## Missing value training: 0
cat("Missing value testing:",
    sum(is.na(X_test_encoded)), "\n")
## Missing value testing: 0
# Memeriksa nama variabel hasil encoding
names(X_train_encoded)
##  [1] "Suhu"                          "Kelembapan"                   
##  [3] "Kecepatan_Angin"               "Keadaan_Cuaca_reduced_X0"     
##  [5] "Keadaan_Cuaca_reduced_X1"      "Keadaan_Cuaca_reduced_X2"     
##  [7] "Keadaan_Cuaca_reduced_X3"      "Keadaan_Cuaca_reduced_X4"     
##  [9] "Keadaan_Cuaca_reduced_X5"      "Keadaan_Cuaca_reduced_X6"     
## [11] "Keadaan_Cuaca_reduced_X7"      "Keadaan_Cuaca_reduced_X8"     
## [13] "Keadaan_Cuaca_reduced_X9"      "Keadaan_Cuaca_reduced_unknown"

Encoding dilakukan untuk mengubah variabel Keadaan_Cuaca_reduced yang berbentuk kategori menjadi representasi numerik agar dapat digunakan dalam proses pemodelan machine learning. Sebelum proses tersebut, kategori diubah menjadi tipe factor. Fungsi step_unknown() digunakan untuk menangani nilai kategori yang hilang dengan menyediakan kategori khusus bernama unknown, sedangkan step_dummy() digunakan untuk membentuk variabel indikator dari kategori yang tersedia. Pada syntax ini, parameter encoding dipelajari menggunakan data training melalui fungsi prep(). Hasilnya kemudian diterapkan pada data training dan testing menggunakan bake(). Penggunaan resep yang sama menjaga agar kedua bagian data memiliki struktur fitur yang konsisten. Pemeriksaan ukuran data dan jumlah missing value dilakukan untuk memastikan hasil transformasi dapat digunakan pada tahap berikutnya.

4.7 Hasil Pemeriksaan Keseimbangan Kelas

# Distribusi kelas sebelum SMOTE
cat("Distribusi kelas Hujan pada data training:\n")
## Distribusi kelas Hujan pada data training:
print(table(y_train))
## y_train
##   1   2 
## 131 463
cat("\nPersentase masing-masing kelas:\n")
## 
## Persentase masing-masing kelas:
print(round(prop.table(table(y_train)) * 100, 2))
## y_train
##     1     2 
## 22.05 77.95

Pemeriksaan keseimbangan kelas dilakukan terhadap variabel Hujan pada data training. Berdasarkan dataset awal, kelas 1 berjumlah 164 observasi atau sekitar 22,07%, sedangkan kelas 2 berjumlah 579 observasi atau sekitar 77,93%. Perbedaan proporsi tersebut menunjukkan bahwa kelas 2 lebih dominan dibandingkan kelas 1. Ketidakseimbangan kelas dapat menyebabkan model lebih cenderung mempelajari kelas yang memiliki jumlah observasi lebih besar. Kondisi tersebut perlu diperhatikan, terutama apabila tujuan analisis adalah memperoleh kemampuan klasifikasi yang baik pada kedua kelas. Oleh karena itu, SMOTE diterapkan pada data training untuk meningkatkan jumlah pengamatan pada kelas minoritas melalui pembentukan data sintetis.

4.8 Hasil SMOTE

library(themis)

# Menggabungkan prediktor hasil encoding dan target
train_full <- X_train_encoded %>%
  mutate(Hujan = factor(y_train))

# Distribusi kelas sebelum SMOTE
cat("Distribusi kelas sebelum SMOTE:\n")
## Distribusi kelas sebelum SMOTE:
print(table(train_full$Hujan))
## 
##   1   2 
## 131 463
cat("\nPersentase sebelum SMOTE:\n")
## 
## Persentase sebelum SMOTE:
print(round(prop.table(table(train_full$Hujan)) * 100, 2))
## 
##     1     2 
## 22.05 77.95
# Membuat recipe SMOTE
set.seed(42)

resep_smote <- recipe(
  Hujan ~ .,
  data = train_full
) %>%
  step_smote(
    Hujan,
    over_ratio = 1,
    neighbors = 5
  )

# Menerapkan SMOTE pada data training
resep_smote_prep <- prep(
  resep_smote,
  training = train_full
)

train_balanced <- bake(
  resep_smote_prep,
  new_data = NULL
)

# Distribusi kelas setelah SMOTE
cat("\nDistribusi kelas setelah SMOTE:\n")
## 
## Distribusi kelas setelah SMOTE:
print(table(train_balanced$Hujan))
## 
##   1   2 
## 463 463
cat("\nPersentase setelah SMOTE:\n")
## 
## Persentase setelah SMOTE:
print(round(
  prop.table(table(train_balanced$Hujan)) * 100, 2
))
## 
##  1  2 
## 50 50
# Memisahkan kembali prediktor dan target
X_train_balanced <- dplyr::select(
  train_balanced,
  -Hujan
)

y_train_balanced <- train_balanced$Hujan

SMOTE (Synthetic Minority Over-sampling Technique) diterapkan untuk mengatasi ketidakseimbangan kelas pada data training. Metode ini membentuk pengamatan sintetis pada kelas minoritas berdasarkan kedekatan karakteristik antarobservasi, bukan sekadar menyalin pengamatan yang sudah tersedia. Pada syntax tersebut, parameter over_ratio = 1 digunakan untuk menargetkan keseimbangan kelas minoritas terhadap kelas mayoritas, sedangkan neighbors = 5 menentukan jumlah tetangga yang digunakan dalam pembentukan data sintetis. Distribusi kelas sebelum dan sesudah SMOTE dibandingkan untuk mengetahui perubahan jumlah pengamatan pada setiap kelas. Keberhasilan penyeimbangan ditunjukkan apabila proporsi kelas minoritas meningkat dan kedua kelas mencapai distribusi yang seimbang sesuai dengan kondisi data dan parameter yang digunakan. SMOTE hanya diterapkan pada data training, sedangkan data testing tetap dipertahankan dalam distribusi aslinya agar evaluasi model mencerminkan kondisi data yang tidak digunakan selama pelatihan.

4.9 Hasil Akhir Preprocessing

# Ringkasan ukuran data
cat("RINGKASAN HASIL PREPROCESSING\n")
## RINGKASAN HASIL PREPROCESSING
cat("Jumlah data awal       :", nrow(data), "\n")
## Jumlah data awal       : 743
cat("Data training awal     :", nrow(train_data), "\n")
## Data training awal     : 594
cat("Data testing           :", nrow(test_data), "\n")
## Data testing           : 149
cat("Training setelah SMOTE :", nrow(train_balanced), "\n")
## Training setelah SMOTE : 926
# Memeriksa missing value setelah SMOTE
cat("\nMissing value training setelah SMOTE:\n")
## 
## Missing value training setelah SMOTE:
print(sapply(train_balanced, function(x) sum(is.na(x))))
##                          Suhu                    Kelembapan 
##                             0                             0 
##               Kecepatan_Angin      Keadaan_Cuaca_reduced_X0 
##                             0                             0 
##      Keadaan_Cuaca_reduced_X1      Keadaan_Cuaca_reduced_X2 
##                             0                             0 
##      Keadaan_Cuaca_reduced_X3      Keadaan_Cuaca_reduced_X4 
##                             0                             0 
##      Keadaan_Cuaca_reduced_X5      Keadaan_Cuaca_reduced_X6 
##                             0                             0 
##      Keadaan_Cuaca_reduced_X7      Keadaan_Cuaca_reduced_X8 
##                             0                             0 
##      Keadaan_Cuaca_reduced_X9 Keadaan_Cuaca_reduced_unknown 
##                             0                             0 
##                         Hujan 
##                             0
# Membandingkan distribusi kelas
cat("\nDistribusi kelas sebelum SMOTE:\n")
## 
## Distribusi kelas sebelum SMOTE:
print(table(train_full$Hujan))
## 
##   1   2 
## 131 463
cat("\nDistribusi kelas setelah SMOTE:\n")
## 
## Distribusi kelas setelah SMOTE:
print(table(train_balanced$Hujan))
## 
##   1   2 
## 463 463
# Memeriksa ukuran akhir prediktor dan target
cat("\nUkuran prediktor training setelah SMOTE:\n")
## 
## Ukuran prediktor training setelah SMOTE:
print(dim(X_train_balanced))
## [1] 926  14
cat("\nJumlah target training setelah SMOTE:\n")
## 
## Jumlah target training setelah SMOTE:
print(length(y_train_balanced))
## [1] 926
cat("\nUkuran prediktor testing:\n")
## 
## Ukuran prediktor testing:
print(dim(X_test_encoded))
## [1] 149  14
cat("\nJumlah target testing:\n")
## 
## Jumlah target testing:
print(length(y_test))
## [1] 149

Berdasarkan rangkaian preprocessing yang telah dilakukan, data curah hujan melalui tahapan penanganan missing value, penanganan outlier menggunakan capping, pembagian data secara stratified splitting, reduksi kategori Keadaan_Cuaca, scaling menggunakan Standard Scaler, encoding, dan penyeimbangan kelas menggunakan SMOTE. Setiap tahapan memiliki tujuan yang berbeda dalam mempersiapkan data agar dapat digunakan untuk proses pemodelan machine learning. Hasil akhir diperiksa melalui ukuran data, jumlah missing value, serta distribusi kelas sebelum dan sesudah SMOTE. Data training hasil SMOTE menjadi data yang digunakan untuk melatih model, sedangkan data testing tetap digunakan sebagai data evaluasi. Pemeriksaan tersebut penting untuk memastikan bahwa tahapan transformasi telah berjalan sesuai tujuan dan bahwa variabel prediktor serta target memiliki jumlah observasi yang konsisten.

BAB V KESIMPULAN

5.1 Kesimpulan

Feature engineering merupakan tahapan pengolahan data yang bertujuan mempersiapkan variabel agar dapat digunakan secara lebih optimal dalam proses machine learning. Teknik yang diterapkan pada praktikum ini meliputi penanganan missing value, penanganan outlier, pembagian data, reduksi kategori, scalling, encoding, dan penanganan ketidakseimbangan kelas. Setiap teknik memiliki fungsi yang berbeda sesuai dengan karakteristik data dan kebutuhan analisis.

Penerapan feature engineering pada data curah hujan dilakukan menggunakan R melalui beberapa tahapan. Missing value pada Kecepatan_Angin ditangani menggunakan mode imputation, sedangkan Keadaan_Cuaca diproses menggunakan interpolasi linear. Penanganan outlier dilakukan menggunakan capping berdasarkan metode IQR, kemudian data dibagi menjadi data training dan testing dengan proporsi 80:20 menggunakan stratified splitting. Variabel numerik ditransformasi menggunakan Standard Scaler, kategori Keadaan_Cuaca direduksi dan diubah melalui encoding, serta ketidakseimbangan kelas pada data training ditangani menggunakan SMOTE.

RStudio dapat digunakan untuk melaksanakan tahapan feature engineering melalui pemanfaatan berbagai paket dan fungsi yang tersedia. Pemeriksaan hasil pada setiap tahap diperlukan untuk mengetahui perubahan struktur data, jumlah missing value, sebaran nilai, serta distribusi kelas. Sehingga, penerapan feature engineering secara terstruktur dapat membantu mempersiapkan data sebelum dilakukan pemodelan dan evaluasi algoritma machine learning.

5.2 Saran

Praktikan diharapkan dapat mempelajari lebih lanjut berbagai teknik feature engineering serta memahami fungsi dan karakteristik setiap metode sebelum menerapkannya pada dataset. Pemilihan metode perlu disesuaikan dengan jenis variabel dan kondisi data agar proses pengolahan tidak mengubah makna informasi yang terkandung di dalamnya. Pemeriksaan output pada setiap tahapan juga perlu dilakukan untuk memastikan tidak terdapat kesalahan pengolahan data. Praktikan disarankan untuk berlatih menggunakan dataset lain agar lebih memahami penerapan feature engineering melalui RStudio.

DAFTAR PUSTAKA

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).

Fransiska, H. (2026). Modul Praktikum Machine Learning dan Model Prediction. Universitas Bengkulu: Bengkulu.

Nurhalizah, R. S., Ardianto, R., Purwono. (2024). Analisis Supervised dan Unsupervised Learning pada Machine Learning: Systematic Literature Review. Jurnal Ilmu Komputer dan Informatika (JIKI), 4(1), 61-74.