Support Vector machine (SVM) untuk Model Klasifikasi dengan R
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.
Jika anda ingin mempelajari teori dan konsep dasar dari SVM silahkan cek tulisan berikut: Support Vector Machine (SVM): Teori dan Konsep Dasar
Untuk anda yang ingin mempelajari SVM dalam bahasa Python silahkan cek tulisan berikut: Support Vector machine (SVM) untuk Model Klasifikasi dengan Python dan Model Support Vector Regression (SVR) dengan Scikit-Learn.
Pada tutorial ini, kita akan menggunakan metapaket tidymodels
untuk menangani setiap tahap pemodelan, mulai dari pra-pemrosesan data, pemodelan SVM, evaluasi hingga tuning hyperparameter model. 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, engine untuk SVM menggunakan paket kernlab
. Oleh karena itu, kita perlu menginstal kedua paket tersebut untuk melanjutkan.
Untuk memulai, pastikan anda telah menginstal kedua paket ini dengan perintah berikut:
R
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) library(kernlab) # Sebenarnya tidak diperlukan secara eksplisit
Penyiapan Data
Data yang digunakan dalam tutorial ini adalah Heart Disease Dataset. Dataset ini memberikan gambaran 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. Dataset terdiri dari 918 observasi dengan 11 variabel input atau fitur, yang mencakup tipe data numerik dan kategorik. Variabel respon ada pada kolom HeartDisease
, dengan kelas biner di mana nilai 0 menunjukkan kondisi normal dan nilai 1 menunjukkan adanya penyakit jantung.
R
# 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)
# OUTPUT Show in New Window '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 ...
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. Pada tidymodels
, standardisasi dapat dilakukan menggunakan fungsi step_center
dan step_scale
dari paket recipe
.
Jika terdapat pra-pemrosesan lainnya yang harus dilakukan seperti penanganan missing value atau penanganan outlier maka dapat juga ditambahkan pada fungsi recipe
.
R
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()) %>% # features standardization (center + scale) step_scale(all_numeric_predictors()) # features standardization (center + scale) data_recipe
# OUTPUT ── 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
: parametercost
berupa 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_sigma
berupa 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:
mode
cost
degree
: derajat polinomial yang digunakan (misal 2: kuadratik, 3: kubik, dan sebagainya)scale_factor
: (atau dikenal juga sebagaigamma
dalam 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
.
Saat ini, 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 dimulai dengan menginisiasi model, misalnya menggunakan svm_rbf
dan menetapkan nilai-nilai parameternya, seperti cost = 2
dan rbf_sigma = 1
. Pada tahap ini, kita akan menggunakan nilai-nilai parameter secara langsung, tetapi untuk bagian selanjutnya, nilai-nilai tersebut akan ditentukan melalui proses tuning hyperparameter.
Selanjutnya, kita membuat workflow pemodelan menggunakan fungsi workflow
. Di sini, kita menentukan langkah-langkah yang akan diikuti selama proses pemodelan. Dalam hal ini, ada dua proses utama: pra-pemrosesan data yang telah didefinisikan sebelumnya, dan tahap pemodelan menggunakan model SVM.
R
# 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)
# OUTPUT 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 dan Prediksi
Model yang telah dilatih kemudian digunakan untuk memprediksi data uji dan mengevaluasi hasilnya. Dalam contoh berikut, kita menggunakan metrik akurasi sebagai ukuran kinerja model.
Hasil di bawah ini menunjukkan performa model SVM pada data uji. Nilai akurasi yang diperoleh adalah 0,819
, yang berarti model mampu membuat prediksi yang benar sekitar 81,9 persen dari data uji. Jika diperlukan, kita juga dapat menampilkan confusion matrix atau metrik-metrik lain yang relevan dalam pemodelan klasifikasi untuk analisis yang lebih mendalam. [lihat: Metrik Evaluasi untuk Model Klasifikasi].
R
# memprediksi data uji svm_preds <- predict(svm_fit, data_test, type = "class") %>% bind_cols(data_test) print(svm_preds) # menghitung metrik akurasi svm_metrics <- svm_preds %>% metrics(truth = HeartDisease, estimate = .pred_class) print(svm_metrics) # menghitung confusion matrix cm <- svm_preds %>% conf_mat(truth = HeartDisease, estimate = .pred_class) print(cm) # 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)
# OUTPUT .metric .estimator .estimate <chr> <chr> <dbl> 1 accuracy binary 0.819 2 kap binary 0.617 Truth Prediction 0 1 0 78 11 1 39 148 Precision Recall Bal_Accuracy F1_Score <dbl> <dbl> <dbl> <dbl> 1 0.876 0.667 0.799 0.757
Tuning Hiperparameter
Model sebelumnya dibangun dengan menetapkan nilai-nilai parameternya secara langsung. Untuk mencari kemungkinan model yang lebih optimal, kita dapat melakukan tuning hyperparameter menggunakan teknik seperti Grid Search, Random Search, atau metode lainnya. Pada contoh ini, kita akan menggunakan Random Search. Random Search bekerja dengan mencoba berbagai kombinasi nilai parameter yang diberikan, misalnya sebanyak 50 atau 100 kali. Semakin banyak percobaan yang dilakukan, semakin besar kemungkinan untuk menemukan model yang lebih baik, meskipun hal ini juga akan meningkatkan waktu pencarian yang dibutuhkan.
Pencarian dengan Random Search
Seperti sebelumnya, kita memulai dengan menginisiasi model menggunakan fungsi svm_rbf
dan membuat workflow-nya. Perbedaannya terletak pada penentuan nilai-nilai parameter. Setiap parameter yang akan di-tuning, diinisiasi menggunakan fungsi tune()
, yang menandakan bahwa nilai parameter tersebut akan ditentukan melalui proses tuning hyperparameter.
Selanjutnya, kita mendefinisikan rentang nilai hyperparameter untuk pencarian. Misalnya, untuk cost
dan rbf_sigma
, kita batasi pencariannya pada rentang 0.01 ($10^-2$) hingga 100 ($10^2$). Fungsi range
digunakan untuk membuat rentang nilai dalam skala logaritmik, yang sangat berguna untuk parameter seperti cost
dan rbf_sigma
yang dapat berfluktuasi dalam skala yang luas. Proses pencarian dilakukan menggunakan fungsi tune_grid
dan dievaluasi dengan validasi silang k-fold pada data latih.
Nilai parameter terbaik dapat diperoleh melalui fungsi select_best
berdasarkan metrik yang diinginkan, seperti akurasi. Dari output di bawah ini, diperoleh model dengan nilai akurasi terbaik (berdasarkan validasi silang k-fold), yaitu dengan cost = 1.87
dan rbf_sigma = 0.0351
.
R
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)
# OUTPUT cost rbf_sigma .config <dbl> <dbl> <chr> 1 1.87 0.0351 Preprocessor1_Model002
Finalisasi Workflow Model Terbaik
Dari hasil di atas, kita dapat membuat workflow menggunakan model terbaik yang telah diperoleh dengan langkah-langkahnya sama seperti sebelumnya.
Evaluasi model pada data uji menunjukkan peningkatan kinerja yang signifikan dengan akurasi sebesar 0,884
. Berdasarkan confusion matrix, terlihat bahwa kemampuan model dalam memprediksi relatif lebih baik, terutama pada kelas 0
.
R
# 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) # buat confusion matrix cm_best <- best_preds %>% conf_mat(truth = HeartDisease, estimate = .pred_class) print(cm_best)
# OUTPUT .metric .estimator .estimate <chr> <chr> <dbl> 1 accuracy binary 0.884 2 kap binary 0.763 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 sehingga dapat digunakan kembali atau didistribusikan tanpa perlu melatih ulang atau dikenal sebagai persistensi model. Dalam bahasa 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.
Misalkan terdapat dua data baru seperti contoh di bawah ini. Hasil prediksi model SVM menunjukkan bahwa orang pertama diprediksi terkena Heart Desease (1
) sementara orang kedua diprediksi Normal (0
).
R
# 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") # contoh data baru 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)) # Prediksi data baru menggunakan model predictions <- predict(loaded_final_model, data_baru) %>% bind_cols(data_baru) predictions
# OUTPUT .pred_class Age Sex ChestPainType RestingBP Cholesterol FastingBS RestingECG MaxHR ExerciseAngina Oldpeak ST_Slope <fct> <dbl> <chr> <chr> <dbl> <dbl> <dbl> <chr> <dbl> <chr> <dbl> <chr> 1 1 38 F ASY 105 50 1 Normal 166 N 2.8 Up 2 0 29 M ATA 120 243 0 Normal 160 N 0 Up
Selamat mencoba!!!