Support Vector Machine (SVM) adalah algoritma supervised learning yang digunakan untuk klasifikasi data dengan mencari hyperplane optimal yang memisahkan kelas-kelas berbeda dengan margin maksimal. SVM pertama kali diperkenalkan oleh Vladimir Vapnik dan timnya pada awal 1990-an. SVM bekerja dengan memaksimalkan jarak antara hyperplane dan titik-titik data terdekat dari masing-masing kelas, yang dikenal sebagai support vectors, karena titik-titik tersebut menentukan posisi dan orientasi bidang pemisah dalam ruang fitur berdimensi-N.
Dataset Palmer Penguin berisi data morfologi dari tiga spesies penguin yang berbeda, yaitu Adelie, Gentoo, dan Chinstrap yang diamati di Pulau Biscoe, Dream, dan Torgersen. Dataset ini mencakup ukuran fisik seperti panjang paruh (bill length), kedalaman paruh (bill depth), panjang sirip, dan berat tubuh. Data ini dikumpulkan dari tahun 2007 - 2009 oleh Dr. Kristen Gorman dengan Palmer Station Long Term Ecological Research Program, bagian dari US Long Term Ecological Research Network. Data tersebut diimpor langsung dari Portal Data Environmental Data Initiative (EDI).
data(penguins)
head(penguins)
## # A tibble: 6 × 8
## species island bill_length_mm bill_depth_mm flipper_length_mm body_mass_g
## <fct> <fct> <dbl> <dbl> <int> <int>
## 1 Adelie Torgersen 39.1 18.7 181 3750
## 2 Adelie Torgersen 39.5 17.4 186 3800
## 3 Adelie Torgersen 40.3 18 195 3250
## 4 Adelie Torgersen NA NA NA NA
## 5 Adelie Torgersen 36.7 19.3 193 3450
## 6 Adelie Torgersen 39.3 20.6 190 3650
## # ℹ 2 more variables: sex <fct>, year <int>
setwd("C:/Users/Luri Zahara/Downloads")
str(penguins)
## tibble [344 × 8] (S3: tbl_df/tbl/data.frame)
## $ species : Factor w/ 3 levels "Adelie","Chinstrap",..: 1 1 1 1 1 1 1 1 1 1 ...
## $ island : Factor w/ 3 levels "Biscoe","Dream",..: 3 3 3 3 3 3 3 3 3 3 ...
## $ bill_length_mm : num [1:344] 39.1 39.5 40.3 NA 36.7 39.3 38.9 39.2 34.1 42 ...
## $ bill_depth_mm : num [1:344] 18.7 17.4 18 NA 19.3 20.6 17.8 19.6 18.1 20.2 ...
## $ flipper_length_mm: int [1:344] 181 186 195 NA 193 190 181 195 193 190 ...
## $ body_mass_g : int [1:344] 3750 3800 3250 NA 3450 3650 3625 4675 3475 4250 ...
## $ sex : Factor w/ 2 levels "female","male": 2 1 1 NA 1 2 1 2 NA NA ...
## $ year : int [1:344] 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 ...
summary(penguins)
## species island bill_length_mm bill_depth_mm
## Adelie :152 Biscoe :168 Min. :32.10 Min. :13.10
## Chinstrap: 68 Dream :124 1st Qu.:39.23 1st Qu.:15.60
## Gentoo :124 Torgersen: 52 Median :44.45 Median :17.30
## Mean :43.92 Mean :17.15
## 3rd Qu.:48.50 3rd Qu.:18.70
## Max. :59.60 Max. :21.50
## NA's :2 NA's :2
## flipper_length_mm body_mass_g sex year
## Min. :172.0 Min. :2700 female:165 Min. :2007
## 1st Qu.:190.0 1st Qu.:3550 male :168 1st Qu.:2007
## Median :197.0 Median :4050 NA's : 11 Median :2008
## Mean :200.9 Mean :4202 Mean :2008
## 3rd Qu.:213.0 3rd Qu.:4750 3rd Qu.:2009
## Max. :231.0 Max. :6300 Max. :2009
## NA's :2 NA's :2
cat("Jumlah nilai yang hilang:", sum(is.na(penguins)), "\n")
## Jumlah nilai yang hilang: 19
colSums(is.na(penguins))
## species island bill_length_mm bill_depth_mm
## 0 0 2 2
## flipper_length_mm body_mass_g sex year
## 2 2 11 0
# Menghapus baris dengan nilai NA
penguins<- penguins %>% drop_na()
# Melihat ukuran dataset setelah pembersihan
cat("Ukuran dataset setelah pembersihan:", dim(penguins)[1], "baris dan",
dim(penguins)[2], "kolom\n")
## Ukuran dataset setelah pembersihan: 333 baris dan 8 kolom
# Distribusi spesies penguin
penguin_counts <- penguins %>%
count(species) %>%
mutate(percentage = n / sum(n) * 100)
kable(penguin_counts, caption = "Distribusi Spesies Penguin") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
| species | n | percentage |
|---|---|---|
| Adelie | 146 | 43.84384 |
| Chinstrap | 68 | 20.42042 |
| Gentoo | 119 | 35.73574 |
# Mengubah variable kategoris menjadi faktor
penguins$species <- as.factor(penguins$species)
penguins$island <- as.factor(penguins$island)
penguins$sex <- as.factor(penguins$sex)
library(palmerpenguins)
library(explore)
## Warning: package 'explore' was built under R version 4.4.3
##
## Attaching package: 'explore'
## The following object is masked from 'package:GGally':
##
## rescale01
penguins %>%
explore_all()
penguins %>%
explore_all(target = species, color = c("lightblue", "lightgreen", "lightpink"))
penguins %>%
explore_all(target = island, color = c("lightblue", "lightgreen", "lightpink"))
penguins %>%
explore_all(target = sex, color = c("lightblue", "lightpink"))
# Menghitung jumlah setiap spesies
species_count <- penguins %>%
count(species) %>%
mutate(percentage = round(n / sum(n) * 100, 1))
# Tampilkan dalam bentuk tabel
species_count %>%
kable(col.names = c("Spesies", "Jumlah", "Persentase (%)")) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
| Spesies | Jumlah | Persentase (%) |
|---|---|---|
| Adelie | 146 | 43.8 |
| Chinstrap | 68 | 20.4 |
| Gentoo | 119 | 35.7 |
# Visualisasi distribusi spesies
ggplot(penguins, aes(x = species, fill = species)) +
geom_bar() +
geom_text(stat = 'count', aes(label = after_stat(count)), vjust = -0.5) +
labs(title = "Distribusi Spesies Penguin",
x = "Spesies",
y = "Jumlah") +
theme(legend.position = "none")
# Menghitung jumlah penguin per pulau
island_count <- penguins %>%
count(island) %>%
mutate(percentage = round(n / sum(n) * 100, 1))
# Tampilkan dalam bentuk tabel
island_count %>%
kable(col.names = c("Pulau", "Jumlah", "Persentase (%)")) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
| Pulau | Jumlah | Persentase (%) |
|---|---|---|
| Biscoe | 163 | 48.9 |
| Dream | 123 | 36.9 |
| Torgersen | 47 | 14.1 |
# Membuat tabel kontingensi
species_island <- table(penguins$species, penguins$island)
species_island_df <- as.data.frame(species_island)
names(species_island_df) <- c("Species", "Island", "Count")
# Visualisasi dengan facet
ggplot(penguins, aes(x = species, fill = species)) +
geom_bar() +
facet_wrap(~island) +
labs(title = "Distribusi Spesies Penguin di Setiap Pulau",
x = "Spesies",
y = "Jumlah") +
theme(legend.position = "none",
axis.text.x = element_text(angle = 45, hjust = 1))
# Menghitung jumlah penguin per jenis kelamin
sex_count <- penguins %>%
count(sex) %>%
mutate(percentage = round(n / sum(n) * 100, 1))
# Tampilkan dalam bentuk tabel
sex_count %>%
kable(col.names = c("Jenis Kelamin", "Jumlah", "Persentase (%)")) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
| Jenis Kelamin | Jumlah | Persentase (%) |
|---|---|---|
| female | 165 | 49.5 |
| male | 168 | 50.5 |
# Visualisasi distribusi jenis kelamin per spesies
ggplot(penguins, aes(x = sex, fill = sex)) +
geom_bar() +
facet_wrap(~species) +
labs(title = "Distribusi Jenis Kelamin Penguin per Spesies",
x = "Jenis Kelamin",
y = "Jumlah") +
theme(legend.position = "bottom")
# Membuat dataset dari variabel numerik
numeric_vars <- penguins %>%
select(bill_length_mm, bill_depth_mm, flipper_length_mm, body_mass_g)
# Menghitung korelasi
cor_matrix <- cor(numeric_vars)
# Heatmap korelasi
ggplot(as.data.frame(as.table(cor_matrix)),
aes(x = Var1, y = Var2, fill = Freq)) +
geom_tile() +
geom_text(aes(label = round(Freq, 2)), color = "black", size = 4) +
scale_fill_gradient2(low = "blue", high = "red", mid = "white",
midpoint = 0, limit = c(-1, 1), name = "Korelasi") +
labs(title = "Heatmap Korelasi Antar Variabel Numerik",
x = "",
y = "") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
Interpretasi Eksplorasi dan Visualisasi Data:
Karakteristik Penguin:
Korelasi Antar Variabel:
set.seed(123)
numeric_vars <- penguins %>%
select(species,bill_length_mm, bill_depth_mm, flipper_length_mm, body_mass_g)
penguins<-numeric_vars
# Standarisasi fitur
# menghindari atribut dalam rentang angka yang lebih besar mendominasi atribut dalam rentang angka yang lebih kecil
penguins[, 2:5] <- scale(penguins[, 2:5])
# 80% data latih, 20% data test
split <- createDataPartition(penguins$species, p = 0.8, list = FALSE)
train_data <- penguins[split, ]
test_data <- penguins[-split, ]
# Melihat pembagian data
cat("Ukuran data pelatihan:", dim(train_data)[1], "baris\n")
## Ukuran data pelatihan: 268 baris
cat("Ukuran data pengujian:", dim(test_data)[1], "baris\n")
## Ukuran data pengujian: 65 baris
# Memeriksa distribusi kelas di kedua set data
train_dist <- table(train_data$species)
test_dist <- table(test_data$species)
par(mfrow = c(1, 2), mar = c(5, 4, 6, 2))
barplot(train_dist, main = "Data Pelatihan",
col = c("salmon", "lightblue", "lightgreen"), las = 2)
barplot(test_dist, main = "Data Pengujian",
col = c("salmon", "lightblue", "lightgreen"), las = 2)
Pada SVM linear, dicari hyperplane linear optimal yang dapat memisahkan data:
\[\min_{w, b} \frac{1}{2} ||w||^2\]
dengan syarat \(y_i(w^T x_i + b) \geq 1\) untuk semua data \(i\), di mana:
# Model SVM linear
svm_linear <- svm(species ~ ., data = train_data, kernel = "linear", cost = 1,scale=FALSE)
# Ringkasan model
summary(svm_linear)
##
## Call:
## svm(formula = species ~ ., data = train_data, kernel = "linear",
## cost = 1, scale = FALSE)
##
##
## Parameters:
## SVM-Type: C-classification
## SVM-Kernel: linear
## cost: 1
##
## Number of Support Vectors: 20
##
## ( 9 3 8 )
##
##
## Number of Classes: 3
##
## Levels:
## Adelie Chinstrap Gentoo
# Prediksi menggunakan model linear
pred_linear <- predict(svm_linear, test_data)
# Evaluasi model dengan confusion matrix
conf_linear <- confusionMatrix(pred_linear, test_data$species)
conf_linear
## Confusion Matrix and Statistics
##
## Reference
## Prediction Adelie Chinstrap Gentoo
## Adelie 29 2 0
## Chinstrap 0 11 0
## Gentoo 0 0 23
##
## Overall Statistics
##
## Accuracy : 0.9692
## 95% CI : (0.8932, 0.9963)
## No Information Rate : 0.4462
## P-Value [Acc > NIR] : < 2.2e-16
##
## Kappa : 0.951
##
## Mcnemar's Test P-Value : NA
##
## Statistics by Class:
##
## Class: Adelie Class: Chinstrap Class: Gentoo
## Sensitivity 1.0000 0.8462 1.0000
## Specificity 0.9444 1.0000 1.0000
## Pos Pred Value 0.9355 1.0000 1.0000
## Neg Pred Value 1.0000 0.9630 1.0000
## Prevalence 0.4462 0.2000 0.3538
## Detection Rate 0.4462 0.1692 0.3538
## Detection Prevalence 0.4769 0.1692 0.3538
## Balanced Accuracy 0.9722 0.9231 1.0000
# Menyimpan metrik performa
linear_metrics <- conf_linear$byClass
# Mengambil kolom Precision, Recall dan F1
linear_metrics_df <- data.frame(
Precision = linear_metrics[, "Precision"],
Recall = linear_metrics[, "Recall"],
F1 = linear_metrics[, "F1"]
)
print(linear_metrics_df)
## Precision Recall F1
## Class: Adelie 0.9354839 1.0000000 0.9666667
## Class: Chinstrap 1.0000000 0.8461538 0.9166667
## Class: Gentoo 1.0000000 1.0000000 1.0000000
# Fungsi untuk memplot model SVM
plot_svm <- function(model, title) {
plot(model, data = train_data, bill_length_mm ~ bill_depth_mm,
main = title)
}
# Plot model SVM linear
plot_svm(svm_linear, "SVM Linear")
Untuk data yang tidak dapat dipisahkan secara linear, SVM menggunakan
kernel trick untuk memetakan data ke dimensi yang lebih tinggi
di mana pemisahan linear mungkin dilakukan. Dengan menggunakan fungsi
kernel, dapat menyelesaikan masalah klasifikasi yang kompleks tanpa
perlu secara eksplisit menghitung fitur baru dalam dimensi tinggi.
Hal ini membuat SVM menjadi algoritma yang sangat fleksibel, efisien
secara komputasi, dan kuat dalam menghadapi data nonlinier. Kernel yang
umum digunakan adalah:
\[ K(x_i, x_j) = x_i^T x_j \]
\[ K(x_i, x_j) = (x_i^T x_j + c)^d \]
\[ K(x_i, x_j) = \exp(-\gamma \|x_i - x_j\|^2) \]
\[ K(x_i, x_j) = \tanh(\alpha x_i^T x_j + c) \]
Pada perhitungan ini akan digunakan Kernel RBF
# Model SVM Non-linear(RBF)
svm_rbf <- svm(species ~ ., data = train_data,
kernel = "radial", cost = 1, gamma = 0.1, scale = FALSE)
# Ringkasan model
summary(svm_rbf)
##
## Call:
## svm(formula = species ~ ., data = train_data, kernel = "radial",
## cost = 1, gamma = 0.1, scale = FALSE)
##
##
## Parameters:
## SVM-Type: C-classification
## SVM-Kernel: radial
## cost: 1
##
## Number of Support Vectors: 54
##
## ( 23 9 22 )
##
##
## Number of Classes: 3
##
## Levels:
## Adelie Chinstrap Gentoo
# Prediksi pada data pengujian - FIXED: Remove $species from test_data
predictions_rbf <- predict(svm_rbf, test_data)
# Matriks konfusi
conf_matrix_rbf <- confusionMatrix(predictions_rbf, test_data$species)
conf_matrix_rbf
## Confusion Matrix and Statistics
##
## Reference
## Prediction Adelie Chinstrap Gentoo
## Adelie 28 2 0
## Chinstrap 1 11 0
## Gentoo 0 0 23
##
## Overall Statistics
##
## Accuracy : 0.9538
## 95% CI : (0.871, 0.9904)
## No Information Rate : 0.4462
## P-Value [Acc > NIR] : < 2.2e-16
##
## Kappa : 0.927
##
## Mcnemar's Test P-Value : NA
##
## Statistics by Class:
##
## Class: Adelie Class: Chinstrap Class: Gentoo
## Sensitivity 0.9655 0.8462 1.0000
## Specificity 0.9444 0.9808 1.0000
## Pos Pred Value 0.9333 0.9167 1.0000
## Neg Pred Value 0.9714 0.9623 1.0000
## Prevalence 0.4462 0.2000 0.3538
## Detection Rate 0.4308 0.1692 0.3538
## Detection Prevalence 0.4615 0.1846 0.3538
## Balanced Accuracy 0.9550 0.9135 1.0000
# Menyimpan metrik performa
rbf_metrics <- conf_matrix_rbf$byClass
# Mengambil kolom Precision, Recall dan F1
rbf_metrics_df <- data.frame(
Precision = rbf_metrics[, "Precision"],
Recall = rbf_metrics[, "Recall"],
F1 = rbf_metrics[, "F1"]
)
print(rbf_metrics_df)
## Precision Recall F1
## Class: Adelie 0.9333333 0.9655172 0.9491525
## Class: Chinstrap 0.9166667 0.8461538 0.8800000
## Class: Gentoo 1.0000000 1.0000000 1.0000000
# Fungsi untuk memplot model SVM
plot_svm <- function(model, title) {
plot(model, data = train_data, bill_length_mm ~ bill_depth_mm,
main = title)
}
# Plot model SVM RBF
plot_svm(svm_rbf, "SVM RBF")
# ========================== EVALUASI LINEAR ==========================
accuracy_linear <- conf_linear$overall['Accuracy']
if (!is.null(conf_linear$byClass) && is.matrix(conf_linear$byClass)) {
precision_linear <- conf_linear$byClass[, 'Pos Pred Value']
recall_linear <- conf_linear$byClass[, 'Sensitivity']
f1_linear <- conf_linear$byClass[, 'F1']
} else {
precision_linear <- c(conf_linear$byClass['Pos Pred Value'])
recall_linear <- c(conf_linear$byClass['Sensitivity'])
f1_linear <- c(conf_linear$byClass['F1'])
}
precision_linear[is.na(precision_linear)] <- 0
recall_linear[is.na(recall_linear)] <- 0
f1_linear[is.na(f1_linear)] <- 0
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)
)
# ========================== EVALUASI RBF ==========================
accuracy_rbf <- conf_matrix_rbf$overall['Accuracy']
if (!is.null(conf_matrix_rbf$byClass) && is.matrix(conf_matrix_rbf$byClass)) {
precision_rbf <- conf_matrix_rbf$byClass[, 'Pos Pred Value']
recall_rbf <- conf_matrix_rbf$byClass[, 'Sensitivity']
f1_rbf <- conf_matrix_rbf$byClass[, 'F1']
} else {
precision_rbf <- c(conf_matrix_rbf$byClass['Pos Pred Value'])
recall_rbf <- c(conf_matrix_rbf$byClass['Sensitivity'])
f1_rbf <- c(conf_matrix_rbf$byClass['F1'])
}
precision_rbf[is.na(precision_rbf)] <- 0
recall_rbf[is.na(recall_rbf)] <- 0
f1_rbf[is.na(f1_rbf)] <- 0
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)
)
# ========================== KOMPARASI ==========================
# Pastikan struktur 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, ]
comparison <- data.frame(
Metrics = eval_linear_subset$Metrics,
SVM_Linear = eval_linear_subset$Values,
SVM_RBF = eval_rbf_subset$Values
)
# Menampilkan tabel
print(kable(comparison, digits = 4, caption = "Perbandingan Performa SVM Linear vs RBF"))
##
##
## Table: Perbandingan Performa SVM Linear vs RBF
##
## |Metrics | SVM_Linear| SVM_RBF|
## |:--------------------------|----------:|-------:|
## |Accuracy | 0.9692| 0.9538|
## |Precision_Class: Adelie | 0.9355| 0.9333|
## |Precision_Class: Chinstrap | 1.0000| 0.9167|
## |Precision_Class: Gentoo | 1.0000| 1.0000|
## |Recall_Class: Adelie | 1.0000| 0.9655|
## |Recall_Class: Chinstrap | 0.8462| 0.8462|
## |Recall_Class: Gentoo | 1.0000| 1.0000|
## |F1_Class: Adelie | 0.9667| 0.9492|
## |F1_Class: Chinstrap | 0.9167| 0.8800|
## |F1_Class: Gentoo | 1.0000| 1.0000|
Berdasarkan evaluasi performa model F1-Score, karena merupakan rata-rata harmonik dari precision dan recall, serta memberikan keseimbangan antara kedua metrik tersebut. F1-Score sangat penting dalam kasus klasifikasi multikelas seperti ini untuk meminimalkan kesalahan tipe I (false positive) dan tipe II (false negative) secara bersamaan.
Model SVM Linear menunjukkan performa yang lebih baik secara keseluruhan dibandingkan SVM RBF, terutama dalam hal stabilitas performa antar kelas.
F1-Score untuk masing-masing kelas pada kedua model adalah sebagai berikut:
Berdasarkan hasil di atas, SVM Linear direkomendasikan sebagai model terbaik karena:
# Ekstrak koefisien dari model SVM linear
coefs <- t(svm_linear$coefs) %*% svm_linear$SV
# Hitung importance berdasarkan absolute value koefisien
feature_importance <- apply(abs(coefs), 2, mean)
names(feature_importance) <- colnames(train_data)[-which(names(train_data) == "species")]
# Urutkan dan ambil 2 fitur teratas
top_2_features <- sort(feature_importance, decreasing = TRUE)[1:2]
print("2 Fitur Paling Penting (berdasarkan koefisien SVM):")
## [1] "2 Fitur Paling Penting (berdasarkan koefisien SVM):"
print(top_2_features)
## flipper_length_mm body_mass_g
## 4.536611 3.987452
# Fungsi untuk memplot model SVM dengan 2 fitur penting
plot_svm <- function(model, title) {
plot(model, data = train_data, body_mass_g~flipper_length_mm,
main = title)
}
# Plot model SVM linear
plot_svm(svm_linear, "SVM Linear")
# 1. PENGARUH PARAMETER C (SVM Linear)
c_values <- c(0.01, 0.1, 1, 10, 100)
c_results <- data.frame()
for(c_val in c_values) {
svm_model <- svm(species ~ ., data = train_data,
kernel = "linear", cost = c_val, scale = FALSE)
pred <- predict(svm_model, test_data)
accuracy <- mean(pred == test_data$species)
c_results <- rbind(c_results,
data.frame(C = c_val,
Accuracy = accuracy,
Support_Vectors = nrow(svm_model$SV)))
}
c_results$C_Label <- paste("C =", c_results$C)
c_results$Accuracy_Pct <- paste0(round(c_results$Accuracy * 100, 1), "%")
print(c_results[, c("C_Label", "Accuracy_Pct", "Support_Vectors")])
## C_Label Accuracy_Pct Support_Vectors
## 1 C = 0.01 92.3% 155
## 2 C = 0.1 93.8% 61
## 3 C = 1 96.9% 20
## 4 C = 10 95.4% 12
## 5 C = 100 96.9% 10
# 2. PENGARUH PARAMETER GAMMA (SVM RBF)
gamma_values <- c(0.001, 0.01, 0.1, 1, 10)
gamma_results <- data.frame()
for(gamma_val in gamma_values) {
svm_model <- svm(species ~ ., data = train_data,
kernel = "radial", cost = 1, gamma = gamma_val, scale = FALSE)
pred <- predict(svm_model, test_data)
accuracy <- mean(pred == test_data$species)
gamma_results <- rbind(gamma_results,
data.frame(Gamma = gamma_val,
Accuracy = accuracy,
Support_Vectors = nrow(svm_model$SV)))
}
gamma_results$Gamma_Label <- paste("Gamma =", gamma_results$Gamma)
gamma_results$Accuracy_Pct <- paste0(round(gamma_results$Accuracy * 100, 1), "%")
print(gamma_results[, c("Gamma_Label", "Accuracy_Pct", "Support_Vectors")])
## Gamma_Label Accuracy_Pct Support_Vectors
## 1 Gamma = 0.001 80% 223
## 2 Gamma = 0.01 95.4% 122
## 3 Gamma = 0.1 95.4% 54
## 4 Gamma = 1 93.8% 71
## 5 Gamma = 10 83.1% 254
Parameter C (SVM Linear): Parameter regularisasi yang mengontrol trade-off antara mencapai margin maksimal dan meminimalkan kesalahan klasifikasi.
Parameter Gamma (untuk RBF): Parameter kernel yang mengontrol pengaruhdari setiap titik data.
Dari analisis yang telah dilakukan pada dataset Palmer Penguins, dapat disimpulkan bahwa:
SVM Linear menunjukkan performa dengan akurasi sebesar 96% dibandingkan SVM RBF yang mencapai 93%.
F1-Score rata-rata untuk SVM Linear lebih konsisten di semua kelas spesies penguin.
Kedua model menunjukkan performa sempurna (F1-Score = 1) untuk klasifikasi spesies Gentoo, menunjukkan bahwa spesies ini memiliki karakteristik yang sangat distinktif.
Separability yang baik: Data dapat dipisahkan dengan relatif mudah menggunakan hyperplane linear.
Fitur numerik yang relevan: Keempat fitur morfologi (panjang paruh, kedalaman paruh, panjang flipper, dan massa tubuh) memberikan informasi yang cukup untuk klasifikasi.
Berdasarkan analisis koefisien SVM Linear, Body mass dan flipper length merupakan fitur paling penting untuk klasifikasi. Hal ini konsisten dengan visualisasi data yang menunjukkan korelasi kuat antara kedua fitur tersebut.
Penguin Gentoo dapat dibedakan dengan jelas berdasarkan massa tubuh dan panjang flipper yang lebih besar.
Parameter C = 1 memberikan keseimbangan optimal antara margin maksimum dan akurasi klasifikasi.
Parameter Gamma = 0.1 pada kernel RBF memberikan kompleksitas model yang tepat tanpa overfitting.