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).
Memahami prinsip dasar SVM untuk klasifikasi
Membandingkan performa SVM linear dan nonlinear (RBF kernel)
Menganalisis pengaruh parameter C dan gamma
Visualisasi decision boundary
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)# Load dataset
data(BreastCancer)
df <- BreastCancer
# Informasi dasar dataset
cat("Dimensi dataset:", dim(df), "\n")## Dimensi dataset: 699 11
## Jumlah missing values: 16
## '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 ...
## 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
##
##
##
##
##
##
## 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.
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
## 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")| benign | malignant | |
|---|---|---|
| train_dist | 356 | 192 |
| test_dist | 88 | 47 |
# 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
##
# 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")| 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%.
# 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
##
# 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")| 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).
# 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")| 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.
# 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
# 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%.
# 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.
# 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()| 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.
# 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()| 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.
## Jumlah Support Vectors SVM Linear: 43
## Jumlah Support Vectors SVM RBF: 149
## 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%).
# 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()| 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.
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.