1 Pendahuluan

Support Vector Machine (SVM) adalah algoritma pembelajaran mesin yang digunakan untuk klasifikasi dan regresi. Inti dari metode ini adalah menemukan hyperplane terbaik yang dapat memisahkan dua kelas dengan margin maksimum. SVM bekerja sangat baik pada dataset yang memiliki margin pemisah yang jelas dan digunakan secara luas karena efektivitasnya dalam menangani dimensi tinggi dan generalisasi yang baik.

Tujuan dari eksperimen ini adalah mengklasifikasikan spesies Penguin (Adelie dan Chinstrap) berdasarkan fitur morfologis seperti panjang paruh, kedalaman paruh, panjang sirip, dan massa tubuh.

Support Vector Machine (SVM) merupakan algoritma klasifikasi yang bekerja dengan mencari hyperplane optimal untuk memisahkan dua kelas data.

2 Komponen Dasar SVM

Beberapa komponen utama dari SVM antara lain:

  • Hyperplane: Garis atau bidang pemisah di ruang fitur yang membedakan kelas satu dengan lainnya.
  • Margin: Jarak antara hyperplane dan data support vector terdekat dari masing-masing kelas.
  • Support Vectors: Titik data yang terletak paling dekat dengan hyperplane. Titik-titik ini berpengaruh besar dalam menentukan posisi hyperplane.
  • Kernel Trick: Teknik yang memungkinkan SVM untuk memisahkan data yang tidak dapat dipisahkan secara linear dengan mentransformasikannya ke ruang dimensi yang lebih tinggi.

Jenis kernel yang sering digunakan meliputi: - Linear - Polynomial - Radial Basis Function (RBF)

  • Hyperplane: bidang pemisah antara dua kelas
  • Margin: jarak antara hyperplane dengan titik data terdekat dari tiap kelas
  • Support Vectors: titik data terdekat ke hyperplane
  • Kernel: fungsi untuk mentransformasikan data agar dapat dipisahkan secara linear

3 Dataset Penguin

data <- penguins %>% drop_na()
glimpse(data)
## Rows: 333
## Columns: 8
## $ species           <fct> Adelie, Adelie, Adelie, Adelie, Adelie, Adelie, Adel…
## $ island            <fct> Torgersen, Torgersen, Torgersen, Torgersen, Torgerse…
## $ bill_length_mm    <dbl> 39.1, 39.5, 40.3, 36.7, 39.3, 38.9, 39.2, 41.1, 38.6…
## $ bill_depth_mm     <dbl> 18.7, 17.4, 18.0, 19.3, 20.6, 17.8, 19.6, 17.6, 21.2…
## $ flipper_length_mm <int> 181, 186, 195, 193, 190, 181, 195, 182, 191, 198, 18…
## $ body_mass_g       <int> 3750, 3800, 3250, 3450, 3650, 3625, 4675, 3200, 3800…
## $ sex               <fct> male, female, female, female, male, female, male, fe…
## $ year              <int> 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007…

4 Eksplorasi Data

summary(data)
##       species          island    bill_length_mm  bill_depth_mm  
##  Adelie   :146   Biscoe   :163   Min.   :32.10   Min.   :13.10  
##  Chinstrap: 68   Dream    :123   1st Qu.:39.50   1st Qu.:15.60  
##  Gentoo   :119   Torgersen: 47   Median :44.50   Median :17.30  
##                                  Mean   :43.99   Mean   :17.16  
##                                  3rd Qu.:48.60   3rd Qu.:18.70  
##                                  Max.   :59.60   Max.   :21.50  
##  flipper_length_mm  body_mass_g       sex           year     
##  Min.   :172       Min.   :2700   female:165   Min.   :2007  
##  1st Qu.:190       1st Qu.:3550   male  :168   1st Qu.:2007  
##  Median :197       Median :4050                Median :2008  
##  Mean   :201       Mean   :4207                Mean   :2008  
##  3rd Qu.:213       3rd Qu.:4775                3rd Qu.:2009  
##  Max.   :231       Max.   :6300                Max.   :2009
ggplot(data, aes(x = species, fill = island)) + 
  geom_bar() + 
  theme_minimal() + 
  labs(title = "Distribusi Spesies Penguin per Pulau", 
       x = "Spesies", y = "Jumlah")

corrplot(cor(data %>% select(where(is.numeric))), method = "circle", 
         type = "lower", tl.cex = 0.8, title = "Korelasi antar Fitur", mar = c(0,0,1,0))

5 Preprocessing

data$species <- as.factor(data$species)
data <- data %>% filter(species != "Gentoo")  # hanya 2 kelas: Adelie vs Chinstrap
data <- data %>% select(species, bill_length_mm, bill_depth_mm, flipper_length_mm, body_mass_g)

set.seed(123)
index <- createDataPartition(data$species, p = 0.8, list = FALSE)
train <- data[index, ]
test <- data[-index, ]

6 Pelatihan Model SVM (Linear & RBF)

svm_linear <- svm(species ~ ., data = train, kernel = "linear", cost = 1, scale = TRUE)
svm_rbf <- svm(species ~ ., data = train, kernel = "radial", cost = 1, gamma = 0.01)

7 Evaluasi Model

pred_linear <- predict(svm_linear, test)
pred_rbf <- predict(svm_rbf, test)

cm_linear <- confusionMatrix(pred_linear, test$species)
cm_rbf <- confusionMatrix(pred_rbf, test$species)

cm_linear
## Confusion Matrix and Statistics
## 
##            Reference
## Prediction  Adelie Chinstrap Gentoo
##   Adelie        29         2      0
##   Chinstrap      0        11      0
##   Gentoo         0         0      0
## 
## Overall Statistics
##                                           
##                Accuracy : 0.9524          
##                  95% CI : (0.8384, 0.9942)
##     No Information Rate : 0.6905          
##     P-Value [Acc > NIR] : 3.384e-05       
##                                           
##                   Kappa : 0.8837          
##                                           
##  Mcnemar's Test P-Value : NA              
## 
## Statistics by Class:
## 
##                      Class: Adelie Class: Chinstrap Class: Gentoo
## Sensitivity                 1.0000           0.8462            NA
## Specificity                 0.8462           1.0000             1
## Pos Pred Value              0.9355           1.0000            NA
## Neg Pred Value              1.0000           0.9355            NA
## Prevalence                  0.6905           0.3095             0
## Detection Rate              0.6905           0.2619             0
## Detection Prevalence        0.7381           0.2619             0
## Balanced Accuracy           0.9231           0.9231            NA
cm_rbf
## Confusion Matrix and Statistics
## 
##            Reference
## Prediction  Adelie Chinstrap Gentoo
##   Adelie        29         3      0
##   Chinstrap      0        10      0
##   Gentoo         0         0      0
## 
## Overall Statistics
##                                          
##                Accuracy : 0.9286         
##                  95% CI : (0.8052, 0.985)
##     No Information Rate : 0.6905         
##     P-Value [Acc > NIR] : 0.0002153      
##                                          
##                   Kappa : 0.8215         
##                                          
##  Mcnemar's Test P-Value : NA             
## 
## Statistics by Class:
## 
##                      Class: Adelie Class: Chinstrap Class: Gentoo
## Sensitivity                 1.0000           0.7692            NA
## Specificity                 0.7692           1.0000             1
## Pos Pred Value              0.9062           1.0000            NA
## Neg Pred Value              1.0000           0.9062            NA
## Prevalence                  0.6905           0.3095             0
## Detection Rate              0.6905           0.2381             0
## Detection Prevalence        0.7619           0.2381             0
## Balanced Accuracy           0.8846           0.8846            NA

8 ROC Curve

# Konversi label target ke biner (Adelie = 1)
test_bin <- ifelse(test$species == "Adelie", 1, 0)

# Latih ulang model dengan estimasi probabilitas aktif
svm_rbf_prob <- svm(species ~ ., data = train, 
                    kernel = "radial", cost = 1, gamma = 0.01, 
                    probability = TRUE)

# Prediksi probabilitas
pred_prob <- predict(svm_rbf_prob, test, probability = TRUE)
probs <- attr(pred_prob, "probabilities")[, "Adelie"]

# ROC Curve
roc_obj <- roc(test_bin, probs)
plot(roc_obj, main = "ROC Curve - SVM RBF", col = "blue")

# Penjelasan: ROC Curve ini menggambarkan trade-off antara sensitivitas dan spesifisitas dari model SVM dengan kernel RBF.
# Area under the curve (AUC) menunjukkan seberapa baik model membedakan dua kelas.
auc(roc_obj)
## Area under the curve: 0.9947

9 Tuning Model

tune_result <- tune(svm, species ~ ., data = train,
                    kernel = "radial",
                    ranges = list(cost = c(0.1, 1, 10), gamma = c(0.001, 0.01, 0.1)))
summary(tune_result)
## 
## Parameter tuning of 'svm':
## 
## - sampling method: 10-fold cross validation 
## 
## - best parameters:
##  cost gamma
##    10  0.01
## 
## - best performance: 0.01699346 
## 
## - Detailed performance results:
##   cost gamma      error dispersion
## 1  0.1 0.001 0.32124183 0.11774838
## 2  1.0 0.001 0.32124183 0.11774838
## 3 10.0 0.001 0.03464052 0.04073550
## 4  0.1 0.010 0.32124183 0.11774838
## 5  1.0 0.010 0.04640523 0.03699857
## 6 10.0 0.010 0.01699346 0.02737653
## 7  0.1 0.100 0.07516340 0.06072924
## 8  1.0 0.100 0.01699346 0.02737653
## 9 10.0 0.100 0.01732026 0.02790245

10 Kesimpulan

SVM terbukti efektif untuk klasifikasi dua kelas data Penguin. Dengan tuning parameter kernel dan cost, performa dapat ditingkatkan secara signifikan.

11 Visualisasi Support Vector Machine

11.1 Visualisasi Data Asli

ggplot(train, aes(x = bill_length_mm, y = bill_depth_mm, color = species)) +
  geom_point(size = 3, alpha = 0.7) +
  theme_minimal() +
  labs(title = "Visualisasi Data Latih: bill_length vs bill_depth")

11.2 Visualisasi Decision Boundary (Linear SVM)

plot_svm_linear <- function(model, data){
  x_range <- seq(min(data$bill_length_mm), max(data$bill_length_mm), length.out = 100)
  y_range <- seq(min(data$bill_depth_mm), max(data$bill_depth_mm), length.out = 100)
  grid <- expand.grid(bill_length_mm = x_range, bill_depth_mm = y_range)
  grid$flipper_length_mm <- mean(data$flipper_length_mm)
  grid$body_mass_g <- mean(data$body_mass_g)

  grid$pred <- predict(model, grid)
  ggplot() +
    geom_tile(data = grid, aes(x = bill_length_mm, y = bill_depth_mm, fill = pred), alpha = 0.3) +
    geom_point(data = data, aes(x = bill_length_mm, y = bill_depth_mm, color = species), size = 2) +
    labs(title = "Decision Boundary SVM Linear") +
    theme_minimal()
}
plot_svm_linear(svm_linear, train)

# Penjelasan: Grafik ini menunjukkan bagaimana model SVM linear memisahkan dua kelas Penguin berdasarkan panjang dan kedalaman paruh. 
# Warna latar menunjukkan area keputusan (decision region), dan titik mewakili data latih aktual.

12 Penjelasan Tambahan

SVM Linear cocok ketika data dapat dipisahkan secara lurus. Kernel RBF cocok saat data tidak terpisahkan secara linear.

Tuning dilakukan untuk mendapatkan parameter cost dan gamma yang menghasilkan margin optimal dengan error minimum.
ROC Curve digunakan untuk menilai trade-off antara sensitivitas dan spesifisitas.


13 Referensi

  • Cristianini, N. and Shawe-Taylor, J., “An Introduction to Support Vector Machines and Other Kernel-based Learning Methods”, Cambridge University Press.
  • James, G., Witten, D., Hastie, T., Tibshirani, R., “An Introduction to Statistical Learning”.
  • Scikit-learn documentation (https://scikit-learn.org)