Analisis data menggunakan machine learning perlu memperhatikan kondisi data sebelum model dibangun. Data mentah tidak selalu dapat langsung digunakan. Diperlukan tahap pengolahan awal agar karakteristik data sesuai dengan kebutuhan metode yang digunakan. Pengolahan awal tersebut terdiri atas preprocessing dan feature engineering. Preprocessing mencakup penanganan nilai hilang dan pencilan, sedangkan feature engineering mencakup pembentukan atau perubahan representasi variabel agar informasi dalam data dapat dimanfaatkan oleh model. Teknik yang umum digunakan antara lain pengelompokan kategori untuk mengurangi kardinalitas, penskalaan variabel numerik, dan pengodean (encoding) variabel kategorik. Pemilihan teknik perlu mempertimbangkan tipe variabel, kondisi data, dan tujuan analisis karena setiap teknik memiliki fungsi yang berbeda. RStudio merupakan bahasa pemrograman yang dapat memeriksa struktur data, melakukan transformasi, serta menyajikan hasil dalam bentuk tabel dan grafik. Penggunaan sintaks juga memungkinkan setiap langkah analisis dicatat dan dijalankan ulang sehingga prosesnya dapat ditelusuri dan direproduksi. Berdasarkan uraian tersebut, praktikum ini membahas konsep berbagai teknik feature engineering serta penerapannya menggunakan RStudio sebagai dasar untuk mempersiapkan data sebelum digunakan dalam pemodelan machine learning
Machine learning merupakan salah satu cabang kecerdasan buatan (artificial intelligence/AI) yang mempelajari pengembangan algoritma agar komputer dapat belajar dari data, lalu menghasilkan prediksi atau keputusan tanpa perlu diprogram secara eksplisit. Tujuan utamanya adalah membangun sistem yang kinerjanya terus membaik seiring bertambahnya pengalaman, yang dalam hal ini berupa data (Hartono 2021). Secara umum, machine learning dipahami sebagai bidang studi yang membekali sistem komputer dengan kemampuan untuk belajar dan memperbaiki kinerjanya dari pengalaman, tanpa harus diprogram secara khusus untuk setiap tugas. Inti dari machine learning terletak pada kemampuan adaptif sistem untuk meningkatkan performanya seiring data yang terus berkembang. Machine learning (ML) mencakup bidang yang luas dengan beragam pendekatan untuk menyelesaikan berbagai jenis permasalahan. Berdasarkan cara data digunakan dan cara model belajar, ML dapat dikelompokkan menjadi empat kategori utama, yaitu supervised learning, unsupervised learning, semi-supervised learning, dan reinforcement learning. Setiap kategori memiliki karakteristik, metode, dan penerapan yang berbeda (Bintoro et al. 2024).
Feature engineering merupakan proses memanfaatkan pengetahuan domain untuk mengekstrak atau membentuk fitur baru dari data mentah. Tahap ini penting karena kinerja model machine learning sangat dipengaruhi oleh kualitas fitur masukan (Darmawan dkk., 2026). Dalam prosesnya, data mentah diubah menjadi fitur yang dapat digunakan oleh algoritma, dan variabel yang paling berpengaruh dipilih serta direkayasa untuk pemodelan. Proses ini menuntut pemahaman yang baik karena memadukan analisis data, pengetahuan tentang data, dan sedikit intuisi. Tujuannya adalah menyederhanakan dan mempercepat transformasi data sekaligus meningkatkan akurasi model, sebab kualitas fitur jauh lebih menentukan daripada kecanggihan algoritma yang dipilih. Beberapa jenis feature engineering yang perlu dilakukan adalah sebagai berikut (Fransiska, 2026):
Missing value atau data hilang terjadi ketika tidak ada nilai yang tersimpan untuk suatu observasi pada sebuah variabel. Kondisi ini umum dijumpai dan dapat berdampak besar pada pemodelan machine learning. Data yang tidak lengkap hampir tidak mungkin dihindari pada sebagian besar sumber data.
Kardinalitas adalah jumlah nilai unik atau label dalam sebuah variabel kategorik, dan digunakan untuk mengukur tingkat granularitas atau keunikan data pada suatu fitur. Kardinalitas umumnya dibedakan menjadi rendah (low cardinality) dan tinggi (high cardinality). Pengaruhnya sangat besar terhadap kinerja model dan efisiensi komputasi. Pertama, variabel berkardinalitas tinggi dapat memicu curse of dimensionality bila ditransformasi dengan metode encoding standar seperti One-Hot Encoding. Metode tersebut membentuk banyak fitur biner baru sesuai jumlah label sehingga data menjadi sangat jarang (sparse) dan kompleksitas komputasi meningkat tajam. Kedua, kardinalitas yang tinggi memperbesar risiko overfitting. Banyak label hanya muncul beberapa kali pada data latih, sehingga model cenderung menghafal pola khusus dari label langka tersebut dan gagal mempelajari pola umum yang dapat digeneralisasi ke data baru.
Splitting data adalah strategi mendasar dalam machine learning untuk membagi himpunan data menjadi data latih (training) dan data uji (testing).
Outlier atau pencilan adalah observasi yang menyimpang ekstrem dan berbeda nyata dari sebagian besar data lain dalam suatu himpunan data. Pencilan dapat bersumber dari kesalahan pengukuran, kesalahan input data, kontaminasi data, hingga representasi sah dari kejadian langka atau variabilitas alami populasi. Dalam analisis statistik dan pemodelan machine learning, pencilan perlu mendapat perhatian khusus karena berpotensi memberikan pengaruh yang tidak proporsional terhadap hasil.
Scaling data adalah langkah pra-pemrosesan yang mentransformasi variabel ke rentang skala yang sama. Tujuannya agar tidak ada variabel independen yang mendominasi proses pembelajaran semata-mata karena rentang nilainya lebih besar.
Feature encoding adalah proses mengubah fitur kategorik atau non-numerik menjadi format numerik agar dapat menjadi masukan bagi algoritma machine learning, karena banyak algoritma mensyaratkan masukan numerik. Dua teknik yang umum digunakan adalah One-Hot Encoding dan Ordinal Encoding.
Imbalanced dataset adalah dataset dengan distribusi kelas yang tidak setara. Kelas yang mencakup proporsi besar disebut kelas mayoritas, sedangkan kelas dengan proporsi lebih kecil disebut kelas minoritas.
Jenis data yang digunakan dalam penelitian ini berupa data kuantitatif dan data kualitatif. Data kuantitatif adalah jenis data yang dapat diukur (measurable) atau dihitung secara langsung sebagai variabel angka. Data kualitatif merupakan data yang tidak dapat diukur atau dihitung dengan angka yang bertujuan untuk menjabarkan data analisis secara naratif. Sumber data yang digunakan dalam penelitian ini yaitu data sekunder. Data sekunder adalah data yang diperoleh secara tidak langsung oleh peneliti melainkan melalui prantara. Data sekunder dalam penelitian ini diperoleh dari dari Asisten Praktikum.
Variabel adalah objek penelitian atau apa yang menjadi titik perhatian. Dalam penelitian ini terdapat beberapa variabel. Variabel yang digunakan dalam penelitian ini adalah variabel hujan, suhu, kelembapan, keadaan cuaca dan kecepatan angin.
Langkah-langkah analisis yang dilakukan adalah:
Input data curah hujan ke RStudio.
Melakukan pemeriksaan dan preprocessing data.
Mengisi nilai hilang menggunakan mean imputation pada Kecepatan_Angin dan interpolasi pada Keadaan_Cuaca.
Mengelompokkan nilai Keadaan_Cuaca untuk mengurangi kardinalitas.
Membagi data menjadi 80% data latih dan 20% data uji menggunakan shuffle splitting.
Mendeteksi pencilan dengan metode IQR dan menanganinya menggunakan capping.
Melakukan penskalaan prediktor numerik menggunakan Robust Scaler.
Mengubah kelompok Keadaan_Cuaca menggunakan one-hot encoding.
Menyeimbangkan kelas Hujan pada data latih menggunakan SMOTE.
Menampilkan dan menginterpretasikan hasil setiap tahap.
kolom kotak abu ini bagian tempat kalian menuliskan sintaksnya ya, sedangkan tombol pause warna hijau dikanan atas itu untuk runingnya tapi bisa jg makai ctrl+enter
##
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
## ── 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
##
## Attaching package: 'e1071'
##
## The following object is masked from 'package:rsample':
##
## permutations
##
## The following object is masked from 'package:ggplot2':
##
## element
##
## Attaching package: 'gridExtra'
##
## The following object is masked from 'package:dplyr':
##
## combine
##
## Attaching package: 'recipes'
##
## The following object is masked from 'package:stringr':
##
## fixed
##
## The following object is masked from 'package:stats':
##
## step
## 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
## # A tibble: 6 × 5
## Hujan Suhu Kelembapan Keadaan_Cuaca Kecepatan_Angin
## <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1 23 95 5 NA
## 2 1 24 90 1 NA
## 3 1 26.8 77 1 NA
## 4 1 29.6 62 2 2
## 5 1 30.8 56 1 7
## 6 1 31 55 1 7
## tibble [743 × 5] (S3: tbl_df/tbl/data.frame)
## $ Hujan : num [1:743] 1 1 1 1 1 1 1 2 2 2 ...
## $ Suhu : num [1:743] 23 24 26.8 29.6 30.8 31 30.4 30.9 30.2 29.7 ...
## $ Kelembapan : num [1:743] 95 90 77 62 56 55 57 58 62 62 ...
## $ Keadaan_Cuaca : num [1:743] 5 1 1 2 1 1 3 2 2 2 ...
## $ Kecepatan_Angin: num [1:743] NA NA NA 2 7 7 9 10 8 7 ...
Data yang digunakan terdiri atas 743 observasi dan 5 variabel. Berdasarkan pemeriksaan awal, seluruh variabel masih tersimpan dalam tipe numerik. Variabel Hujan merupakan variabel kategorik dengan 2 kategori, sehingga perlu diubah terlebih dahulu menjadi tipe factor agar dapat dianalisis dengan benar.
## tibble [743 × 5] (S3: tbl_df/tbl/data.frame)
## $ Hujan : Factor w/ 2 levels "1","2": 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 ...
## Hujan Suhu Kelembapan Keadaan_Cuaca Kecepatan_Angin
## 1:164 Min. :22.60 Min. : 52.00 Min. : 1.00 Min. : 2.000
## 2:579 1st Qu.:24.30 1st Qu.: 75.00 1st Qu.: 2.00 1st Qu.: 4.000
## Median :26.00 Median : 86.00 Median : 2.00 Median : 6.000
## Mean :26.54 Mean : 83.88 Mean :15.11 Mean : 6.655
## 3rd Qu.:28.90 3rd Qu.: 94.00 3rd Qu.:15.00 3rd Qu.: 9.000
## Max. :32.00 Max. :100.00 Max. :97.00 Max. :21.000
## NAs :9 NAs :314
Variabel Hujan terdiri atas kategori 1 sebanyak 164 observasi dan kategori 2 sebanyak 579 observasi, sehingga distribusi kelas tidak seimbang karena didominasi oleh kategori 2. Suhu berkisar antara 22,60–32,00 dengan rata-rata 26,54, sedangkan Kelembapan berkisar antara 52–100 dengan rata-rata 83,88. Kecepatan_Angin berkisar antara 2–21 dengan rata-rata 6,655 berdasarkan nilai yang tersedia. Terdapat missing value pada Keadaan_Cuaca sebanyak 9 observasi dan Kecepatan_Angin sebanyak 314 observasi. Kondisi ini menunjukkan bahwa data memerlukan tahap Feature engineering sebelum dilakukan pemodelan.
## Hujan Suhu Kelembapan Keadaan_Cuaca Kecepatan_Angin
## 0 0 0 9 314
## Hujan Suhu Kelembapan Keadaan_Cuaca Kecepatan_Angin
## 0.00000000 0.00000000 0.00000000 0.01211306 0.42261104
# Penanganan Missing Value menggunakan Mean Imputation
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
# Penanganan Missing Value menggunakan Interpolasi
df_imp$Keadaan_Cuaca <- na.approx(df_imp$Keadaan_Cuaca, na.rm = FALSE)
colSums(is.na(df_imp))## Hujan Suhu Kelembapan Keadaan_Cuaca Kecepatan_Angin
## 0 0 0 0 0
Terdapat dua variabel yang memiliki missing value, yaitu Kecepatan_Angin dan Keadaan_Cuaca. Nilai hilang pada Kecepatan_Angin ditangani menggunakan mean imputation, yaitu diisi dengan rata-rata nilai yang tersedia. Sementara itu, nilai hilang pada Keadaan_Cuaca ditangani menggunakan interpolasi linear, yaitu diisi dengan nilai yang dihitung berdasarkan nilai sebelum dan sesudahnya sesuai urutan pengamatan.
## [1] 5 1 1 2 1 1 3 2 2 2
## [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
# 1. Tentukan batas bin
bins <- c(0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100)
# 2. Tentukan label untuk setiap bin (10 label: 0 s/d 9)
labels <- 0:9
# 3. Terapkan cut()
df_imp$Keadaan_Cuaca_reduced <- cut(
df_imp$Keadaan_Cuaca,
breaks = bins,
labels = labels,
right = TRUE,
include.lowest = TRUE)
# 4. Verifikasi
cat("--- Hasil Perbandingan ---\n")## --- Hasil Perbandingan ---
## # A tibble: 10 × 6
## Hujan Suhu Kelembapan Keadaan_Cuaca Kecepatan_Angin Keadaan_Cuaca_reduced
## <fct> <dbl> <dbl> <dbl> <dbl> <fct>
## 1 2 28 82 2 5 0
## 2 1 29 72 3 6.66 0
## 3 2 26.8 82 2 2 0
## 4 1 23.4 91 2 6.66 0
## 5 2 23.4 97 21 6.66 2
## 6 2 26.6 89 2 2 0
## 7 2 25.4 92 2 6.66 0
## 8 2 25.9 90 16 6.66 1
## 9 2 29.5 74 60 12 5
## 10 2 30 69 2 11 0
##
## --- Pengecekan Kardinalitas ---
## Jumlah kategori di "Keadaan_Cuaca" asli : 23
cat('Jumlah kategori di "Keadaan_Cuaca_reduced" :', length(unique(df_imp$Keadaan_Cuaca_reduced)), "\n")## Jumlah kategori di "Keadaan_Cuaca_reduced" : 7
##
## Kategori unik yang baru (reduced):
## [1] 0 1 5 6 2 9 4
## Levels: 0 1 2 3 4 5 6 7 8 9
Pengurangan kardinalitas pada variabel Keadaan_Cuaca dilakukan dengan mengelompokkan nilai ke dalam 10 interval berlebar 10 yang diberi label 0 hingga 9. Sebelum pengelompokan, variabel tersebut memiliki 23 nilai unik. Proses ini menyederhanakan variasi nilai Keadaan_Cuaca sehingga jumlah kategori yang digunakan pada tahap one-hot encoding menjadi lebih sedikit.
# Splitting Data Menggunakan Shuffle Splitting
set.seed(200)
split_shuffle <- initial_split(df_imp, prop = 0.8)
X_train <- training(split_shuffle) %>% select(-Hujan)
X_test <- testing(split_shuffle) %>% select(-Hujan)
y_train <- training(split_shuffle)$Hujan
y_test <- testing(split_shuffle)$Hujan
dim(X_train)## [1] 594 5
Pembagian data dilakukan menggunakan shuffle splitting,
yaitu membagi 743 observasi secara acak dengan proporsi 80% untuk data
latih dan 20% untuk data uji. Hasil pembagian menghasilkan 594 observasi
data latih dan 149 observasi data uji. Penggunaan
set.seed(200) bertujuan agar hasil pembagian acak dapat
diulang.
## Handling Outlier
# Buat list fitur numerik
list_num <- c("Suhu", "Kelembapan", "Kecepatan_Angin")
# Siapkan wadah kosong untuk menampung hasil
list_outlier <- c()
list_lower_bound <- c()
list_upper_bound <- c()
# Hitung IQR untuk setiap kolom
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
# Tentukan batas bawah dan batas atas untuk outlier
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)
# Hitung jumlah outlier di bawah batas bawah dan di atas batas atas
num_outliers_lower <- sum(X_train[[i]] < lower_bound, na.rm = TRUE)
num_outliers_upper <- sum(X_train[[i]] > upper_bound, na.rm = TRUE)
# Jumlah total outlier
total_outliers <- num_outliers_lower + num_outliers_upper
list_outlier <- c(list_outlier, total_outliers)
}
# Mendefinisikan dataframe baru mengenai 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
# Ambil nilai lower dan upper berdasarkan baris 'Kecepatan_Angin'
outliers_indexed <- outliers %>% filter(Kolom == "Kecepatan_Angin")
lower_kecepatan <- outliers_indexed$Lower_Bound
upper_kecepatan <- outliers_indexed$Upper_BoundBerdasarkan metode IQR, batas bawah dan batas atas pencilan pada variabel Suhu adalah 17,4 dan 35,8, sedangkan pada Kelembapan adalah 46,5 dan 122,5. Tidak ditemukan pencilan pada kedua variabel karena seluruh nilai data latih berada dalam batas tersebut. Pada variabel Kecepatan_Angin, batas bawah sebesar 2 dan batas atas sebesar 10, dengan 50 observasi berada di luar rentang tersebut. Nilai yang kurang dari batas bawah atau lebih dari batas atas dikategorikan sebagai pencilan dan selanjutnya ditangani menggunakan capping.
# Handling Outlier dengan Capping
X_train_capped <- X_train
X_train_capped$Kecepatan_Angin <- Winsorize(
X_train$Kecepatan_Angin,
val = c(lower_kecepatan, upper_kecepatan)
)
X_test_capped <- X_test
X_test_capped$Kecepatan_Angin <- Winsorize(
X_test$Kecepatan_Angin,
val = c(lower_kecepatan, upper_kecepatan)
)
diagnostic_plots <- function(df, variable) {
p1 <- ggplot(df, aes(x = .data[[variable]])) +
geom_histogram(bins = 30, fill = "#008080", color = "black") +
ggtitle("Histogram") +
theme_minimal()
p2 <- ggplot(df, aes(y = .data[[variable]])) +
geom_boxplot(fill = "#008080") +
ggtitle("Boxplot") +
theme_minimal()
grid.arrange(p1, p2, ncol = 2)
}
for (col in list_num) {
cat(col, "- Before Capping\n")
diagnostic_plots(X_train, col)
cat("\n", col, "- After Capping\n")
diagnostic_plots(X_train_capped, col)
}## Suhu - Before Capping
##
## Suhu - After Capping
## Kelembapan - Before Capping
##
## Kelembapan - After Capping
## Kecepatan_Angin - Before Capping
##
## Kecepatan_Angin - After Capping
Penanganan pencilan dilakukan menggunakan metode capping pada variabel Kecepatan_Angin dengan fungsi Winsorize(). Nilai di bawah batas bawah 2 diganti menjadi 2, sedangkan nilai di atas batas atas 10 diganti menjadi 10. Nilai dalam rentang tersebut tetap dipertahankan. Batas yang diperoleh dari data latih diterapkan pada data latih dan data uji tanpa mengurangi jumlah observasi.
Sebelum dilakukan capping, histogram dan boxplot Kecepatan_Angin memperlihatkan nilai ekstrem pada bagian atas distribusi. Nilai tersebut menyebabkan sebaran data memanjang ke arah nilai yang lebih tinggi. Setelah capping, rentang nilai menjadi lebih terbatas karena nilai yang melebihi batas atas telah disesuaikan, sehingga penyebaran pada bagian atas distribusi berkurang. Sementara itu, pola distribusi Suhu dan Kelembapan tetap sama karena tidak terdapat nilai di luar batas pencilan yang ditentukan.
## Scaling menggunakan Robust Scaler
list_num <- c("Suhu", "Kelembapan", "Kecepatan_Angin")
# Menghitung median dan IQR dari data latih
median_val <- sapply(X_train_capped[list_num], median, na.rm = TRUE)
iqr_val <- sapply(X_train_capped[list_num], IQR, na.rm = TRUE)
# Menghindari pembagian dengan nol
iqr_val[iqr_val == 0] <- 1
# Menyimpan hasil scaling pada objek baru
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]
}
for (col in list_num) {
X_test_scale[[col]] <- (
X_test_capped[[col]] - median_val[col]
) / iqr_val[col]
}
# Menampilkan hasil scaling
head(X_train_scale)## # 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
## 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
Penskalaan menggunakan Robust Scaler dilakukan pada variabel Suhu, Kelembapan, dan Kecepatan_Angin dengan mengurangi setiap nilai menggunakan median dan membaginya dengan IQR data latih. Hasil penskalaan menunjukkan bahwa ketiga variabel memiliki median sebesar 0 dan IQR sebesar 1. Nilai negatif menunjukkan pengamatan di bawah median, sedangkan nilai positif menunjukkan pengamatan di atas median. Rentang nilai Suhu setelah penskalaan adalah −0,7391 hingga 1,2174, Kelembapan −1,7895 hingga 0,7368, dan Kecepatan_Angin −2,3275 hingga 1,6725. Parameter yang sama diterapkan pada data uji agar proses penskalaan konsisten.
## One-Hot Encoding
list_cat <- c("Keadaan_Cuaca_reduced")
# Buang kode cuaca asli karena sudah diganti versi reduced
train_encode <- X_train_scale %>% select(-Keadaan_Cuaca)
test_encode <- X_test_scale %>% select(-Keadaan_Cuaca)
# Pelajari encoding dari data latih
resep_encode <- recipe(~ ., data = train_encode) %>%
step_dummy(all_of(list_cat), one_hot = TRUE) %>%
prep(training = train_encode)
# Terapkan pada data latih dan data uji
X_train_encoded <- bake(resep_encode, new_data = NULL)
X_test_encoded <- bake(resep_encode, new_data = test_encode)
# Tampilkan hasil
head(X_train_encoded)## # 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>
## # A tibble: 6 × 13
## Suhu Kelembapan Kecepatan_Angin Keadaan_Cuaca_reduced_X0
## <dbl> <dbl> <dbl> <dbl>
## 1 -0.652 0.474 0 1
## 2 1.09 -1.63 0.172 1
## 3 1.07 -1.47 1.67 1
## 4 0.565 -0.684 -0.828 1
## 5 -0.304 0.211 0 1
## 6 0.0652 -0.316 0 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>
## [1] 594 13
## [1] 149 13
Setelah dilakukan one-hot encoding, variabel Keadaan_Cuaca_reduced diubah menjadi 10 kolom yang bernilai 0 atau 1. Nilai 1 menunjukkan bahwa suatu observasi termasuk dalam kategori tersebut, sedangkan nilai 0 menunjukkan sebaliknya. Bersama tiga variabel numerik yang tetap digunakan, jumlah variabel prediktor menjadi 13. Data latih terdiri atas 594 observasi dan data uji terdiri atas 149 observasi.
## y_train
## 1 2
## 128 466
train_full <- X_train_encoded %>%
mutate(Hujan = y_train)
train_full$Hujan <- factor(train_full$Hujan)
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)
# Pisahkan lagi jadi X dan y
X_train_balanced <- train_balanced %>% select(-Hujan)
y_train_balanced <- train_balanced$Hujan
table(y_train_balanced)## y_train_balanced
## 1 2
## 466 466
# Visualisasi sebelum dan sesudah SMOTE
par(mfrow = c(1, 2))
barplot(
table(y_train),
main = "Sebelum SMOTE",
xlab = "Kelas Hujan",
ylab = "Frekuensi",
col = "skyblue"
)
barplot(
table(y_train_balanced),
main = "Setelah SMOTE",
xlab = "Kelas Hujan",
ylab = "Frekuensi",
col = "lightgreen"
)
Sebelum penerapan SMOTE, data latih terdiri atas 128 observasi kategori
1 dan 466 observasi kategori 2, sehingga jumlah kedua kelas tidak
seimbang. SMOTE menambahkan 338 observasi sintetis pada kategori 1
hingga jumlahnya sama dengan kategori 2. Setelah proses tersebut,
masing-masing kategori memiliki 466 observasi, dengan total data latih
sebanyak 932 observasi. Dengan demikian, ketidakseimbangan kelas pada
data latih telah ditangani, sedangkan data uji tetap dipertahankan untuk
evaluasi model.
Berdasarkan batasan masalah dilakukan preprocessing data curah hujan melalui penanganan nilai hilang, pengurangan kardinalitas, pembagian data, penanganan pencilan, penskalaan, encoding, dan penyeimbangan kelas. Nilai hilang pada Kecepatan_Angin diisi menggunakan mean imputation, sedangkan pada Keadaan_Cuaca ditangani menggunakan interpolasi. Penanganan pencilan dengan capping membatasi nilai ekstrem pada Kecepatan_Angin tanpa mengurangi jumlah observasi. Selanjutnya, Robust Scaler digunakan untuk menyesuaikan skala prediktor numerik dan one-hot encoding digunakan untuk mengubah kelompok Keadaan_Cuaca menjadi kolom indikator.Pembagian menggunakan shuffle splitting menghasilkan 594 observasi data latih dan 149 observasi data uji. Setelah encoding, masing-masing data memiliki 13 variabel prediktor. Penerapan SMOTE pada data latih menghasilkan jumlah kelas yang seimbang, yaitu 466 observasi pada setiap kategori Hujan, sehingga total data latih menjadi 932 observasi.
Bintoro, P., Ratnasari, Wihardjo, E., Putri, I.P. and Asari, A. (2024). Pengantar Machine Learning. Solok: PT Mafy Media Literasi Indonesia.
Darmawan, R., dkk. (2026). Analisis Peran Feature Engineering Pada Kinerja Model Machine Learning untuk Klasifikasi Potensi Tsunami. JITET (Jurnal Informatika dan Teknik Elektro Terapan), 14(1), 236-249.
Fransiska, H. (2026). Modul Praktikum Machine Learning and Modern Prediction. Laboratorium Statistika, Universitas Bengkulu.
Hartono. (2021). Modul Digital Machine Learning. MS-SPADA Kementerian Pendidikan, Kebudayaan, Riset, dan Teknologi.