Support Vector machine (SVM) untuk Model Klasifikasi
Cahya Alkahfi | sainsdata.id
Support Vector Machine (SVM) adalah salah satu algoritma pembelajaran mesin yang populer dan serbaguna untuk tugas klasifikasi dan regresi. Algoritma ini bekerja dengan mencari hyperplane terbaik yang memisahkan kelas-kelas dalam data. Dalam tutorial ini, kita akan fokus pada penggunaan SVM untuk tugas klasifikasi menggunakan bahasa pemrograman R.
Pada tutorial ini, kita akan menggunakan metapaket
tidymodels untuk menangani setiap tahap pemodelan, mulai
dari pra-pemrosesan data, pemodelan, evaluasi hingga tuning
hyperparameter model. Pada tahap pemodelan, kita akan menggunakan engine
dari paket kernlab. Oleh karena itu, kita perlu menginstal
kedua paket tersebut untuk melanjutkan.
tidymodels adalah sekumpulan paket dalam R yang
dirancang untuk memudahkan proses analisis data dan pembuatan model
prediktif. Dengan menggunakan tidymodels, kita dapat
melakukan semua langkah pemodelan secara sistematis dan konsisten, mulai
dari membersihkan data hingga mengevaluasi performa model.
Pada tahap pemodelan, kernlab akan digunakan sebagai
engine untuk membangun model SVM. kernlab menyediakan berbagai metode
kernel dan SVM yang dapat disesuaikan dengan kebutuhan analisis kita.
Penggunaan kernlab memungkinkan kita untuk melakukan pemodelan yang
lebih fleksibel dan komprehensif.
Untuk memulai, pastikan anda telah menginstal kedua paket ini dengan perintah berikut:
# install.packages("tidymodels") # metapaket yang berisi berbagai paket untuk seluruh alur pemodelan
# install.packages("kernlabs") # paket yang digunakan sebagai engine model svm pada tidymodels
library(tidymodels)## Warning: package 'tidymodels' was built under R version 4.2.3
## ── Attaching packages ────────────────────────────────────── tidymodels 1.2.0 ──
## ✔ broom 1.0.5 ✔ recipes 1.0.10
## ✔ dials 1.2.1 ✔ rsample 1.2.1
## ✔ dplyr 1.1.4 ✔ tibble 3.2.1
## ✔ ggplot2 3.5.1 ✔ tidyr 1.3.1
## ✔ infer 1.0.7 ✔ tune 1.2.1
## ✔ modeldata 1.3.0 ✔ workflows 1.1.4
## ✔ parsnip 1.2.1 ✔ workflowsets 1.1.0
## ✔ purrr 1.0.2 ✔ yardstick 1.3.1
## Warning: package 'broom' was built under R version 4.2.3
## Warning: package 'dials' was built under R version 4.2.3
## Warning: package 'scales' was built under R version 4.2.3
## Warning: package 'dplyr' was built under R version 4.2.3
## Warning: package 'ggplot2' was built under R version 4.2.3
## Warning: package 'infer' was built under R version 4.2.3
## Warning: package 'modeldata' was built under R version 4.2.3
## Warning: package 'parsnip' was built under R version 4.2.3
## Warning: package 'purrr' was built under R version 4.2.3
## Warning: package 'recipes' was built under R version 4.2.3
## Warning: package 'rsample' was built under R version 4.2.3
## Warning: package 'tibble' was built under R version 4.2.3
## Warning: package 'tidyr' was built under R version 4.2.3
## Warning: package 'tune' was built under R version 4.2.3
## Warning: package 'workflows' was built under R version 4.2.3
## Warning: package 'workflowsets' was built under R version 4.2.3
## Warning: package 'yardstick' was built under R version 4.2.3
## ── Conflicts ───────────────────────────────────────── tidymodels_conflicts() ──
## ✖ purrr::discard() masks scales::discard()
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ✖ recipes::step() masks stats::step()
## • Dig deeper into tidy modeling with R at https://www.tmwr.org
Penyiapan Data
Pada tutorial ini, kita akan bekerja dengan Heart Disease Dataset. Dataset ini mencakup 918 observasi dan terdiri dari 11 variabel input atau fitur, yang mencakup tipe data numerik dan kategorikal. Variabel respon dalam dataset ini adalah HeartDisease, di mana nilai 0 menunjukkan kondisi normal dan nilai 1 menunjukkan adanya penyakit jantung.
Dataset ini memberikan gambaran yang komprehensif tentang berbagai faktor yang dapat mempengaruhi kesehatan jantung, dan dengan menggunakan teknik machine learning seperti SVM, kita akan mencoba membangun model yang dapat memprediksi risiko penyakit jantung berdasarkan fitur-fitur yang ada.
# memuat dataset
data <- read.csv('https://raw.githubusercontent.com/sainsdataid/dataset/main/heart.csv')
# merubah kolom respon menjadi factor
data$HeartDisease <- as.factor(data$HeartDisease)
str(data)## 'data.frame': 918 obs. of 12 variables:
## $ Age : int 40 49 37 48 54 39 45 54 37 48 ...
## $ Sex : chr "M" "F" "M" "F" ...
## $ ChestPainType : chr "ATA" "NAP" "ATA" "ASY" ...
## $ RestingBP : int 140 160 130 138 150 120 130 110 140 120 ...
## $ Cholesterol : int 289 180 283 214 195 339 237 208 207 284 ...
## $ FastingBS : int 0 0 0 0 0 0 0 0 0 0 ...
## $ RestingECG : chr "Normal" "Normal" "ST" "Normal" ...
## $ MaxHR : int 172 156 98 108 122 170 170 142 130 120 ...
## $ ExerciseAngina: chr "N" "N" "N" "Y" ...
## $ Oldpeak : num 0 1 0 1.5 0 0 0 0 1.5 0 ...
## $ ST_Slope : chr "Up" "Flat" "Up" "Flat" ...
## $ HeartDisease : Factor w/ 2 levels "0","1": 1 2 1 2 1 1 1 1 2 1 ...
##
## 0 1
## 410 508
Pra-pemrosesan Data
Tahapan pra-pemrosesan data bertujuan untuk menyiapkan data agar siap digunakan dalam pemodelan. Dalam bagian ini, kita akan melakukan dua proses utama: pembagian data dan standardisasi data.
Pembagian data adalah langkah penting yang memungkinkan model untuk
dilatih dan dievaluasi menggunakan data yang berbeda. Dalam konteks ini,
kita akan menggunakan fungsi initial_split dari paket
rsample dalam tidymodels untuk membagi data.
Model akan dilatih menggunakan 70 persen data dan 30 persen sisanya akan
digunakan sebagai data uji.
Standardisasi data juga merupakan langkah penting, terutama dalam
pemodelan SVM yang sangat bergantung pada jarak antara titik data.
Perbedaan skala antar fitur dapat mempengaruhi performa model, sehingga
perlu disesuaikan. Proses standardisasi akan membuat setiap fitur
memiliki nilai rata-rata 0 dan standar deviasi 1. Di
tidymodels, standardisasi dapat dilakukan menggunakan
fungsi step_center dan step_scale dari paket
recipe.
Jika terdapat pra-pemrosesan lainnya yang diperlukan seperti,
penanganan missing value, penanganan outlier juga dapat ditambahkan pada
fungsi recipe.
Berikut adalah langkah-langkahnya dalam kode R menggunakan
tidymodels:
set.seed(111)
# membagi data latih dan data uji
data_split <- initial_split(data, prop = 0.7)
data_train <- training(data_split)
data_test <- testing(data_split)
# menyiapkan tahapan preprocessing
data_recipe <- recipe(HeartDisease ~ ., data = data_train) %>%
step_center(all_numeric_predictors()) %>% # standardisasi fitur (center + scale)
step_scale(all_numeric_predictors()) # standardisasi fitur (center + scale)
data_recipe##
## ── Recipe ──────────────────────────────────────────────────────────────────────
##
## ── Inputs
## Number of variables by role
## outcome: 1
## predictor: 11
##
## ── Operations
## • Centering for: all_numeric_predictors()
## • Scaling for: all_numeric_predictors()
Pemodelan SVM
Dalam ekosistem tidymodels, kita dapat menggunakan
beberapa fungsi untuk membangun, men-tuning, dan mengevaluasi model SVM.
Berikut adalah beberapa fungsi utama dan parameter dapat digunakan untuk
model SVM di tidymodels:
svm_rbf: fungsi ini digunakan untuk
membuat model SVM dengan kernel radial basis function (RBF). RBF adalah
kernel yang sering digunakan karena fleksibilitasnya dalam menangani
berbagai tipe data. Pada fungsi ini terdapat aprameter yang dapat diatur
meliputi:
mode: Menentukan apakah model digunakan untuk klasifikasi ("classification") atau regresi ("regression").cost: parametercostberupa nilai positif dan berfungsi sebagai regularisasi yang mengontrol margin serta penalti kesalahan klasifikasi. Nilai yang lebih tinggi memberikan penalti yang lebih besar untuk kesalahan klasifikasi.rbf_sigma: parameterrbf_sigmaberupa nilai positif yang menentukan luas dari pengaruh satu titik data dan berhubungan dengan seberapa “lebar” kernel RBF.
svm_poly: fungsi ini digunakan untuk
membuat model SVM menggunakan kernel polinomial. Parameter pada fungsi
svm_poly yaitu:
modecostdegree: derajat polinomial yang digunakan (misal 2: kuadratik, 3: kubik, dan sebagainya)scale_factor: (atau dikenal juga sebagaigammadalam beberapa literatur) adalah parameter yang mengatur skala dari kernel polinomial yang menentukan seberapa besar kontribusi setiap fitur sebelum dipangkatkan.
svm_linear: fungsi ini digunakan untuk
membuat SVM dengan kernel linier. Fungsi ini merupakan model SVM yang
paling sederhana, dan dapat bekerja baik jika kelas data dapat terpisah
dengan baik secara linier. Parameter pada fungsi svm_linear
yaitu mode dan cost.
Di sini, kita akan menggunakan fungsi svm_rbf untuk
membangun model SVM. Silahkan mengeksplorasi secara mandiri dua fungsi
lainnya dan coba bandingkan hasilnya.
Pelatihan Model
Tahapan pelatihan di mulai dengan melakukan inisiasi model, misalkan
menggunakan svm_rbf. Kita dapat menentukan nilai
parameternya, sebagai contoh dengan cost=2 dan
rbf_sigma=1. Pada bagian ini kita akan menggunakan nilai
tersebut secara langsung, namun berikutnya nilai tersebut akan diperoleh
berdasarkan proses tuning hyperparameter.
Selanjutnya, kita dapat membuat workflow pemodelan menggunakan fungsi
workflow. Di sini, kita dapat menentukan langkah apa yang
dilakukan pada proses pemodelan. Dalam hal ini, ada dua proses meliputi
pra-pemrosesan data yang sudah didefinisikan sebelumnya dan tahapan
pemodelan menggunakan model SVM.
# inisiasi model
svm_model <- svm_rbf(mode = "classification", cost = 2, rbf_sigma = 1) %>%
set_engine("kernlab")
# membuat workflow model
svm_workflow <- workflow() %>%
add_recipe(data_recipe) %>%
add_model(svm_model)
# melatih model dengan data latih
svm_fit <- svm_workflow %>%
fit(data = data_train)
print(svm_fit)## ══ Workflow [trained] ══════════════════════════════════════════════════════════
## Preprocessor: Recipe
## Model: svm_rbf()
##
## ── Preprocessor ────────────────────────────────────────────────────────────────
## 2 Recipe Steps
##
## • step_center()
## • step_scale()
##
## ── Model ───────────────────────────────────────────────────────────────────────
## Support Vector Machine object of class "ksvm"
##
## SV type: C-svc (classification)
## parameter : cost C = 2
##
## Gaussian Radial Basis kernel function.
## Hyperparameter : sigma = 1
##
## Number of Support Vectors : 591
##
## Objective Function Value : -235.4691
## Training error : 0.001558
## Probability model included.
Evaluasi Model
Model yang diperoleh selanjutnya digunakan untuk memprediksi data uji sekaligus mengevaluasi hasil model tersebut. Pada contoh dibawah ini, kita menggunakan metrik accuracy sebagai ukuran kinerja model.
Hasil di bawah ini menunjukkan kinerja model SVM pada data uji. Nilai
akurasi yang didapatkan adalah sebesar 0,819 atau secara
umum model mampu memprediksi benar sekitar 81,9 persen data uji. Jika
diperlukan, kita juga dapat menampilkan confusion matrix, atau
metrik-metrik lainnya dalam pemodelan klasifikasi.
# memprediksi data uji
svm_preds <- predict(svm_fit, data_test, type = "class") %>%
bind_cols(data_test)
print(svm_preds)## # A tibble: 276 × 13
## .pred_class Age Sex ChestPainType RestingBP Cholesterol FastingBS
## <fct> <int> <chr> <chr> <int> <int> <int>
## 1 0 40 M ATA 140 289 0
## 2 1 49 F NAP 160 180 0
## 3 0 45 F ATA 130 237 0
## 4 1 38 M ASY 110 196 0
## 5 0 43 F TA 100 223 0
## 6 0 49 F ATA 124 201 0
## 7 1 44 M ATA 150 288 0
## 8 0 52 M ATA 120 284 0
## 9 1 53 F ATA 113 468 0
## 10 1 54 M ASY 125 224 0
## # ℹ 266 more rows
## # ℹ 6 more variables: RestingECG <chr>, MaxHR <int>, ExerciseAngina <chr>,
## # Oldpeak <dbl>, ST_Slope <chr>, HeartDisease <fct>
# menghitung metrik akurasi
svm_metrics <- svm_preds %>%
metrics(truth = HeartDisease, estimate = .pred_class)
print(svm_metrics)## # A tibble: 2 × 3
## .metric .estimator .estimate
## <chr> <chr> <dbl>
## 1 accuracy binary 0.819
## 2 kap binary 0.617
# menghitung confusion matrix
cm <- svm_preds %>%
conf_mat(truth = HeartDisease, estimate = .pred_class)
print(cm)## Truth
## Prediction 0 1
## 0 78 11
## 1 39 148
# Menghitung metrik lainnya (jika diperlukan)
# (balanced accuracy, precision, recall, F1-score)
svm_metrics_oth <- svm_preds %>%
summarise(
Precision = precision_vec(truth = HeartDisease, estimate = .pred_class),
Recall = recall_vec(truth = HeartDisease, estimate = .pred_class),
Bal_Accuracy = bal_accuracy_vec(truth = HeartDisease, estimate = .pred_class),
F1_Score = f_meas_vec(truth = HeartDisease, estimate = .pred_class)
)
print(svm_metrics_oth)## # A tibble: 1 × 4
## Precision Recall Bal_Accuracy F1_Score
## <dbl> <dbl> <dbl> <dbl>
## 1 0.876 0.667 0.799 0.757
Tuning Hyperparameter
Model sebelumnya dibangun dengan menetapkan secara langsung nilai parameternya. Untuk mencari model yang lebih baik kita dapat melakukan tuning hyperparameter seperti Grid Search, Random Search atau teknik lainnya. Pada contoh ini kita akan menggunakan teknik Random Search. Random Search bekerja dengan mencoba berbagai kombinasi berbagai nilai parameter yang diberikan sebanyak jumlah tertentu, misalkan 50 kali atau 100 kali. Semakin banyak percobaan, maka semakin besar kemungkinan memperoleh model yang lebih baik, namun tentunya semakin lama juga waktu pencarian yang dibutuhkan.
Pencarian dengan Random Search
Sama seperti sebelumnya, pertama kita inisiasi model menggunakan
fungsi svm_rbf serta membuat workflow-nya. Perbedaannya
adalah pada bagian penentuan nilai parameternya. Di sini, kita
menggunakan fungsi tune() yang menandakan nilai parameter
tersebut akan ditentukan berdasarkan proses tuning hyperparameter.
Berikutnya, kita perlu mendefinisikan nilai-nilai hyperparameter
sebagai acuan pencarian. Misalkan untuk cost dan
rbf_sigma keduanya kita batasi pencarian pada rentang nilai
0.01 hingga 100. Fungsi range digunakan untuk membuat
rentang nilai dalam skala logaritmik, yang sangat berguna untuk
pencarian parameter seperti cost dan rbf_sigma
yang dapat berfluktuasi dalam skala yang luas.
Proses pencarian dilakukan menggunakan fungsi tune_grid
dan evaluasi selama proses pencarian dapat dilakukan menggunakan
validasi silang k-fold pada data latih.
Nilai parameter terbaik dapat diperoleh melalui fungsi
select_best berdasarkan metrik yang diinginkan (contoh:
accuracy). Dari output di bawah ini, diperoleh model dengan nilai
accuracy terbaik (berdasarkan validasi silang k-fold) yaitu dengan nilai
cost=1.87 dan rbf_sigma=0.0351.
set.seed(111)
# inisiasi model svm
svm_tune_model <- svm_rbf(mode = "classification",
cost = tune(),
rbf_sigma = tune()) %>%
set_engine("kernlab")
# membuat model workflow
svm_tune_workflow <- workflow() %>%
add_recipe(data_recipe) %>%
add_model(svm_tune_model)
# mendefinisikan grid parameter (random search)
param_grid <- grid_random(
cost(range = c(-2, 2)), # rentang pencarian nilai cost dari 10^-2 hingga 10^2
rbf_sigma(range = c(-2, 2)), # rentang pencarian nilai sigma dari 10^-2 hingga 10^2
size=100 # buat kombinasi random search sebanyak 100 kali
)
# membuat data untuk k-fold cv dengan 3 fold
folds <- vfold_cv(data_train, v = 3)
# melatih model dengan pencarian hyperparameter
svm_tune <- tune_grid(
svm_tune_workflow,
resamples = folds,
grid = param_grid
)
# menentukan hyperaprameter terbaik
svm_best <- select_best(svm_tune, metric="accuracy")
print(svm_best)## # A tibble: 1 × 3
## cost rbf_sigma .config
## <dbl> <dbl> <chr>
## 1 1.87 0.0351 Preprocessor1_Model002
Finalisasi Workflow Model
Dari hasil di atas, kita dapat membuat workflow menggunakan model
terbaik yang telah diperoleh. Adapun langkah-langkahnya sama seperti
sebelumnya. Hasil evaluasi model pada data uji menunjukkan kinerja yang
jauh lebih baik dibandingkan sebelumnya dengan akurasi sebesar
0,884. Berdasarkan confusion matrix juga dapat dilihat
bahwa kemampuan model memprediksi relatif lebih baik, khususnya pada
kelas 0.
# Finalisasi alur kerja dengan hyperparameter terbaik
final_svm_workflow <- finalize_workflow(
svm_tune_workflow,
svm_best
)
# Latih model dengan data latih
best_fit <- final_svm_workflow %>%
fit(data = data_train)
# Evaluasi model dengan data uji
best_preds <- predict(best_fit, data_test) %>%
bind_cols(data_test)
svm_metrics_best <- best_preds %>%
metrics(truth = HeartDisease, estimate = .pred_class)
print(svm_metrics_best)## # A tibble: 2 × 3
## .metric .estimator .estimate
## <chr> <chr> <dbl>
## 1 accuracy binary 0.884
## 2 kap binary 0.763
# buat confusion matrix
cm_best <- best_preds %>%
conf_mat(truth = HeartDisease, estimate = .pred_class)
print(cm_best)## Truth
## Prediction 0 1
## 0 101 16
## 1 16 143
Persistensi Model
Setelah kita selesai melatih model dan melakukan proses tuning
hyperparameter, penting untuk menyimpan model yang telah dilatih
sehingga dapat digunakan kembali atau didistribusikan tanpa perlu
melatih ulang atau dikenal sebagai persistensi model. Di R, kita dapat
menyimpan objek model menggunakan fungsi saveRDS dan
memuatnya kembali dengan readRDS. Model yang sudah dimuat
selanjutnya dapat kita gunakan kembali, misalkan untuk memprediksi data
baru.
Pada contoh berikut, terdapat 2 data baru dan akan dilakukan prediksi
kondisi keduanya apakah Normal atau kemungkinan mengalami
heart Desease.
# contoh menyimpan model ke dalam file .rds
saveRDS(best_fit, file = "final_model.rds")
# contoh membuka model dari file .rds
loaded_final_model <- readRDS(file = "final_model.rds")
# Prediksi data baru menggunakan model
data_1 = data.frame(Age=38,
Sex="F",
ChestPainType="ASY",
RestingBP=105,
Cholesterol=50,
FastingBS=1,
RestingECG="Normal",
MaxHR=166,
ExerciseAngina="N",
Oldpeak=2.8,
ST_Slope="Up")
data_2 = data.frame(Age=29,
Sex="M",
ChestPainType="ATA",
RestingBP=120,
Cholesterol=243,
FastingBS=0,
RestingECG="Normal",
MaxHR=160,
ExerciseAngina="N",
Oldpeak=0.0,
ST_Slope="Up")
data_baru = data.frame(rbind(data_1, data_2))
predictions <- predict(loaded_final_model, data_baru) %>%
bind_cols(data_baru)
predictions## # A tibble: 2 × 12
## .pred_class Age Sex ChestPainType RestingBP Cholesterol FastingBS
## <fct> <dbl> <chr> <chr> <dbl> <dbl> <dbl>
## 1 1 38 F ASY 105 50 1
## 2 0 29 M ATA 120 243 0
## # ℹ 5 more variables: RestingECG <chr>, MaxHR <dbl>, ExerciseAngina <chr>,
## # Oldpeak <dbl>, ST_Slope <chr>
Selamat mencoba!!!
sumber: Support Vector machine (SVM) untuk Model Klasifikasi dengan R