Support Vector machine (SVM) untuk Model Klasifikasi dengan R

Support Vector Machine (SVM) tidymodels 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

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

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: parameter cost 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: parameter rbf_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 sebagai gamma 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

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

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!!!

Tulisan Lainnya

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *

Daftar Isi