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?
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"
)
| 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"
)
| 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.
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"
)
| 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.
class_distribution <- wdbc |>
count(diagnosis) |>
mutate(
proporsi = n / sum(n),
persen = proporsi * 100
)
kable(
class_distribution,
digits = 3,
caption = "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
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.
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"
)
| 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"
)
| 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"
)
| 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.
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
)
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:
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.
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"
)
| 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.
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"
)
| 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
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.
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"
)
| 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"
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"
)
| .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.
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"
)
| 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
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.
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
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"
)
| .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.
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"
)
| .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"
)
| 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.
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.
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.
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.