1 Pendahuluan

Kanker payudara merupakan salah satu penyakit yang membutuhkan proses identifikasi dan diagnosis yang akurat. Dalam analisis berbasis data, karakteristik inti sel hasil pemeriksaan dapat digunakan untuk membantu membedakan apakah suatu tumor tergolong ganas atau jinak. Oleh karena itu, pendekatan machine learning dapat digunakan sebagai alat bantu analitik untuk mengenali pola pada data dan membangun model klasifikasi yang terukur.

Penelitian ini menggunakan metode Support Vector Machine (SVM) untuk mengklasifikasikan diagnosis kanker payudara menjadi dua kelas, yaitu Malignant dan Benign. SVM dipilih karena sesuai untuk permasalahan klasifikasi dengan banyak prediktor numerik. Selain itu, SVM memungkinkan perbandingan antara model dengan kernel linear dan kernel radial/RBF, sehingga dapat dianalisis apakah pola pemisahan antarkelas lebih sesuai dengan batas linear atau non-linear.

Tujuan penelitian ini adalah membangun model klasifikasi diagnosis kanker payudara menggunakan SVM serta mengevaluasi performanya menggunakan confusion matrix, accuracy, sensitivity, specificity, ROC curve, dan AUC.

Pertanyaan analisis dalam penelitian ini adalah:

Dapatkah karakteristik inti sel digunakan untuk mengklasifikasikan tumor sebagai Malignant atau Benign menggunakan Support Vector Machine?

2 Deskripsi Data

Dataset yang digunakan adalah Breast Cancer Wisconsin Diagnostic Dataset yang diperoleh dari UCI Machine Learning Repository. Dataset ini berisi karakteristik inti sel dari sampel tumor payudara.

Unit observasi dalam dataset ini adalah sampel tumor payudara. Variabel respons yang digunakan adalah diagnosis, yang terdiri dari dua kelas:

Kelas Keterangan
Malignant Tumor ganas
Benign Tumor jinak

Prediktor yang digunakan berupa karakteristik inti sel, antara lain radius, texture, perimeter, area, smoothness, compactness, concavity, concave_points, symmetry, dan fractal_dimension. Setiap karakteristik memiliki tiga bentuk pengukuran, yaitu nilai mean, standard error, dan worst value.

required_packages <- c("tidyverse", "tidymodels", "kernlab", "knitr")

missing_packages <- required_packages[
  !(required_packages %in% installed.packages()[, "Package"])
]

if (length(missing_packages) > 0) {
  stop(
    paste0(
      "Paket berikut belum terinstal: ",
      paste(missing_packages, collapse = ", "),
      ". Jalankan install.packages() terlebih dahulu."
    )
  )
}

library(tidyverse)
library(tidymodels)
library(kernlab)
library(knitr)

set.seed(15062026)
url_wdbc <- paste0(
  "https://archive.ics.uci.edu/ml/machine-learning-databases/",
  "breast-cancer-wisconsin/wdbc.data"
)

feature_names <- c(
  "radius", "texture", "perimeter", "area", "smoothness",
  "compactness", "concavity", "concave_points", "symmetry",
  "fractal_dimension"
)

col_names <- c(
  "id", "diagnosis",
  paste0(feature_names, "_mean"),
  paste0(feature_names, "_se"),
  paste0(feature_names, "_worst")
)

wdbc <- readr::read_csv(
  url_wdbc,
  col_names = col_names,
  show_col_types = FALSE
) |>
  mutate(
    diagnosis = factor(
      if_else(diagnosis == "M", "Malignant", "Benign"),
      levels = c("Malignant", "Benign")
    )
  )
jumlah_observasi <- nrow(wdbc)
jumlah_variabel <- ncol(wdbc)

ringkasan_dimensi <- data.frame(
  Komponen = c(
    "Jumlah observasi",
    "Jumlah variabel",
    "Variabel respons",
    "Variabel ID",
    "Prediktor numerik"
  ),
  Jumlah = c(
    jumlah_observasi,
    jumlah_variabel,
    1,
    1,
    jumlah_variabel - 2
  )
)

kable(
  ringkasan_dimensi,
  caption = "Tabel 1. Ringkasan Dimensi Dataset"
)
Tabel 1. Ringkasan Dimensi Dataset
Komponen Jumlah
Jumlah observasi 569
Jumlah variabel 32
Variabel respons 1
Variabel ID 1
Prediktor numerik 30

Interpretasi Tabel 1. Dataset terdiri dari 569 observasi dan 32 variabel. Satu variabel berperan sebagai identitas observasi, satu variabel merupakan respons diagnosis, sedangkan 30 variabel lainnya merupakan prediktor numerik. Struktur data ini sesuai untuk pemodelan SVM karena seluruh prediktor utama berbentuk numerik.

tipe_variabel <- tibble(
  Tipe_Variabel = c("Variabel numerik", "Variabel faktor", "Variabel karakter"),
  Jumlah = c(
    sum(purrr::map_lgl(wdbc, is.numeric)),
    sum(purrr::map_lgl(wdbc, is.factor)),
    sum(purrr::map_lgl(wdbc, is.character))
  )
)

kable(
  tipe_variabel,
  caption = "Tabel 2. Ringkasan Tipe Variabel"
)
Tabel 2. Ringkasan Tipe Variabel
Tipe_Variabel Jumlah
Variabel numerik 31
Variabel faktor 1
Variabel karakter 0

Interpretasi Tabel 2. Sebagian besar variabel pada dataset merupakan variabel numerik. Hal ini mendukung penggunaan SVM karena metode tersebut bekerja dengan membentuk batas pemisah berdasarkan posisi observasi dalam ruang prediktor numerik. Variabel diagnosis sudah berbentuk faktor sehingga dapat digunakan sebagai target klasifikasi.

3 Prapemrosesan dan Exploratory Data Analysis

Tahap prapemrosesan dilakukan untuk memastikan data siap digunakan dalam pemodelan. Pemeriksaan pertama dilakukan terhadap data hilang (missing value), karena keberadaan data hilang dapat mengganggu proses pelatihan dan evaluasi model.

total_missing <- sum(is.na(wdbc))

missing_table <- data.frame(
  Pemeriksaan = "Total missing value",
  Hasil = total_missing
)

kable(
  missing_table,
  caption = "Tabel 3. Pemeriksaan Missing Value"
)
Tabel 3. Pemeriksaan Missing Value
Pemeriksaan Hasil
Total missing value 0

Interpretasi Tabel 3. Hasil pemeriksaan menunjukkan bahwa total missing value adalah 0. Dengan demikian, dataset tidak memerlukan proses imputasi dan dapat langsung digunakan pada tahap eksplorasi serta pemodelan setelah dilakukan standardisasi prediktor.

3.1 Distribusi Kelas Diagnosis

class_distribution <- wdbc |>
  count(diagnosis) |>
  mutate(
    proporsi = n / sum(n),
    persen = proporsi * 100
  )

kable(
  class_distribution,
  digits = 3,
  caption = "Tabel 4. Distribusi Kelas Diagnosis"
)
Tabel 4. Distribusi Kelas Diagnosis
diagnosis n proporsi persen
Malignant 212 0.373 37.258
Benign 357 0.627 62.742

Interpretasi Tabel 4. Terdapat 212 observasi Malignant atau sekitar 37.3%, dan 357 observasi Benign atau sekitar 62.7%. Kelas Benign lebih dominan dibandingkan kelas Malignant, sehingga pembagian data perlu dilakukan secara stratified agar proporsi kelas tetap terjaga.

ggplot(class_distribution, aes(x = diagnosis, y = n)) +
  geom_col(fill = "#9bcfe0") +
  geom_text(aes(label = n), vjust = -0.5, size = 5, color = "#23627c") +
  scale_y_continuous(expand = expansion(mult = c(0, 0.15))) +
  labs(
    title = "Distribusi Kelas Diagnosis",
    x = "Diagnosis",
    y = "Jumlah Observasi"
  ) +
  theme_minimal()
Gambar 1. Distribusi Kelas Diagnosis

Gambar 1. Distribusi Kelas Diagnosis

Interpretasi Gambar 1. Gambar 1 memperlihatkan bahwa jumlah kasus Benign lebih banyak dibandingkan kasus Malignant. Perbedaan distribusi ini tidak terlalu ekstrem, namun tetap perlu diperhatikan karena model klasifikasi dapat dipengaruhi oleh distribusi kelas. Oleh karena itu, strategi stratified split digunakan pada tahap pembagian data.

3.2 Pembagian Data Latih dan Data Uji

Data dibagi menjadi data latih dan data uji dengan proporsi 80:20. Pembagian dilakukan secara stratified berdasarkan variabel diagnosis agar proporsi kelas Malignant dan Benign tetap terjaga.

set.seed(15062026)

split_obj <- initial_split(
  wdbc,
  prop = 0.80,
  strata = diagnosis
)

train_dat <- training(split_obj)
test_dat  <- testing(split_obj)

split_table <- data.frame(
  Jenis_Data = c("Data latih", "Data uji"),
  Jumlah_Observasi = c(nrow(train_dat), nrow(test_dat))
)

kable(
  split_table,
  caption = "Tabel 5. Jumlah Observasi Data Latih dan Data Uji"
)
Tabel 5. Jumlah Observasi Data Latih dan Data Uji
Jenis_Data Jumlah_Observasi
Data latih 454
Data uji 115

Interpretasi Tabel 5. Dataset dibagi menjadi 454 observasi data latih dan 115 observasi data uji. Data latih digunakan untuk pemodelan dan tuning, sedangkan data uji hanya digunakan setelah model final ditetapkan. Pemisahan ini penting agar evaluasi akhir mencerminkan performa model pada data yang belum digunakan dalam pelatihan.

train_distribution <- train_dat |>
  count(diagnosis) |>
  mutate(
    proporsi = n / sum(n),
    persen = proporsi * 100
  )

test_distribution <- test_dat |>
  count(diagnosis) |>
  mutate(
    proporsi = n / sum(n),
    persen = proporsi * 100
  )

kable(
  train_distribution,
  digits = 3,
  caption = "Tabel 6. Distribusi Kelas pada Data Latih"
)
Tabel 6. Distribusi Kelas pada Data Latih
diagnosis n proporsi persen
Malignant 169 0.372 37.225
Benign 285 0.628 62.775
kable(
  test_distribution,
  digits = 3,
  caption = "Tabel 7. Distribusi Kelas pada Data Uji"
)
Tabel 7. Distribusi Kelas pada Data Uji
diagnosis n proporsi persen
Malignant 43 0.374 37.391
Benign 72 0.626 62.609

Interpretasi Tabel 6 dan Tabel 7. Distribusi kelas pada data latih dan data uji relatif serupa dengan distribusi pada data awal. Pada data latih, proporsi Malignant sekitar 37.2%, sedangkan pada data uji sekitar 37.4%. Hal ini menunjukkan bahwa stratified split berhasil mempertahankan proporsi kelas sehingga evaluasi model menjadi lebih representatif.

3.3 Standardisasi Prediktor

Karena metode SVM sensitif terhadap skala variabel, seluruh prediktor numerik distandardisasi. Proses standardisasi dilakukan berdasarkan data latih melalui recipe pemodelan, kemudian diterapkan secara konsisten pada data uji. Variabel id tidak digunakan sebagai prediktor karena hanya berfungsi sebagai identitas observasi.

set.seed(15062026)

folds <- vfold_cv(
  train_dat,
  v = 5,
  strata = diagnosis
)

rec_svm <- recipe(diagnosis ~ ., data = train_dat) |>
  update_role(id, new_role = "id") |>
  step_zv(all_predictors()) |>
  step_normalize(all_numeric_predictors())

svm_metrics <- metric_set(
  roc_auc,
  accuracy,
  sens,
  spec
)

4 Metode

Metode yang digunakan dalam penelitian ini adalah Support Vector Machine (SVM) untuk klasifikasi. SVM bekerja dengan mencari hyperplane terbaik yang memisahkan observasi ke dalam kelas tertentu. Dalam penelitian ini, kelas yang diprediksi adalah Malignant dan Benign.

Dua model SVM dibangun dan dibandingkan, yaitu:

  1. SVM Linear
  2. SVM Radial/RBF

SVM Linear digunakan untuk membentuk batas klasifikasi linear antarkelas. SVM Radial/RBF digunakan untuk menangkap kemungkinan hubungan non-linear antar prediktor.

Tuning model dilakukan menggunakan 5-fold cross-validation pada data latih. Data uji tidak digunakan dalam proses tuning, melainkan hanya digunakan setelah model final ditetapkan. Hal ini dilakukan agar evaluasi performa model pada data uji tetap objektif.

Parameter tuning yang digunakan adalah:

Model Parameter Tuning
SVM Linear cost
SVM Radial/RBF cost, rbf_sigma

Metrik evaluasi yang digunakan adalah:

Metrik Fungsi
Accuracy Mengukur proporsi prediksi yang benar secara keseluruhan
Sensitivity Mengukur kemampuan model mengenali kelas Malignant
Specificity Mengukur kemampuan model mengenali kelas Benign
ROC AUC Mengukur kemampuan model membedakan kelas Malignant dan Benign

Dalam konteks diagnosis kanker payudara, sensitivity kelas Malignant menjadi metrik penting karena kesalahan memprediksi tumor ganas sebagai jinak dapat memiliki implikasi substantif.

5 Hasil Analisis

5.1 Hasil Tuning SVM Linear

svm_linear_spec <- svm_linear(
  cost = tune()
) |>
  set_engine("kernlab", prob.model = TRUE) |>
  set_mode("classification")

svm_linear_wf <- workflow() |>
  add_recipe(rec_svm) |>
  add_model(svm_linear_spec)

linear_grid <- grid_regular(
  cost(range = c(-5, 5)),
  levels = 11
)

set.seed(15062026)

svm_linear_tuned <- tune_grid(
  svm_linear_wf,
  resamples = folds,
  grid = linear_grid,
  metrics = svm_metrics,
  control = control_grid(save_pred = TRUE)
)

linear_tuning_result <- show_best(
  svm_linear_tuned,
  metric = "roc_auc",
  n = 10
)

best_linear <- select_best(
  svm_linear_tuned,
  metric = "roc_auc"
)

kable(
  linear_tuning_result,
  digits = 4,
  caption = "Tabel 8. Hasil Tuning SVM Linear Berdasarkan ROC AUC"
)
Tabel 8. Hasil Tuning SVM Linear Berdasarkan ROC AUC
cost .metric .estimator mean n std_err .config
0.1250 roc_auc binary 0.9940 5 0.0034 pre0_mod03_post0
0.0625 roc_auc binary 0.9938 5 0.0038 pre0_mod02_post0
0.2500 roc_auc binary 0.9936 5 0.0038 pre0_mod04_post0
0.0312 roc_auc binary 0.9935 5 0.0037 pre0_mod01_post0
0.5000 roc_auc binary 0.9930 5 0.0043 pre0_mod05_post0
1.0000 roc_auc binary 0.9924 5 0.0047 pre0_mod06_post0
2.0000 roc_auc binary 0.9916 5 0.0046 pre0_mod07_post0
4.0000 roc_auc binary 0.9904 5 0.0052 pre0_mod08_post0
8.0000 roc_auc binary 0.9877 5 0.0054 pre0_mod09_post0
16.0000 roc_auc binary 0.9868 5 0.0052 pre0_mod10_post0

Interpretasi Tabel 8. Tabel 8 menunjukkan bahwa SVM Linear memperoleh performa validasi terbaik pada parameter cost = 0,125 dengan ROC AUC sekitar 0,9940. Nilai ROC AUC yang tinggi menunjukkan bahwa model linear memiliki kemampuan yang sangat baik dalam membedakan kelas Malignant dan Benign pada proses validasi.

5.2 Hasil Tuning SVM Radial/RBF

svm_rbf_spec <- svm_rbf(
  cost = tune(),
  rbf_sigma = tune()
) |>
  set_engine("kernlab", prob.model = TRUE) |>
  set_mode("classification")

svm_rbf_wf <- workflow() |>
  add_recipe(rec_svm) |>
  add_model(svm_rbf_spec)

rbf_grid <- grid_regular(
  cost(range = c(-5, 5)),
  rbf_sigma(range = c(-10, 0)),
  levels = 5
)

set.seed(15062026)

capture.output({
  svm_rbf_tuned <- tune_grid(
    svm_rbf_wf,
    resamples = folds,
    grid = rbf_grid,
    metrics = svm_metrics,
    control = control_grid(save_pred = TRUE)
  )
})
## [1] "maximum number of iterations reached 2.802898e-05 -2.802898e-05maximum number of iterations reached 0.0001602164 -0.0001602165maximum number of iterations reached 0.0009002941 -0.000900294maximum number of iterations reached 0.0002383682 -0.0002383675maximum number of iterations reached 0.00134179 -0.001341755maximum number of iterations reached 0.007279176 -0.007267246maximum number of iterations reached 0.01398421 -0.01413019maximum number of iterations reached 0.002261472 -0.002247367maximum number of iterations reached 0.009962531 -0.01006283maximum number of iterations reached 0.0002064682 -0.0002054113maximum number of iterations reached 0.005188952 -0.004932812maximum number of iterations reached 2.708259e-05 -2.70826e-05maximum number of iterations reached 0.0001614053 -0.0001614054maximum number of iterations reached 0.0009013422 -0.0009013432maximum number of iterations reached 0.0002410419 -0.0002410412maximum number of iterations reached 0.001357973 -0.00135794maximum number of iterations reached 0.00734312 -0.007330486maximum number of iterations reached 0.01417766 -0.01431639maximum number of iterations reached 0.002105537 -0.002095812maximum number of iterations reached 0.01038929 -0.01047408maximum number of iterations reached 0.0002511309 -0.0002498592maximum number of iterations reached 0.004163258 -0.003963435maximum number of iterations reached 2.820998e-05 -2.820998e-05maximum number of iterations reached 0.0001627906 -0.0001627907maximum number of iterations reached 0.0009130626 -0.0009130618maximum number of iterations reached 0.0002404185 -0.0002404179maximum number of iterations reached 0.001364316 -0.001364276maximum number of iterations reached 0.007330638 -0.007318066maximum number of iterations reached 0.01387721 -0.01406275maximum number of iterations reached 0.002449671 -0.002433636maximum number of iterations reached 0.01012552 -0.01022844maximum number of iterations reached 0.0001962916 -0.0001953071maximum number of iterations reached 0.003285917 -0.003109537maximum number of iterations reached 2.723328e-05 -2.723328e-05maximum number of iterations reached 0.0001543697 -0.0001543697maximum number of iterations reached 0.0008551214 -0.0008551223maximum number of iterations reached 0.0002292887 -0.0002292881maximum number of iterations reached 0.001296177 -0.001296145maximum number of iterations reached 0.006974005 -0.006963716maximum number of iterations reached 0.01406761 -0.01420109maximum number of iterations reached 0.001963362 -0.001950494maximum number of iterations reached 0.01056555 -0.01061921maximum number of iterations reached 0.0001489826 -0.0001481762maximum number of iterations reached 0.003724087 -0.003520188maximum number of iterations reached 2.657578e-05 -2.657579e-05maximum number of iterations reached 0.000149816 -0.0001498161maximum number of iterations reached 0.0008458179 -0.0008458185maximum number of iterations reached 0.0002191465 -0.0002191459maximum number of iterations reached 0.001229212 -0.001229186maximum number of iterations reached 0.006687006 -0.006678164maximum number of iterations reached 0.01445798 -0.01455902maximum number of iterations reached 0.002219538 -0.002206377maximum number of iterations reached 0.0104157 -0.01044693maximum number of iterations reached 0.0002253164 -0.000224121maximum number of iterations reached 0.006048806 -0.005697174"
rbf_tuning_result <- show_best(
  svm_rbf_tuned,
  metric = "roc_auc",
  n = 10
)

best_rbf <- select_best(
  svm_rbf_tuned,
  metric = "roc_auc"
)

kable(
  rbf_tuning_result,
  digits = 4,
  caption = "Tabel 9. Hasil Tuning SVM Radial/RBF Berdasarkan ROC AUC"
)
Tabel 9. Hasil Tuning SVM Radial/RBF Berdasarkan ROC AUC
cost rbf_sigma .metric .estimator mean n std_err .config
32.0000 0.0032 roc_auc binary 0.9938 5 0.0038 pre0_mod24_post0
1.0000 0.0032 roc_auc binary 0.9930 5 0.0031 pre0_mod14_post0
5.6569 0.0032 roc_auc binary 0.9929 5 0.0042 pre0_mod19_post0
0.1768 0.0032 roc_auc binary 0.9891 5 0.0037 pre0_mod09_post0
32.0000 0.0000 roc_auc binary 0.9890 5 0.0037 pre0_mod23_post0
0.0312 0.0000 roc_auc binary 0.9871 5 0.0041 pre0_mod02_post0
0.0312 0.0000 roc_auc binary 0.9871 5 0.0041 pre0_mod03_post0
0.1768 0.0000 roc_auc binary 0.9871 5 0.0041 pre0_mod07_post0
0.1768 0.0000 roc_auc binary 0.9871 5 0.0041 pre0_mod08_post0
1.0000 0.0000 roc_auc binary 0.9871 5 0.0041 pre0_mod12_post0

Interpretasi Tabel 9. Tabel 9 menunjukkan bahwa model SVM Radial/RBF memperoleh performa terbaik pada kombinasi cost = 32 dan rbf_sigma = 0,0032 dengan ROC AUC sekitar 0,9938. Nilai ini sangat tinggi, tetapi masih sedikit lebih rendah dibandingkan hasil terbaik SVM Linear.

autoplot(svm_rbf_tuned) +
  labs(
    title = "Hasil Tuning SVM Radial/RBF",
    subtitle = "Tuning dilakukan dengan 5-fold cross-validation pada data latih"
  ) +
  theme_minimal()
Gambar 2. Hasil Tuning SVM Radial/RBF

Gambar 2. Hasil Tuning SVM Radial/RBF

Interpretasi Gambar 2. Gambar 2 memperlihatkan perubahan performa model SVM Radial/RBF pada berbagai kombinasi parameter cost dan rbf_sigma. Pola grafik menunjukkan bahwa performa model dipengaruhi oleh kombinasi kedua parameter tersebut. Kombinasi terbaik terdapat pada cost = 32 dan rbf_sigma = 0,0032, tetapi peningkatan performanya tidak melebihi SVM Linear.

5.3 Perbandingan Model dan Pemilihan Model Final

best_linear_auc <- show_best(
  svm_linear_tuned,
  metric = "roc_auc",
  n = 1
) |>
  mutate(model = "SVM Linear")

best_rbf_auc <- show_best(
  svm_rbf_tuned,
  metric = "roc_auc",
  n = 1
) |>
  mutate(model = "SVM Radial/RBF")

ringkasan_tuning <- bind_rows(
  best_linear_auc,
  best_rbf_auc
) |>
  select(model, everything()) |>
  arrange(desc(mean))

kable(
  ringkasan_tuning,
  digits = 4,
  caption = "Tabel 10. Ringkasan Perbandingan Tuning SVM Linear dan SVM Radial/RBF"
)
Tabel 10. Ringkasan Perbandingan Tuning SVM Linear dan SVM Radial/RBF
model cost .metric .estimator mean n std_err .config rbf_sigma
SVM Linear 0.125 roc_auc binary 0.9940 5 0.0034 pre0_mod03_post0 NA
SVM Radial/RBF 32.000 roc_auc binary 0.9938 5 0.0038 pre0_mod24_post0 0.0032

Interpretasi Tabel 10. Tabel 10 menunjukkan bahwa SVM Linear memperoleh ROC AUC validasi sebesar 0,9940, sedangkan SVM Radial/RBF memperoleh ROC AUC validasi sebesar 0,9938. Perbedaan keduanya sangat kecil, tetapi SVM Linear tetap memiliki performa validasi yang sedikit lebih tinggi. Oleh karena itu, SVM Linear dipilih sebagai model final. Pemilihan ini juga didukung oleh pertimbangan kesederhanaan model.

if (best_rbf_auc$mean[1] > best_linear_auc$mean[1]) {

  model_terpilih <- "SVM Radial/RBF"

  final_wf <- finalize_workflow(
    svm_rbf_wf,
    best_rbf
  )

} else {

  model_terpilih <- "SVM Linear"

  final_wf <- finalize_workflow(
    svm_linear_wf,
    best_linear
  )
}

model_terpilih
## [1] "SVM Linear"

5.4 Evaluasi Model Final pada Data Uji

Data uji digunakan hanya setelah model final ditetapkan. Dengan demikian, data uji tidak terlibat dalam proses tuning.

set.seed(15062026)

final_fit <- last_fit(
  final_wf,
  split = split_obj,
  metrics = svm_metrics
)

test_metrics <- collect_metrics(final_fit)

pred_test <- collect_predictions(final_fit)

kable(
  test_metrics,
  digits = 4,
  caption = "Tabel 11. Metrik Evaluasi Model Final pada Data Uji"
)
Tabel 11. Metrik Evaluasi Model Final pada Data Uji
.metric .estimator .estimate .config
accuracy binary 0.9739 pre0_mod0_post0
sens binary 0.9535 pre0_mod0_post0
spec binary 0.9861 pre0_mod0_post0
roc_auc binary 0.9958 pre0_mod0_post0

Interpretasi Tabel 11. Model final SVM Linear menghasilkan accuracy sebesar 0,9739, sensitivity sebesar 0,9535, specificity sebesar 0,9861, dan ROC AUC sebesar 0,9958. Nilai ini menunjukkan bahwa model memiliki performa klasifikasi yang sangat baik pada data uji. Sensitivity sebesar 0,9535 menunjukkan bahwa sebagian besar kasus Malignant berhasil dikenali oleh model.

5.5 Confusion Matrix

conf_matrix_table <- pred_test |>
  count(
    Aktual = diagnosis,
    Prediksi = .pred_class,
    name = "Frekuensi"
  ) |>
  complete(
    Aktual = factor(c("Malignant", "Benign"),
                    levels = c("Malignant", "Benign")),
    Prediksi = factor(c("Malignant", "Benign"),
                      levels = c("Malignant", "Benign")),
    fill = list(Frekuensi = 0)
  )

kable(
  conf_matrix_table,
  caption = "Tabel 12. Confusion Matrix Model Final pada Data Uji"
)
Tabel 12. Confusion Matrix Model Final pada Data Uji
Aktual Prediksi Frekuensi
Malignant Malignant 41
Malignant Benign 2
Benign Malignant 1
Benign Benign 71

Interpretasi Tabel 12. Model berhasil mengklasifikasikan 41 kasus Malignant sebagai Malignant dan 71 kasus Benign sebagai Benign. Namun, terdapat 2 kasus Malignant yang salah diprediksi sebagai Benign dan 1 kasus Benign yang salah diprediksi sebagai Malignant. Dengan demikian, terdapat 112 prediksi benar dan 3 prediksi salah dari total 115 observasi data uji.

ggplot(conf_matrix_table, aes(x = Prediksi, y = Aktual, fill = Frekuensi)) +
  geom_tile() +
  geom_text(aes(label = Frekuensi), size = 6, color = "#163f50") +
  scale_y_discrete(limits = c("Benign", "Malignant")) +
  scale_fill_gradient(low = "#eef7fb", high = "#7fbdd4") +
  labs(
    title = paste("Confusion Matrix", model_terpilih, "pada Data Uji"),
    x = "Prediksi",
    y = "Aktual",
    fill = "Frekuensi"
  ) +
  theme_minimal()
Gambar 3. Confusion Matrix SVM Linear pada Data Uji

Gambar 3. Confusion Matrix SVM Linear pada Data Uji

Interpretasi Gambar 3. Gambar 3 memperjelas pola kesalahan klasifikasi model. Sel diagonal menunjukkan prediksi benar, yaitu Malignant diprediksi Malignant dan Benign diprediksi Benign. Sel di luar diagonal menunjukkan kesalahan klasifikasi. Kesalahan yang paling penting adalah 2 kasus Malignant yang diprediksi sebagai Benign, karena termasuk false negative.

5.6 ROC Curve dan AUC

roc_data <- roc_curve(
  pred_test,
  truth = diagnosis,
  .pred_Malignant,
  event_level = "first"
)

autoplot(roc_data) +
  labs(
    title = paste("ROC Curve", model_terpilih),
    subtitle = "Kelas positif: Malignant"
  ) +
  theme_minimal()
Gambar 4. ROC Curve Model SVM Linear

Gambar 4. ROC Curve Model SVM Linear

auc_value <- roc_auc(
  pred_test,
  truth = diagnosis,
  .pred_Malignant,
  event_level = "first"
)

Interpretasi Gambar 4. ROC curve berada dekat dengan sudut kiri atas. Hal ini menunjukkan bahwa model memiliki kemampuan yang sangat baik dalam membedakan kelas Malignant dan Benign pada berbagai ambang probabilitas. Semakin dekat kurva ke sudut kiri atas, semakin baik kemampuan diskriminasi model.

kable(
  auc_value,
  digits = 4,
  caption = "Tabel 13. Nilai AUC Model Final"
)
Tabel 13. Nilai AUC Model Final
.metric .estimator .estimate
roc_auc binary 0.9958

Interpretasi Tabel 13. Nilai AUC sebesar 0,9958 menunjukkan bahwa model SVM Linear memiliki kemampuan diskriminasi yang sangat tinggi. Dengan kata lain, model hampir selalu mampu memberikan skor probabilitas yang lebih tinggi untuk kasus Malignant dibandingkan Benign.

5.7 Tabel Metrik Data Uji dan Kesalahan Klasifikasi

accuracy_value <- accuracy(
  pred_test,
  truth = diagnosis,
  estimate = .pred_class
)

sensitivity_value <- sens(
  pred_test,
  truth = diagnosis,
  estimate = .pred_class,
  event_level = "first"
)

specificity_value <- spec(
  pred_test,
  truth = diagnosis,
  estimate = .pred_class,
  event_level = "first"
)

test_metric_table <- bind_rows(
  accuracy_value,
  sensitivity_value,
  specificity_value,
  auc_value
) |>
  mutate(
    .estimate = round(.estimate, 4)
  )

kable(
  test_metric_table,
  digits = 4,
  caption = "Tabel 14. Tabel Metrik Evaluasi Model Final pada Data Uji"
)
Tabel 14. Tabel Metrik Evaluasi Model Final pada Data Uji
.metric .estimator .estimate
accuracy binary 0.9739
sens binary 0.9535
spec binary 0.9861
roc_auc binary 0.9958

Interpretasi Tabel 14. Keempat metrik menunjukkan performa yang sangat baik. Accuracy yang tinggi menunjukkan ketepatan prediksi secara keseluruhan. Sensitivity sebesar 0,9535 menunjukkan kemampuan model mengenali kasus Malignant, sedangkan specificity sebesar 0,9861 menunjukkan kemampuan model mengenali kasus Benign. AUC sebesar 0,9958 menunjukkan kemampuan diskriminasi kelas yang sangat kuat.

false_negative <- pred_test |>
  filter(
    diagnosis == "Malignant",
    .pred_class == "Benign"
  )

false_positive <- pred_test |>
  filter(
    diagnosis == "Benign",
    .pred_class == "Malignant"
  )

jumlah_false_negative <- nrow(false_negative)
jumlah_false_positive <- nrow(false_positive)

error_table <- data.frame(
  Jenis_Kesalahan = c(
    "False negative: Malignant diprediksi Benign",
    "False positive: Benign diprediksi Malignant"
  ),
  Jumlah = c(
    jumlah_false_negative,
    jumlah_false_positive
  )
)

kable(
  error_table,
  caption = "Tabel 15. Ringkasan Kesalahan Klasifikasi"
)
Tabel 15. Ringkasan Kesalahan Klasifikasi
Jenis_Kesalahan Jumlah
False negative: Malignant diprediksi Benign 2
False positive: Benign diprediksi Malignant 1

Interpretasi Tabel 15. Terdapat 2 kasus false negative, yaitu kasus Malignant yang diprediksi sebagai Benign. Kesalahan ini penting karena dalam konteks diagnosis kanker payudara, tumor ganas yang diprediksi sebagai jinak dapat berimplikasi pada keterlambatan pemeriksaan atau penanganan lanjutan. Selain itu, terdapat 1 kasus false positive, yaitu kasus Benign yang diprediksi sebagai Malignant.

6 Interpretasi dan Diskusi

Secara umum, model SVM Linear menunjukkan performa klasifikasi yang sangat baik pada data uji. Accuracy sebesar 0,9739 menunjukkan bahwa sebagian besar observasi berhasil diklasifikasikan dengan benar. Dari 115 observasi pada data uji, hanya terdapat 3 observasi yang salah diklasifikasikan.

Nilai sensitivity sebesar 0,9535 menunjukkan bahwa model mampu mengenali sebagian besar kasus Malignant. Dari 43 kasus Malignant pada data uji, sebanyak 41 kasus berhasil diprediksi sebagai Malignant. Namun, terdapat 2 kasus Malignant yang salah diprediksi sebagai Benign.

Kesalahan tersebut disebut false negative. Dalam konteks diagnosis kanker payudara, false negative merupakan kesalahan yang penting untuk diperhatikan karena tumor yang sebenarnya ganas dapat diprediksi sebagai jinak. Hal ini dapat berimplikasi pada keterlambatan pemeriksaan lanjutan atau penanganan medis.

Selain itu, terdapat 1 kasus Benign yang diprediksi sebagai Malignant. Kesalahan ini disebut false positive. False positive dapat menyebabkan pemeriksaan lanjutan yang mungkin tidak diperlukan, tetapi risikonya relatif lebih rendah dibandingkan false negative pada kasus Malignant.

Perbandingan antara SVM Linear dan SVM Radial/RBF menunjukkan bahwa kedua model memiliki performa validasi yang sangat tinggi dan sangat dekat. SVM Linear memperoleh ROC AUC validasi sebesar 0,9940, sedangkan SVM Radial/RBF memperoleh ROC AUC validasi sebesar 0,9938. Perbedaan performa yang sangat kecil menunjukkan bahwa penggunaan kernel radial tidak memberikan peningkatan yang berarti dibandingkan kernel linear pada dataset ini.

Dengan demikian, SVM Linear dipilih sebagai model final karena memiliki performa validasi yang sedikit lebih baik dan struktur model yang lebih sederhana. Hasil ini menunjukkan bahwa pola pemisahan antara kelas Malignant dan Benign pada dataset ini dapat ditangani dengan baik oleh model linear.

Keterbatasan penelitian ini adalah model hanya diuji pada satu dataset publik, yaitu Breast Cancer Wisconsin Diagnostic Dataset. Selain itu, model belum divalidasi pada data klinis lain yang lebih beragam. Oleh karena itu, hasil analisis ini sebaiknya dipahami sebagai analisis machine learning berbasis dataset publik dan bukan sebagai pengganti diagnosis medis.

7 Kesimpulan

Penelitian ini bertujuan untuk mengklasifikasikan diagnosis kanker payudara menjadi Malignant dan Benign menggunakan metode Support Vector Machine. Berdasarkan hasil tuning, model terbaik yang diperoleh adalah SVM Linear dengan parameter cost = 0,125.

Pada data uji, model SVM Linear menghasilkan accuracy sebesar 0,9739, sensitivity sebesar 0,9535, specificity sebesar 0,9861, dan ROC AUC sebesar 0,9958. Hasil ini menunjukkan bahwa model memiliki performa klasifikasi yang sangat baik.

Berdasarkan confusion matrix, model berhasil mengklasifikasikan 41 kasus Malignant dan 71 kasus Benign dengan benar. Namun, masih terdapat 2 kasus Malignant yang salah diprediksi sebagai Benign dan 1 kasus Benign yang salah diprediksi sebagai Malignant.

Dengan demikian, karakteristik inti sel pada Breast Cancer Wisconsin Diagnostic Dataset dapat digunakan secara efektif untuk mengklasifikasikan diagnosis kanker payudara menggunakan SVM. Meskipun demikian, perhatian khusus tetap perlu diberikan pada false negative kelas Malignant karena memiliki implikasi substantif dalam konteks diagnosis kanker.

Rekomendasi analitik dari penelitian ini adalah menggunakan model SVM Linear sebagai model yang sederhana dan efektif untuk dataset ini. Namun, untuk penggunaan lebih lanjut, model sebaiknya divalidasi pada dataset klinis lain yang lebih beragam dan dipertimbangkan bersama pengetahuan domain medis.

8 Referensi

UCI Machine Learning Repository. Breast Cancer Wisconsin Diagnostic Dataset.
https://archive.ics.uci.edu/dataset/17/breast+cancer+wisconsin+diagnostic

Posit Documentation. Publishing Documents: RPubs.
https://docs.posit.co/ide/user/ide/guide/publish/publishing.html

Kuhn, M., & Johnson, K. (2013). Applied Predictive Modeling. Springer.

James, G., Witten, D., Hastie, T., & Tibshirani, R. (2021). An Introduction to Statistical Learning: With Applications in R. Springer.