Support Vector Machine
Support Vector Machine

1. Pendahuluan

Support Vector Machine (SVM) adalah algoritma pembelajaran mesin yang digunakan dalam tugas klasifikasi. Algoritma ini bekerja dengan mencari hyperplane optimal yang memisahkan kelas-kelas dalam data, sambil memaksimalkan margin antar kelas dalam ruang berdimensi-N (Cortes & Vapnik, 1995). Dalam penelitian ini, kita akan menggunakan Breast Cancer Dataset yang tersedia secara publik untuk membangun dan membandingkan dua model SVM: model linear dan nonlinear (menggunakan kernel Radial Basis Function atau RBF).

Tujuan Analisis

  • Memahami prinsip dasar SVM untuk klasifikasi

  • Membandingkan performa SVM linear dan nonlinear (RBF kernel)

  • Menganalisis pengaruh parameter C dan gamma

  • Visualisasi decision boundary

2. Persiapan Data

Pada tahap persiapan data, dilakukan beberapa langkah berikut: Langkah 1 - Load Library: Digunakan pustaka seperti e1071 untuk model SVM, caret untuk pemodelan, ggplot2 untuk visualisasi, dan pROC untuk kurva ROC. ## Load Library

# Load libraries
# Load libraries
library(e1071)           # SVM
library(caret)           # Machine learning toolkit
library(ggplot2)         # Visualisasi
library(dplyr)           # Data manipulation
library(gridExtra)       # Multiple plots
library(RColorBrewer)    # Color palettes
library(pROC)            # ROC curves
library(tidyr)           # Data tidying (untuk pivot functions)
library(knitr)           # Kable tables
library(mlbench)         # For Dataset
library(corrplot)

Eksplorasi Dataset

# Load dataset
data(BreastCancer)
df <- BreastCancer

# Informasi dasar dataset
cat("Dimensi dataset:", dim(df), "\n")
## Dimensi dataset: 699 11
cat("Jumlah missing values:", sum(is.na(df)), "\n")
## Jumlah missing values: 16
# Struktur data
str(df)
## 'data.frame':    699 obs. of  11 variables:
##  $ Id             : chr  "1000025" "1002945" "1015425" "1016277" ...
##  $ Cl.thickness   : Ord.factor w/ 10 levels "1"<"2"<"3"<"4"<..: 5 5 3 6 4 8 1 2 2 4 ...
##  $ Cell.size      : Ord.factor w/ 10 levels "1"<"2"<"3"<"4"<..: 1 4 1 8 1 10 1 1 1 2 ...
##  $ Cell.shape     : Ord.factor w/ 10 levels "1"<"2"<"3"<"4"<..: 1 4 1 8 1 10 1 2 1 1 ...
##  $ Marg.adhesion  : Ord.factor w/ 10 levels "1"<"2"<"3"<"4"<..: 1 5 1 1 3 8 1 1 1 1 ...
##  $ Epith.c.size   : Ord.factor w/ 10 levels "1"<"2"<"3"<"4"<..: 2 7 2 3 2 7 2 2 2 2 ...
##  $ Bare.nuclei    : Factor w/ 10 levels "1","2","3","4",..: 1 10 2 4 1 10 10 1 1 1 ...
##  $ Bl.cromatin    : Factor w/ 10 levels "1","2","3","4",..: 3 3 3 3 3 9 3 3 1 2 ...
##  $ Normal.nucleoli: Factor w/ 10 levels "1","2","3","4",..: 1 2 1 7 1 7 1 1 1 1 ...
##  $ Mitoses        : Factor w/ 9 levels "1","2","3","4",..: 1 1 1 1 1 1 1 1 5 1 ...
##  $ Class          : Factor w/ 2 levels "benign","malignant": 1 1 1 1 1 2 1 1 1 1 ...
# Summary statistik
summary(df)
##       Id             Cl.thickness   Cell.size     Cell.shape  Marg.adhesion
##  Length:699         1      :145   1      :384   1      :353   1      :407  
##  Class :character   5      :130   10     : 67   2      : 59   2      : 58  
##  Mode  :character   3      :108   3      : 52   10     : 58   3      : 58  
##                     4      : 80   2      : 45   3      : 56   10     : 55  
##                     10     : 69   4      : 40   4      : 44   4      : 33  
##                     2      : 50   5      : 30   5      : 34   8      : 25  
##                     (Other):117   (Other): 81   (Other): 95   (Other): 63  
##   Epith.c.size  Bare.nuclei   Bl.cromatin  Normal.nucleoli    Mitoses   
##  2      :386   1      :402   2      :166   1      :443     1      :579  
##  3      : 72   10     :132   3      :165   10     : 61     2      : 35  
##  4      : 48   2      : 30   1      :152   3      : 44     3      : 33  
##  1      : 47   5      : 30   7      : 73   2      : 36     10     : 14  
##  6      : 41   3      : 28   4      : 40   8      : 24     4      : 12  
##  5      : 39   (Other): 61   5      : 34   6      : 22     7      :  9  
##  (Other): 66   NA's   : 16   (Other): 69   (Other): 69     (Other): 17  
##        Class    
##  benign   :458  
##  malignant:241  
##                 
##                 
##                 
##                 
## 
# Distribusi kelas
table(df$Class)
## 
##    benign malignant 
##       458       241

Langkah 2 - Eksplorasi Dataset Dataset berisi 699 observasi dengan 11 variabel.

Dataset mengalami proses pembersihan untuk menghapus nilai yang hilang, menghasilkan 683 baris data yang bersih.

Kolom ordinal pada dataset (seperti Cl.thickness, Cell.size, dan lainnya) diubah menjadi numerik agar bisa digunakan dalam model.

# Visualisasi distribusi kelas
p1 <- ggplot(df, aes(x = Class, fill = Class)) +
  geom_bar() +
  labs(title = "Distribusi Kelas pada Breast Cancer",
       x = "Kelas", y = "Jumlah") +
  theme_minimal() +
  scale_fill_brewer(type = "qual", palette = "Set2")

# Mengubah kolom ordinal menjadi numerik
df$Cl.thickness <- as.numeric(df$Cl.thickness)
df$Cell.size <- as.numeric(df$Cell.size)
df$Cell.shape <- as.numeric(df$Cell.shape)
df$Marg.adhesion <- as.numeric(df$Marg.adhesion)
df$Epith.c.size <- as.numeric(df$Epith.c.size)
df$Bare.nuclei <- as.numeric(df$Bare.nuclei)
df$Bl.cromatin <- as.numeric(df$Bl.cromatin)
df$Normal.nucleoli <- as.numeric(df$Normal.nucleoli)
df$Mitoses <- as.numeric(df$Mitoses)

# Hanya memilih kolom numerik, kecuali kolom 'Class'
numeric_vars <- df %>%
  select(-Class, -Id) %>%
  select_if(is.numeric)

# Memeriksa data numerik yang dipilih
str(numeric_vars)
## 'data.frame':    699 obs. of  9 variables:
##  $ Cl.thickness   : num  5 5 3 6 4 8 1 2 2 4 ...
##  $ Cell.size      : num  1 4 1 8 1 10 1 1 1 2 ...
##  $ Cell.shape     : num  1 4 1 8 1 10 1 2 1 1 ...
##  $ Marg.adhesion  : num  1 5 1 1 3 8 1 1 1 1 ...
##  $ Epith.c.size   : num  2 7 2 3 2 7 2 2 2 2 ...
##  $ Bare.nuclei    : num  1 10 2 4 1 10 10 1 1 1 ...
##  $ Bl.cromatin    : num  3 3 3 3 3 9 3 3 1 2 ...
##  $ Normal.nucleoli: num  1 2 1 7 1 7 1 1 1 1 ...
##  $ Mitoses        : num  1 1 1 1 1 1 1 1 5 1 ...
# Menghitung matriks korelasi
correlation_matrix <- cor(numeric_vars, use = "complete.obs")

# Visualisasi korelasi antar variabel
corrplot(correlation_matrix, method = "circle", type = "upper",
         title = "Matriks Korelasi Variabel Numerik", mar = c(0,0,1,0))

Korelasi antar variabel numerik dihitung untuk melihat hubungan antara fitur. Visualisasi matriks korelasi menunjukkan bagaimana fitur-fitur seperti Cl.thickness dan Cell.size saling berhubungan.

Preprocessing Data

Data ordinal diubah menjadi numerik agar dapat digunakan dalam model, dan dilakukan standardisasi fitur numerik.

# Hapus missing values
df_clean <- na.omit(df)
cat("Data setelah menghapus missing values:", nrow(df_clean), "baris\n")
## Data setelah menghapus missing values: 683 baris
# Pilih variabel untuk analisis (fokus pada fitur numerik dan kelas)
df_model <- df_clean %>%
  select(Class, Cl.thickness, Cell.size, Cell.shape, Marg.adhesion, 
         Epith.c.size, Bare.nuclei, Bl.cromatin, Normal.nucleoli, Mitoses)

# Standardisasi fitur numerik
df_scaled <- df_model
df_scaled[, -1] <- scale(df_scaled[, -1])

# Split data training dan testing (80:20)
set.seed(123)
train_index <- createDataPartition(df_scaled$Class, p = 0.8, list = FALSE)
train_data <- df_scaled[train_index, ]
test_data <- df_scaled[-train_index, ]

cat("Data training:", nrow(train_data), "baris\n")
## Data training: 548 baris
cat("Data testing:", nrow(test_data), "baris\n")
## Data testing: 135 baris
# Distribusi kelas di data training dan testing
train_dist <- table(train_data$Class)
test_dist <- table(test_data$Class)

kable(rbind(train_dist, test_dist), 
      caption = "Distribusi Kelas dalam Data Training dan Testing")
Distribusi Kelas dalam Data Training dan Testing
benign malignant
train_dist 356 192
test_dist 88 47

3. Model SVM Linear

Training Model SVM Linear

# Training SVM Linear
svm_linear <- svm(Class ~ ., data = train_data, 
                  kernel = "linear", cost = 1, scale = FALSE)

# Summary model
summary(svm_linear)
## 
## Call:
## svm(formula = Class ~ ., data = train_data, kernel = "linear", cost = 1, 
##     scale = FALSE)
## 
## 
## Parameters:
##    SVM-Type:  C-classification 
##  SVM-Kernel:  linear 
##        cost:  1 
## 
## Number of Support Vectors:  43
## 
##  ( 21 22 )
## 
## 
## Number of Classes:  2 
## 
## Levels: 
##  benign malignant
# Prediksi pada data testing
pred_linear <- predict(svm_linear, test_data)

# Confusion Matrix
cm_linear <- confusionMatrix(pred_linear, test_data$Class)
print(cm_linear)
## Confusion Matrix and Statistics
## 
##            Reference
## Prediction  benign malignant
##   benign        87         2
##   malignant      1        45
##                                           
##                Accuracy : 0.9778          
##                  95% CI : (0.9364, 0.9954)
##     No Information Rate : 0.6519          
##     P-Value [Acc > NIR] : <2e-16          
##                                           
##                   Kappa : 0.9508          
##                                           
##  Mcnemar's Test P-Value : 1               
##                                           
##             Sensitivity : 0.9886          
##             Specificity : 0.9574          
##          Pos Pred Value : 0.9775          
##          Neg Pred Value : 0.9783          
##              Prevalence : 0.6519          
##          Detection Rate : 0.6444          
##    Detection Prevalence : 0.6593          
##       Balanced Accuracy : 0.9730          
##                                           
##        'Positive' Class : benign          
## 

Evaluasi Model Linear

# Akurasi, Precision, Recall untuk setiap kelas
accuracy_linear <- cm_linear$overall['Accuracy']

# Handle kasus dimana byClass mungkin NULL atau berbeda struktur
if (!is.null(cm_linear$byClass) && is.matrix(cm_linear$byClass)) {
  precision_linear <- cm_linear$byClass[, 'Pos Pred Value']
  recall_linear <- cm_linear$byClass[, 'Sensitivity']
  f1_linear <- cm_linear$byClass[, 'F1']
} else {
  # Untuk kasus binary classification atau struktur berbeda
  precision_linear <- c(cm_linear$byClass['Pos Pred Value'])
  recall_linear <- c(cm_linear$byClass['Sensitivity'])
  f1_linear <- c(cm_linear$byClass['F1'])
}

# Handle NA values
precision_linear[is.na(precision_linear)] <- 0
recall_linear[is.na(recall_linear)] <- 0
f1_linear[is.na(f1_linear)] <- 0

# Tabel hasil evaluasi
eval_linear <- data.frame(
  Metrics = c("Accuracy", 
              paste0("Precision_", names(precision_linear)),
              paste0("Recall_", names(recall_linear)),
              paste0("F1_", names(f1_linear))),
  Values = c(accuracy_linear, precision_linear, recall_linear, f1_linear)
)

kable(eval_linear, digits = 4, caption = "Evaluasi Model SVM Linear")
Evaluasi Model SVM Linear
Metrics Values
Accuracy Accuracy 0.9778
Pos Pred Value Precision_Pos Pred Value 0.9775
Sensitivity Recall_Sensitivity 0.9886
F1 F1_F1 0.9831

SVM Linear: Model dengan kernel linear dilatih dan diuji pada data. Akurasi model linear mencapai 97.78% dengan sensitivitas tinggi (98.86%) dan spesifikasi 95.74%.

4. Model SVM Nonlinear (RBF Kernel)

Training Model SVM RBF

# Training SVM dengan RBF kernel
svm_rbf <- svm(Class ~ ., data = train_data, 
               kernel = "radial", cost = 1, gamma = 0.25, scale = FALSE)

# Summary model
summary(svm_rbf)
## 
## Call:
## svm(formula = Class ~ ., data = train_data, kernel = "radial", cost = 1, 
##     gamma = 0.25, scale = FALSE)
## 
## 
## Parameters:
##    SVM-Type:  C-classification 
##  SVM-Kernel:  radial 
##        cost:  1 
## 
## Number of Support Vectors:  149
## 
##  ( 33 116 )
## 
## 
## Number of Classes:  2 
## 
## Levels: 
##  benign malignant
# Prediksi pada data testing
pred_rbf <- predict(svm_rbf, test_data)

# Confusion Matrix
cm_rbf <- confusionMatrix(pred_rbf, test_data$Class)
print(cm_rbf)
## Confusion Matrix and Statistics
## 
##            Reference
## Prediction  benign malignant
##   benign        85         1
##   malignant      3        46
##                                           
##                Accuracy : 0.9704          
##                  95% CI : (0.9259, 0.9919)
##     No Information Rate : 0.6519          
##     P-Value [Acc > NIR] : <2e-16          
##                                           
##                   Kappa : 0.9354          
##                                           
##  Mcnemar's Test P-Value : 0.6171          
##                                           
##             Sensitivity : 0.9659          
##             Specificity : 0.9787          
##          Pos Pred Value : 0.9884          
##          Neg Pred Value : 0.9388          
##              Prevalence : 0.6519          
##          Detection Rate : 0.6296          
##    Detection Prevalence : 0.6370          
##       Balanced Accuracy : 0.9723          
##                                           
##        'Positive' Class : benign          
## 

Evaluasi Model RBF

# Akurasi, Precision, Recall untuk setiap kelas
accuracy_rbf <- cm_rbf$overall['Accuracy']

# Handle kasus dimana byClass mungkin NULL atau berbeda struktur
if (!is.null(cm_rbf$byClass) && is.matrix(cm_rbf$byClass)) {
  precision_rbf <- cm_rbf$byClass[, 'Pos Pred Value']
  recall_rbf <- cm_rbf$byClass[, 'Sensitivity']
  f1_rbf <- cm_rbf$byClass[, 'F1']
} else {
  # Untuk kasus binary classification atau struktur berbeda
  precision_rbf <- c(cm_rbf$byClass['Pos Pred Value'])
  recall_rbf <- c(cm_rbf$byClass['Sensitivity'])
  f1_rbf <- c(cm_rbf$byClass['F1'])
}

# Handle NA values
precision_rbf[is.na(precision_rbf)] <- 0
recall_rbf[is.na(recall_rbf)] <- 0
f1_rbf[is.na(f1_rbf)] <- 0

# Tabel hasil evaluasi
eval_rbf <- data.frame(
  Metrics = c("Accuracy", 
              paste0("Precision_", names(precision_rbf)),
              paste0("Recall_", names(recall_rbf)),
              paste0("F1_", names(f1_rbf))),
  Values = c(accuracy_rbf, precision_rbf, recall_rbf, f1_rbf)
)

kable(eval_rbf, digits = 4, caption = "Evaluasi Model SVM RBF")
Evaluasi Model SVM RBF
Metrics Values
Accuracy Accuracy 0.9704
Pos Pred Value Precision_Pos Pred Value 0.9884
Sensitivity Recall_Sensitivity 0.9659
F1 F1_F1 0.9770

SVM RBF: Model dengan kernel Radial Basis Function (RBF) menghasilkan akurasi 97.04%, dengan performa sedikit lebih rendah dibandingkan model linear. Namun, model ini lebih kompleks dan membutuhkan lebih banyak support vectors (149 dibandingkan dengan 43 pada SVM Linear).

5. Perbandingan Model

Tabel Perbandingan Performa

# Pastikan kedua data frame memiliki struktur yang sama
min_length <- min(nrow(eval_linear), nrow(eval_rbf))
eval_linear_subset <- eval_linear[1:min_length, ]
eval_rbf_subset <- eval_rbf[1:min_length, ]

# Gabungkan hasil evaluasi
comparison <- data.frame(
  Metrics = eval_linear_subset$Metrics,
  SVM_Linear = eval_linear_subset$Values,
  SVM_RBF = eval_rbf_subset$Values
)

kable(comparison, digits = 4, 
      caption = "Perbandingan Performa SVM Linear vs RBF")
Perbandingan Performa SVM Linear vs RBF
Metrics SVM_Linear SVM_RBF
Accuracy 0.9778 0.9704
Precision_Pos Pred Value 0.9775 0.9884
Recall_Sensitivity 0.9886 0.9659
F1_F1 0.9831 0.9770
# Visualisasi perbandingan akurasi
accuracy_comparison <- data.frame(
  Model = c("SVM Linear", "SVM RBF"),
  Accuracy = c(accuracy_linear, accuracy_rbf)
)

ggplot(accuracy_comparison, aes(x = Model, y = Accuracy, fill = Model)) +
  geom_col() +
  geom_text(aes(label = round(Accuracy, 4)), vjust = -0.5) +
  labs(title = "Perbandingan Akurasi Model SVM",
       y = "Akurasi") +
  theme_minimal() +
  scale_fill_brewer(type = "qual", palette = "Set1") +
  ylim(0, 1)

Perbandingan menunjukkan bahwa meskipun kedua model memberikan hasil yang baik, SVM Linear sedikit lebih unggul dalam hal akurasi. Meskipun demikian, SVM RBF menunjukkan kemampuan menangani data yang lebih kompleks dengan lebih banyak support vectors.

6. Tuning Parameter

Grid Search untuk Parameter Optimal

# Grid search untuk SVM RBF
tune_result <- tune(svm, Class ~ ., data = train_data,
                    kernel = "radial",
                    ranges = list(cost = c(0.1, 1, 10, 100),
                                  gamma = c(0.01, 0.1, 1, 10)))

# Hasil tuning
summary(tune_result)
## 
## Parameter tuning of 'svm':
## 
## - sampling method: 10-fold cross validation 
## 
## - best parameters:
##  cost gamma
##     1  0.01
## 
## - best performance: 0.02912458 
## 
## - Detailed performance results:
##     cost gamma      error dispersion
## 1    0.1  0.01 0.03646465 0.02421542
## 2    1.0  0.01 0.02912458 0.03228551
## 3   10.0  0.01 0.03276094 0.03405321
## 4  100.0  0.01 0.03094276 0.03094732
## 5    0.1  0.10 0.03461279 0.02900786
## 6    1.0  0.10 0.03276094 0.03405321
## 7   10.0  0.10 0.04373737 0.02731977
## 8  100.0  0.10 0.06387205 0.03356664
## 9    0.1  1.00 0.06377104 0.03334984
## 10   1.0  1.00 0.05282828 0.03015989
## 11  10.0  1.00 0.04737374 0.02730483
## 12 100.0  1.00 0.04737374 0.02730483
## 13   0.1 10.00 0.35050505 0.06434433
## 14   1.0 10.00 0.14589226 0.03988949
## 15  10.0 10.00 0.13127946 0.03582566
## 16 100.0 10.00 0.13127946 0.03582566
# Best parameters
best_params <- tune_result$best.parameters
cat("Parameter optimal - Cost:", best_params$cost, "Gamma:", best_params$gamma, "\n")
## Parameter optimal - Cost: 1 Gamma: 0.01
# Model dengan parameter optimal
svm_tuned <- tune_result$best.model

# Prediksi dengan model yang di-tune
pred_tuned <- predict(svm_tuned, test_data)
cm_tuned <- confusionMatrix(pred_tuned, test_data$Class)

cat("Akurasi model tuned:", cm_tuned$overall['Accuracy'], "\n")
## Akurasi model tuned: 0.9703704

Visualisasi Parameter Tuning

# Heatmap hasil tuning
tuning_results <- tune_result$performances
ggplot(tuning_results, aes(x = factor(cost), y = factor(gamma), fill = error)) +
  geom_tile() +
  scale_fill_gradient(low = "white", high = "red") +
  labs(title = "Heatmap Error Rate - Parameter Tuning",
       x = "Cost", y = "Gamma", fill = "Error Rate") +
  theme_minimal()

Tuning parameter C dan gamma untuk SVM RBF menunjukkan bahwa nilai optimal untuk C adalah 1 dan untuk gamma adalah 0.01, memberikan akurasi 97.04%.

7. Visualisasi Decision Boundary

Decision Boundary 2D

# Pilih 2 fitur untuk visualisasi 2D (misalnya Cl.thickness dan Cell.size)
train_2d <- train_data %>% select(Class, Cl.thickness, Cell.size)
test_2d <- test_data %>% select(Class, Cl.thickness, Cell.size)

# Model SVM untuk 2D
svm_2d_linear <- svm(Class ~ ., data = train_2d, kernel = "linear", cost = 1)
svm_2d_rbf <- svm(Class ~ ., data = train_2d, kernel = "radial", 
                  cost = best_params$cost, gamma = best_params$gamma)

# Fungsi untuk plot decision boundary
plot_decision_boundary <- function(model, data, title) {
  # Create grid
  x1 <- seq(min(data$Cl.thickness) - 0.5, max(data$Cl.thickness) + 0.5, 
            length.out = 100)
  x2 <- seq(min(data$Cell.size) - 0.5, max(data$Cell.size) + 0.5, 
            length.out = 100)
  grid <- expand.grid(Cl.thickness = x1, Cell.size = x2)
  
  # Predict on grid
  grid$Class <- predict(model, grid)
  
  # Plot
  ggplot() +
    geom_point(data = grid, aes(x = Cl.thickness, y = Cell.size, 
                                color = Class), alpha = 0.3, size = 0.5) +
    geom_point(data = data, aes(x = Cl.thickness, y = Cell.size, 
                                color = Class), size = 2) +
    labs(title = title,
         x = "Cl.thickness - Standardized",
         y = "Cell.size - Standardized") +
    theme_minimal() +
    scale_color_brewer(type = "qual", palette = "Set1")
}

# Plot decision boundaries
p_linear_2d <- plot_decision_boundary(svm_2d_linear, train_2d, 
                                     "SVM Linear - Decision Boundary")
p_rbf_2d <- plot_decision_boundary(svm_2d_rbf, train_2d, 
                                  "SVM RBF - Decision Boundary")

grid.arrange(p_linear_2d, p_rbf_2d, ncol = 2)

Visualisasi boundary keputusan untuk kedua model menunjukkan bagaimana data dipisahkan dalam ruang fitur 2D. SVM Linear menghasilkan boundary yang lebih sederhana dibandingkan dengan SVM RBF yang lebih kompleks, sesuai dengan jumlah support vectors yang lebih banyak.

8. Analisis Parameter C dan Gamma

Pengaruh Parameter C

# Test berbagai nilai C dengan gamma tetap
c_values <- c(0.01, 0.1, 1, 10, 100)
c_results <- data.frame(C = c_values, Accuracy = numeric(length(c_values)))

for (i in seq_along(c_values)) {
  svm_c <- svm(Class ~ ., data = train_data, kernel = "radial", 
               cost = c_values[i], gamma = 0.25, scale = FALSE)
  pred_c <- predict(svm_c, test_data)
  cm_c <- confusionMatrix(pred_c, test_data$Class)
  c_results$Accuracy[i] <- cm_c$overall['Accuracy']
}

# Plot pengaruh parameter C
ggplot(c_results, aes(x = log10(C), y = Accuracy)) +
  geom_line(color = "lightblue", size = 1) +
  geom_point(color = "pink", size = 3) +
  labs(title = "Pengaruh Parameter C terhadap Akurasi",
       x = "log10(C)", y = "Akurasi") +
  theme_minimal()

kable(c_results, digits = 4, caption = "Akurasi vs Parameter C")
Akurasi vs Parameter C
C Accuracy
1e-02 0.9630
1e-01 0.9556
1e+00 0.9704
1e+01 0.9704
1e+02 0.9778

Parameter C pada SVM adalah hyperparameter yang mengontrol trade-off antara margin yang lebih besar dan kesalahan klasifikasi. Parameter ini menentukan seberapa besar penalti yang dikenakan terhadap kesalahan klasifikasi. Secara lebih teknis, C mengontrol kompleksitas model:

  • C tinggi: Model akan lebih ketat dalam meminimalkan kesalahan pada data pelatihan, yang dapat menyebabkan overfitting jika nilai C terlalu tinggi.

  • C rendah: Model akan lebih toleran terhadap kesalahan klasifikasi dan mencoba untuk menemukan margin yang lebih besar, yang bisa menghasilkan model yang lebih sederhana dan kurang rentan terhadap overfitting.

Dari hasil eksperimen pengaruh nilai C, kita dapat melihat bahwa:

  • Dengan C = 1 (nilai default yang umum digunakan), model menghasilkan akurasi 97.04%.

  • Dengan C = 10 dan C = 100, akurasi meningkat sedikit dan mencapai 97.78%.

  • Dengan C = 0.1, akurasi turun menjadi 95.56%.

Model dengan C = 1 memiliki akurasi 97.04%, dan meningkat menjadi 97.78% pada C = 10 dan C = 100. Hal ini menunjukkan bahwa C yang lebih besar memberikan sedikit perbaikan dalam akurasi. Namun, ketika C terlalu kecil, misalnya C = 0.1, akurasi model menurun (95.56%). Ini menunjukkan bahwa model lebih toleran terhadap kesalahan klasifikasi dan mencoba untuk membuat margin lebih besar, tetapi pada akhirnya memperburuk performa dalam kasus ini.

Pengaruh Parameter Gamma

# Test berbagai nilai gamma dengan C tetap
gamma_values <- c(0.001, 0.01, 0.1, 1, 10)
gamma_results <- data.frame(Gamma = gamma_values, 
                           Accuracy = numeric(length(gamma_values)))

for (i in seq_along(gamma_values)) {
  svm_gamma <- svm(Class ~ ., data = train_data, kernel = "radial", 
                   cost = 1, gamma = gamma_values[i], scale = FALSE)
  pred_gamma <- predict(svm_gamma, test_data)
  cm_gamma <- confusionMatrix(pred_gamma, test_data$Class)
  gamma_results$Accuracy[i] <- cm_gamma$overall['Accuracy']
}

# Plot pengaruh parameter gamma
ggplot(gamma_results, aes(x = log10(Gamma), y = Accuracy)) +
  geom_line(color = "purple", size = 1) +
  geom_point(color = "orange", size = 3) +
  labs(title = "Pengaruh Parameter Gamma terhadap Akurasi",
       x = "log10(Gamma)", y = "Akurasi") +
  theme_minimal()

kable(gamma_results, digits = 4, caption = "Akurasi vs Parameter Gamma")
Akurasi vs Parameter Gamma
Gamma Accuracy
1e-03 0.9778
1e-02 0.9704
1e-01 0.9778
1e+00 0.9556
1e+01 0.8444

Dari eksperimen yang dilakukan dengan beberapa nilai gamma, berikut adalah hasilnya:

  • Gamma rendah (0.01 dan 0.1) menghasilkan akurasi tinggi (97.78%), menunjukkan bahwa model SVM dengan kernel RBF dapat menangani data dengan baik tanpa membuat batas keputusan yang terlalu tajam.

  • Gamma sedang (1) menunjukkan penurunan akurasi yang signifikan menjadi 95.56%. Ini menunjukkan bahwa gamma yang terlalu besar menyebabkan model terlalu terfokus pada titik data yang lebih dekat dan menyebabkan overfitting.

  • Gamma tinggi (10) menunjukkan penurunan akurasi yang lebih tajam (84.44%), yang mengindikasikan bahwa dengan nilai gamma terlalu besar, model menjadi sangat kompleks dan tidak dapat generalisasi dengan baik pada data pengujian.

9. Interpretasi dan Analisis

Support Vectors

# Analisis support vectors
cat("Jumlah Support Vectors SVM Linear:", svm_linear$tot.nSV, "\n")
## Jumlah Support Vectors SVM Linear: 43
cat("Jumlah Support Vectors SVM RBF:", svm_rbf$tot.nSV, "\n")
## Jumlah Support Vectors SVM RBF: 149
cat("Jumlah Support Vectors SVM Tuned:", svm_tuned$tot.nSV, "\n")
## Jumlah Support Vectors SVM Tuned: 75
# Support vectors per kelas untuk setiap model
sv_linear <- svm_linear$nSV
sv_rbf <- svm_rbf$nSV
sv_tuned <- svm_tuned$nSV

# Menyiapkan data untuk visualisasi
sv_comparison <- data.frame(
  Class = c("benign", "malignant"),
  SVM_Linear = sv_linear,
  SVM_RBF = sv_rbf,
  SVM_Tuned = sv_tuned
)

# Visualisasi support vectors per kelas
sv_long <- sv_comparison %>%
  tidyr::pivot_longer(cols = -Class, names_to = "Model", values_to = "Count")

# Plot jumlah Support Vectors per Kelas
ggplot(sv_long, aes(x = Class, y = Count, fill = Model)) +
  geom_col(position = "dodge") +
  labs(title = "Perbandingan Jumlah Support Vectors",
       x = "Kelas", y = "Jumlah Support Vectors") +
  theme_minimal() +
  scale_fill_brewer(type = "qual", palette = "Set2")

  • SVM Linear: Menggunakan 43 support vectors untuk klasifikasi.

  • SVM RBF: Menggunakan 149 support vectors, menunjukkan bahwa boundary keputusan yang lebih kompleks dibutuhkan untuk memisahkan kelas.

  • SVM Tuned: Model yang dituning menggunakan parameter optimal (C = 1 dan gamma = 0.01) menghasilkan akurasi yang setara dengan SVM RBF (97.04%).

Feature Importance (untuk SVM Linear)

# Koefisien untuk SVM linear (weight vector)
weights <- t(svm_linear$coefs) %*% svm_linear$SV
feature_names <- colnames(train_data)[-1]

importance_df <- data.frame(
  Feature = feature_names,
  Importance = abs(as.numeric(weights))
)
importance_df <- importance_df[order(importance_df$Importance, decreasing = TRUE), ]

ggplot(importance_df, aes(x = reorder(Feature, Importance), y = Importance)) +
  geom_col(fill = "magenta") +
  coord_flip() +
  labs(title = "Feature Importance - SVM Linear",
       x = "Fitur", y = "Absolute Weight") +
  theme_minimal()

kable(importance_df, digits = 4, caption = "Feature Importance SVM Linear")
Feature Importance SVM Linear
Feature Importance
3 Cell.shape 0.6650
6 Bare.nuclei 0.6199
1 Cl.thickness 0.5299
7 Bl.cromatin 0.4316
9 Mitoses 0.3811
8 Normal.nucleoli 0.3423
4 Marg.adhesion 0.1675
5 Epith.c.size 0.1167
2 Cell.size 0.0107

Berdasarkan model SVM Linear, fitur yang paling penting dalam klasifikasi adalah Cell.shape, diikuti oleh Bare.nuclei dan Cl.thickness.

10. Kesimpulan

Kesimpulan - Performa Model: Model SVM Linear menunjukkan performa terbaik dengan akurasi 97.78%, meskipun model SVM RBF juga memberikan hasil yang sangat baik dengan akurasi 97.04%. SVM Linear lebih sederhana, lebih cepat, dan lebih efektif pada dataset ini, sementara SVM RBF lebih kompleks dan memberikan hasil yang sedikit lebih rendah dalam hal akurasi.

  • Parameter Tuning: Pemilihan parameter yang optimal sangat penting dalam meningkatkan performa model. Penyesuaian C dan gamma pada SVM RBF memberikan hasil yang lebih baik, dengan nilai optimal C = 1 dan gamma = 0.01.

  • Feature Importance: Fitur yang paling penting dalam klasifikasi kanker payudara menggunakan model SVM Linear adalah Cell.shape. Fitur-fitur pengukuran fisik lainnya juga berperan penting, tetapi dengan tingkat kepentingan yang lebih rendah.

Rekomendasi:

  • Gunakan SVM Linear jika dataset memiliki karakteristik yang lebih sederhana dan membutuhkan kecepatan serta interpretabilitas.

  • Gunakan SVM RBF untuk dataset yang lebih kompleks dengan pola non-linear, meskipun dengan biaya komputasi yang lebih tinggi.

  • Lakukan parameter tuning dengan menggunakan grid search untuk mendapatkan performa optimal pada model SVM.

Secara keseluruhan, SVM adalah algoritma yang sangat efektif untuk klasifikasi, terutama jika parameter dan kernel yang tepat digunakan untuk mengatasi kompleksitas data.

Kesimpulan Umum mengenai C dan Gamma

C dan gamma adalah dua parameter kunci yang memengaruhi complexity dan generalization model SVM.

  • C yang lebih besar cenderung meningkatkan akurasi model, tetapi berisiko menyebabkan overfitting.

  • Gamma rendah memberikan hasil yang lebih stabil dan akurat, sedangkan gamma tinggi menyebabkan model menjadi terlalu sensitif dan mengarah pada overfitting.

  • Tuning yang tepat pada C dan gamma sangat penting untuk menghasilkan model yang seimbang antara akurasi dan kemampuan generalisasi.