K-Nearest Neighbor (k-NN) adalah algoritma klasifikasi non-parametrik yang termasuk dalam kelompok instance-based learning atau lazy learning. Algoritma ini tidak membentuk fungsi model eksplisit pada tahap pelatihan, tetapi menyimpan seluruh data latih dan menentukan kelas data baru berdasarkan mayoritas kelas dari k tetangga terdekatnya (Fransiska, 2026). Karena kedekatan antar observasi dihitung menggunakan metrik jarak, variabel yang berskala besar dapat mendominasi perhitungan sehingga penskalaan fitur menjadi tahap pra-pemrosesan yang penting (Fransiska, 2026; Ardiansyah & Irawan, 2026).
Pengaruh penskalaan terhadap k-NN ditunjukkan oleh Sari dan Brilliant (2026) pada data kanker payudara Wisconsin (569 observasi, 30 atribut, pembagian data 70:30). Pada penelitian tersebut, k-NN yang dijalankan dengan normalisasi min-max mencapai akurasi rata-rata 95,6%, sedangkan tanpa normalisasi hanya 90,6%. Selain penskalaan, kinerja k-NN juga dipengaruhi oleh nilai k. Muhammad (2026) membandingkan k-NN dan Random Forest pada data kanker payudara Wisconsin (Diagnostic) dan melaporkan bahwa k terbaik adalah 5 dengan akurasi 96,49%, presisi 100%, dan recall 90,48%. Pramudita dkk. (2025) juga memakai k-NN pada data yang sama dengan pembagian 70% data latih dan 30% data uji, dan mengevaluasi model melalui confusion matrix untuk memperoleh akurasi, sensitivitas, dan spesifisitas.
Pada diagnosis tumor payudara, jenis kesalahan klasifikasi tidak memiliki dampak yang sama. Tumor ganas (malignant) yang diprediksi sebagai jinak (benign), atau False Negative (FN), berarti pasien berisiko tidak segera mendapat penanganan, sehingga akurasi saja tidak cukup untuk memilih model terbaik dan sensitivitas perlu mendapat perhatian khusus (Pramudita dkk., 2025; Muhammad, 2026).
Oleh karena itu, pada praktikum ini dilakukan klasifikasi
k-NN pada data Wisconsin Breast Cancer Database
(BreastCancer, paket mlbench) untuk mendeteksi
tumor payudara jinak atau ganas. Data dibagi 70% data latih dan 30% data
uji dengan set.seed(12333), lalu model dibangun untuk
k = 3, 5, 7, 9, dan 11. Kinerja setiap model dibandingkan
menggunakan akurasi, sensitivitas, dan spesifisitas, kemudian ditentukan
nilai k paling optimal dengan mempertimbangkan pentingnya
meminimalkan False Negative.
Berdasarkan latar belakang, rumusan masalah yang dapat disimpulkan adalah sebagai berikut:
Berdasarkan rumusan masalah tersebut, tujuan yang dapat disimpulkan adalah sebagai berikut:
Algoritma k-NN pertama kali digagas oleh Fix dan Hodges (1951) dan landasan konvergensinya dibuktikan oleh Cover dan Hart (1967). Berbeda dengan algoritma parametrik yang mengasumsikan bentuk distribusi data tertentu, k-NN menyimpan seluruh data latih dan menunda komputasi sampai ada data baru yang hendak diprediksi (Fransiska, 2026). Kelas data baru ditentukan dari jaraknya ke k observasi latih terdekat di ruang fitur (Ardiansyah & Irawan, 2026).
Diberikan data latih \(D = \{(x_1, y_1), \ldots, (x_n, y_n)\}\) dengan \(x_i \in \mathbb{R}^p\) dan label kelas \(y_i \in \{1, 2, \ldots, C\}\). Untuk data uji \(x_0\), misalkan \(N_k(x_0)\) adalah himpunan k tetangga terdekatnya. Estimasi probabilitas posterior kelas \(j\) adalah proporsi kelas tersebut di antara tetangga (Fransiska, 2026):
\[\hat{P}(Y = j \mid X = x_0) = \frac{1}{k}\sum_{i \in N_k(x_0)} I(y_i = j)\]
dengan \(I(\cdot)\) fungsi indikator yang bernilai 1 jika \(y_i = j\) dan 0 jika sebaliknya. Keputusan klasifikasi diambil dengan prinsip suara terbanyak (majority voting):
\[\hat{G}(x_0) = \arg\max_{j \in \{1,\ldots,C\}} \hat{P}(Y = j \mid X = x_0)\]
Pada klasifikasi dua kelas, memilih k ganjil membuat hasil pemungutan suara tidak seri.
Cover dan Hart (1967) membuktikan bahwa untuk \(n \to \infty\), peluang kesalahan tetangga terdekat tunggal (\(k = 1\)), yaitu \(R\), dibatasi oleh peluang kesalahan pengklasifikasi Bayes optimal \(R^*\) (Fransiska, 2026):
\[R^* \le R \le R^*\left(2 - \frac{C}{C-1}R^*\right) \le 2R^*\]
Artinya, secara asimtotik kesalahan aturan tetangga terdekat paling buruk dua kali kesalahan pengklasifikasi Bayes.
Tabel 1. Pengaruh nilai k terhadap model
| Nilai k | Batas keputusan | Bias | Varians | Risiko |
|---|---|---|---|---|
| Kecil (mis. \(k = 1\)) | Sangat rumit | Rendah | Tinggi | Sensitif terhadap noise dan overfitting |
| Besar (mis. \(k \to n\)) | Sangat halus | Tinggi | Rendah | Underfitting karena dominasi kelas mayoritas |
Sumber: Fransiska (2026).
Karena tidak ada aturan baku untuk nilai k terbaik, penentuannya dilakukan secara empiris dengan membandingkan beberapa nilai k. Muhammad (2026) menegaskan bahwa kinerja k-NN sangat dipengaruhi oleh nilai k dan skala data.
Tabel 2. Metrik jarak pada k-NN
| Metrik | Rumus | Keterangan |
|---|---|---|
| Euclidean (\(L_2\)) | \(d(x,y)=\sqrt{\sum_{i=1}^{p}(x_i-y_i)^2}\) | Paling umum untuk variabel numerik kontinu |
| Manhattan (\(L_1\)) | \(d(x,y)=\sum_{i=1}^{p}\lvert x_i-y_i\rvert\) | Lebih tangguh terhadap pencilan |
| Minkowski (\(L_m\)) | \(d(x,y)=\left(\sum_{i=1}^{p}\lvert x_i-y_i\rvert^m\right)^{1/m}\) | Generalisasi (\(m=1\) Manhattan, \(m=2\) Euclidean) |
| Mahalanobis | \(d(x,y)=\sqrt{(x-y)^\top\Sigma^{-1}(x-y)}\) | Memperhitungkan kovarians antar variabel |
| Hamming | \(d(x,y)=\frac{1}{p}\sum_{i=1}^{p}I(x_i\ne y_i)\) | Untuk data biner atau kategorik |
Sumber: Fransiska (2026).
Fungsi knn() pada paket class yang dipakai
dalam praktikum ini menggunakan jarak Euclidean.
Karena jarak dihitung dari selisih numerik secara langsung, variabel dengan rentang besar akan mendominasi jarak. Dua cara penskalaan yang umum adalah (Fransiska, 2026):
\[x_{scaled} = \frac{x - x_{min}}{x_{max} - x_{min}} \quad (\text{normalisasi } min\text{-}max), \qquad z = \frac{x - \mu}{\sigma} \quad (\text{standardisasi } z\text{-}score)\]
Ardiansyah dan Irawan (2026) menyebutkan bahwa penskalaan terutama diperlukan pada algoritma berbasis jarak seperti k-NN. Sari dan Brilliant (2026) menunjukkan pada data kanker payudara Wisconsin bahwa k-NN dengan normalisasi min-max (akurasi 95,6%) lebih baik daripada tanpa normalisasi (90,6%).
Evaluasi klasifikasi biner dilakukan dengan confusion matrix yang membandingkan kelas aktual dan prediksi (Pramudita dkk., 2025; Sari & Brilliant, 2026). Pada praktikum ini kelas malignant ditetapkan sebagai kelas positif karena kesalahan utama yang ingin diminimalkan adalah tumor ganas yang tidak terdeteksi.
Tabel 3. Confusion matrix (kelas positif = malignant)
| Aktual malignant | Aktual benign | |
|---|---|---|
| Prediksi malignant | True Positive (TP) | False Positive (FP) |
| Prediksi benign | False Negative (FN) | True Negative (TN) |
Sumber: Fransiska (2026); Sari dan Brilliant (2026).
\[Akurasi = \frac{TP+TN}{TP+TN+FP+FN}, \quad Sensitivitas = \frac{TP}{TP+FN}, \quad Spesifisitas = \frac{TN}{TN+FP}, \quad PPV = \frac{TP}{TP+FP}\]
Sensitivitas (recall) menyatakan proporsi tumor ganas yang berhasil terdeteksi sehingga nilai FN yang kecil berarti sensitivitas tinggi. Spesifisitas menyatakan proporsi tumor jinak yang diprediksi jinak, dan nilai FP yang besar berarti banyak pasien jinak yang dicurigai ganas sehingga perlu pemeriksaan lanjutan. Dalam konteks diagnosis, FN lebih berbahaya daripada FP, sehingga pemilihan model memprioritaskan sensitivitas, kemudian akurasi dan spesifisitas.
Data BreastCancer pada paket mlbench
berasal dari pemeriksaan sitologi tumor payudara di University of
Wisconsin Hospitals, terdiri atas 699 observasi dengan 11 kolom:
Id, sembilan variabel karakteristik sel yang dinilai pada
skala 1 sampai 10, dan variabel respons Class
(benign atau malignant). Variabel
Bare.nuclei memiliki beberapa nilai hilang. Variabel
prediktor pada data ini bertipe factor, sehingga perlu diubah
menjadi numerik sebelum dihitung jaraknya.
Jenis data yang digunakan dalam penelitian ini adalah data
kuantitatif. Data yang digunakan adalah Wisconsin Breast Cancer
Database yang dimuat dengan perintah
data(BreastCancer, package = "mlbench"). Setelah
pra-pemrosesan, data dibagi menjadi 70% data latih dan 30% data uji
menggunakan pengambilan sampel acak dengan set.seed(12333)
(NPM ganjil, \(XY = 33\)). Variabel
Class digunakan sebagai variabel respons.
| No | Variabel | Keterangan | Tipe Data | Peran |
|---|---|---|---|---|
| 1 | Class | Jenis tumor (benign = jinak, malignant = ganas) | Kategorik | Respons |
| 2 | Cl.thickness | Ketebalan gumpalan sel | Numerik (1-10) | Prediktor |
| 3 | Cell.size | Keseragaman ukuran sel | Numerik (1-10) | Prediktor |
| 4 | Cell.shape | Keseragaman bentuk sel | Numerik (1-10) | Prediktor |
| 5 | Marg.adhesion | Adhesi marginal | Numerik (1-10) | Prediktor |
| 6 | Epith.c.size | Ukuran sel epitel tunggal | Numerik (1-10) | Prediktor |
| 7 | Bare.nuclei | Inti sel telanjang | Numerik (1-10) | Prediktor |
| 8 | Bl.cromatin | Kromatin halus | Numerik (1-10) | Prediktor |
| 9 | Normal.nucleoli | Nukleolus normal | Numerik (1-10) | Prediktor |
| 10 | Mitoses | Mitosis | Numerik (1-10) | Prediktor |
Kolom Id tidak digunakan karena hanya pengenal
pasien.
Tabel 4. Skenario model yang dibandingkan
| Skenario | Data training | Data testing | Jumlah tetangga (k) |
|---|---|---|---|
| 1 | 70% | 30% | 3 |
| 2 | 70% | 30% | 5 |
| 3 | 70% | 30% | 7 |
| 4 | 70% | 30% | 9 |
| 5 | 70% | 30% | 11 |
class,
caret, mlbench, ggplot2, dan
knitr).BreastCancer, lalu memeriksa struktur,
ringkasan, distribusi kelas, dan missing value.Id, menghapus observasi
dengan missing value, mengubah prediktor menjadi numerik, dan
menormalisasi prediktor dengan min-max.sample() dan set.seed(12333).knn() untuk
k = 3, 5, 7, 9, dan 11.confusionMatrix() (kelas positif = malignant) dan
menghitung akurasi, sensitivitas, spesifisitas, serta nilai FN dan
FP.Pada batasan masalah diminta melakukan klasifikasi k-NN
terhadap data Wisconsin Breast Cancer Database untuk nilai
\(k \in \{3, 5, 7, 9, 11\}\) dengan
pembagian data 70% training dan 30% testing
menggunakan set.seed(12333), kemudian menyusun tabel
perbandingan metrik evaluasi (akurasi, sensitivitas, spesifisitas) dan
menyimpulkan nilai k paling optimal dengan mempertimbangkan
pentingnya meminimalkan False Negative.
Package class menyediakan fungsi
knn(), caret untuk
confusionMatrix(), mlbench untuk data
BreastCancer, ggplot2 untuk visualisasi, dan
knitr untuk menyajikan tabel.
## Id Cl.thickness Cell.size Cell.shape Marg.adhesion Epith.c.size
## 1 1000025 5 1 1 1 2
## 2 1002945 5 4 4 5 7
## 3 1015425 3 1 1 1 2
## 4 1016277 6 8 8 1 3
## 5 1017023 4 1 1 3 2
## 6 1017122 8 10 10 8 7
## Bare.nuclei Bl.cromatin Normal.nucleoli Mitoses Class
## 1 1 3 1 1 benign
## 2 10 3 2 1 benign
## 3 2 3 1 1 benign
## 4 4 3 7 1 benign
## 5 1 3 1 1 benign
## 6 10 9 7 1 malignant
## '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 ...
## [1] 699 11
## Id Cl.thickness Cell.size Cell.shape Marg.adhesion
## Length :699 1 :145 1 :384 1 :353 1 :407
## N.unique :645 5 :130 10 : 67 2 : 59 2 : 58
## N.blank : 0 3 :108 3 : 52 10 : 58 3 : 58
## Min.nchar: 5 4 : 80 2 : 45 3 : 56 10 : 55
## Max.nchar: 8 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 NAs : 16 (Other): 69 (Other): 69 (Other): 17
## Class
## benign :458
## malignant:241
##
##
##
##
##
Data terdiri atas 699 observasi dan 11 variabel, yaitu kolom
Id, 9 variabel prediktor, dan 1 variabel respons
Class. Seluruh prediktor bertipe factor (bernilai
1 sampai 10), sehingga harus diubah menjadi numerik agar jarak dapat
dihitung.
##
## benign malignant
## 458 241
##
## benign malignant
## 65.52 34.48
Kelas benign berjumlah 458 observasi (65,52%) dan malignant 241 observasi (34,48%). Data tidak seimbang secara sempurna karena kelas jinak lebih banyak, sehingga akurasi saja dapat menyesatkan dan sensitivitas perlu diperhatikan.
## Id Cl.thickness Cell.size Cell.shape Marg.adhesion
## 0 0 0 0 0
## Epith.c.size Bare.nuclei Bl.cromatin Normal.nucleoli Mitoses
## 0 16 0 0 0
## Class
## 0
Total terdapat 16 missing value, seluruhnya pada variabel Bare.nuclei. Data yang hilang tidak dapat dipakai dalam perhitungan jarak sehingga perlu ditangani pada pra-pemrosesan.
Pra-pemrosesan terdiri atas empat langkah: menghapus kolom
Id, menghapus observasi yang memiliki missing
value, mengubah prediktor menjadi numerik, dan menormalisasi
prediktor dengan min-max.
# 1. Hapus kolom Id (hanya pengenal pasien)
bc <- bc_raw[, -1]
# 2. Hapus observasi dengan missing value
n_awal <- nrow(bc)
bc <- na.omit(bc)
n_akhir <- nrow(bc)
# 3. Ubah prediktor (factor) menjadi numerik
fitur <- setdiff(names(bc), "Class")
bc[fitur] <- lapply(bc[fitur], function(x) as.numeric(as.character(x)))
bc$Class <- factor(bc$Class, levels = c("benign", "malignant"))
str(bc)## 'data.frame': 683 obs. of 10 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 ...
## $ Class : Factor w/ 2 levels "benign","malignant": 1 1 1 1 1 2 1 1 1 1 ...
## - attr(*, "na.action")= 'omit' Named int [1:16] 24 41 140 146 159 165 236 250 276 293 ...
## ..- attr(*, "names")= chr [1:16] "24" "41" "140" "146" ...
# 4. Normalisasi Min-Max pada prediktor
min_max_norm <- function(x) (x - min(x)) / (max(x) - min(x))
bc_norm <- bc
bc_norm[fitur] <- lapply(bc[fitur], min_max_norm)
summary(bc_norm)## Cl.thickness Cell.size Cell.shape Marg.adhesion
## Min. :0.0000 Min. :0.0000 Min. :0.0000 Min. :0.0000
## 1st Qu.:0.1111 1st Qu.:0.0000 1st Qu.:0.0000 1st Qu.:0.0000
## Median :0.3333 Median :0.0000 Median :0.0000 Median :0.0000
## Mean :0.3825 Mean :0.2390 Mean :0.2461 Mean :0.2034
## 3rd Qu.:0.5556 3rd Qu.:0.4444 3rd Qu.:0.4444 3rd Qu.:0.3333
## Max. :1.0000 Max. :1.0000 Max. :1.0000 Max. :1.0000
## Epith.c.size Bare.nuclei Bl.cromatin Normal.nucleoli
## Min. :0.0000 Min. :0.0000 Min. :0.0000 Min. :0.0000
## 1st Qu.:0.1111 1st Qu.:0.0000 1st Qu.:0.1111 1st Qu.:0.0000
## Median :0.1111 Median :0.0000 Median :0.2222 Median :0.0000
## Mean :0.2483 Mean :0.2827 Mean :0.2717 Mean :0.2077
## 3rd Qu.:0.3333 3rd Qu.:0.5556 3rd Qu.:0.4444 3rd Qu.:0.3333
## Max. :1.0000 Max. :1.0000 Max. :1.0000 Max. :1.0000
## Mitoses Class
## Min. :0.00000 benign :444
## 1st Qu.:0.00000 malignant:239
## Median :0.00000
## Mean :0.06702
## 3rd Qu.:0.00000
## Max. :1.00000
Sebanyak 16 observasi dengan missing value dihapus sehingga tersisa 683 observasi (444 benign dan 239 malignant). Jumlah yang dihapus kecil (2,29% dari data) sehingga penghapusan dipilih daripada imputasi. Seluruh prediktor kini bertipe numerik. Setelah normalisasi min-max, setiap prediktor berada pada rentang 0 sampai 1 (nilai minimum 0,00 dan maksimum 1,00). Walaupun semua variabel awalnya sama-sama berskala 1-10, normalisasi tetap dilakukan sesuai prosedur modul dan karena rentang yang teramati pada tiap variabel dapat berbeda (Sari & Brilliant, 2026).
par(mfrow = c(1, 2))
boxplot(Cell.size ~ Class, data = bc, col = c("#A5D6A7", "#EF9A9A"),
main = "Cell.size menurut Class", xlab = "Class", ylab = "Skor (1-10)")
boxplot(Bare.nuclei ~ Class, data = bc, col = c("#A5D6A7", "#EF9A9A"),
main = "Bare.nuclei menurut Class", xlab = "Class", ylab = "Skor (1-10)")Boxplot memperlihatkan bahwa Cell.size dan
Bare.nuclei pada tumor malignant cenderung
bernilai jauh lebih tinggi dibandingkan tumor benign, yang
menjadi dugaan awal bahwa kedua kelas dapat dipisahkan dengan baik oleh
jarak pada ruang fitur.
set.seed(12333)
train_indices <- sample(seq_len(nrow(bc_norm)), size = round(0.70 * nrow(bc_norm)))
train_x <- bc_norm[train_indices, fitur]
test_x <- bc_norm[-train_indices, fitur]
train_y <- bc_norm$Class[train_indices]
test_y <- bc_norm$Class[-train_indices]
cat("Dimensi Data Latih (Train):", nrow(train_x), "baris,", ncol(train_x), "fitur\n")## Dimensi Data Latih (Train): 478 baris, 9 fitur
## Dimensi Data Uji (Test) : 205 baris, 9 fitur
dist_kelas <- rbind("Training" = table(train_y), "Testing" = table(test_y))
kable(dist_kelas, align = "c", caption = "Banyaknya observasi tiap kelas pada data training dan testing")| benign | malignant | |
|---|---|---|
| Training | 308 | 170 |
| Testing | 136 | 69 |
Data training berjumlah 478 observasi (70,0%) dan data testing 205 observasi. Pada data testing terdapat 69 tumor malignant dan 136 tumor benign. Setiap satu False Negative menurunkan sensitivitas sebesar 1,45 poin persentase, sedangkan setiap satu False Positive menurunkan spesifisitas sebesar 0,74 poin persentase. Sebagai pembanding, model yang selalu menebak benign akan mencapai akurasi 66,34% tetapi sensitivitas 0%, sehingga akurasi model k-NN harus dibaca terhadap angka dasar ini. Pengambilan sampel bersifat acak tanpa stratifikasi sehingga proporsi kelas pada data training dan testing dapat sedikit berbeda dari proporsi awal.
Model dibentuk untuk \(k\) = 3, 5,
7, 9, dan 11 dengan data prediktor yang sudah dinormalisasi.
set.seed(12333) dipanggil sebelum setiap pemanggilan
knn() agar hasil dapat direproduksi bila terdapat tetangga
dengan jarak yang sama. Kelas positif pada
confusionMatrix() ditetapkan sebagai
malignant.
k_set <- c(3, 5, 7, 9, 11)
cm_list <- vector("list", length(k_set))
hasil_rows <- vector("list", length(k_set))
for (i in seq_along(k_set)) {
set.seed(12333)
pred <- knn(train = train_x, test = test_x, cl = train_y, k = k_set[i])
pred <- factor(pred, levels = levels(test_y))
cm <- confusionMatrix(data = pred, reference = test_y, positive = "malignant")
tab <- as.matrix(cm$table) # baris = prediksi, kolom = aktual
cm_list[[i]] <- cm
hasil_rows[[i]] <- data.frame(
k = k_set[i],
Akurasi = unname(cm$overall["Accuracy"]),
Sensitivitas = unname(cm$byClass["Sensitivity"]),
Spesifisitas = unname(cm$byClass["Specificity"]),
PPV = unname(cm$byClass["Pos Pred Value"]),
NPV = unname(cm$byClass["Neg Pred Value"]),
Bal_Acc = unname(cm$byClass["Balanced Accuracy"]),
TP = tab["malignant", "malignant"],
TN = tab["benign", "benign"],
FP = tab["malignant", "benign"],
FN = tab["benign", "malignant"]
)
}
hasil <- do.call(rbind, hasil_rows)
rownames(hasil) <- NULLKelima model berhasil dibentuk. Hasil setiap model disajikan pada subbab berikut.
| benign | malignant | |
|---|---|---|
| benign | 132 | 3 |
| malignant | 4 | 66 |
| Metrik | Nilai |
|---|---|
| Akurasi | 0.9659 |
| Sensitivitas (Recall, kelas malignant) | 0.9565 |
| Spesifisitas (kelas benign) | 0.9706 |
| Positive Predictive Value (Presisi) | 0.9429 |
| Negative Predictive Value | 0.9778 |
| Balanced Accuracy | 0.9636 |
Interpretasi. Model k-NN dengan \(k\) = 3 menggunakan 3 tetangga terdekat untuk setiap observasi testing. Pada confusion matrix, 198 dari 205 observasi testing diklasifikasikan dengan benar (66 True Positive dan 132 True Negative) sehingga akurasi sebesar 96,59%. Akurasi ini lebih tinggi dari akurasi dasar (selalu menebak benign) sebesar 66,34%. Terdapat 3 tumor ganas yang salah diprediksi sebagai jinak (False Negative), yaitu jenis kesalahan yang paling berbahaya secara klinis karena pasien berisiko tidak segera ditangani; sensitivitas menjadi 95,65%. Terdapat 4 tumor jinak yang salah diprediksi sebagai ganas (False Positive) sehingga spesifisitas menjadi 97,06%; kesalahan ini berdampak pada pemeriksaan lanjutan yang sebenarnya tidak diperlukan. Nilai Positive Predictive Value sebesar 94,29% berarti dari seluruh prediksi ganas, sebesar proporsi tersebut benar-benar ganas.
| benign | malignant | |
|---|---|---|
| benign | 132 | 2 |
| malignant | 4 | 67 |
| Metrik | Nilai |
|---|---|
| Akurasi | 0.9707 |
| Sensitivitas (Recall, kelas malignant) | 0.9710 |
| Spesifisitas (kelas benign) | 0.9706 |
| Positive Predictive Value (Presisi) | 0.9437 |
| Negative Predictive Value | 0.9851 |
| Balanced Accuracy | 0.9708 |
Interpretasi. Model k-NN dengan \(k\) = 5 menggunakan 5 tetangga terdekat untuk setiap observasi testing. Pada confusion matrix, 199 dari 205 observasi testing diklasifikasikan dengan benar (67 True Positive dan 132 True Negative) sehingga akurasi sebesar 97,07%. Akurasi ini lebih tinggi dari akurasi dasar (selalu menebak benign) sebesar 66,34%. Terdapat 2 tumor ganas yang salah diprediksi sebagai jinak (False Negative), yaitu jenis kesalahan yang paling berbahaya secara klinis karena pasien berisiko tidak segera ditangani; sensitivitas menjadi 97,10%. Terdapat 4 tumor jinak yang salah diprediksi sebagai ganas (False Positive) sehingga spesifisitas menjadi 97,06%; kesalahan ini berdampak pada pemeriksaan lanjutan yang sebenarnya tidak diperlukan. Nilai Positive Predictive Value sebesar 94,37% berarti dari seluruh prediksi ganas, sebesar proporsi tersebut benar-benar ganas.
| benign | malignant | |
|---|---|---|
| benign | 132 | 1 |
| malignant | 4 | 68 |
| Metrik | Nilai |
|---|---|
| Akurasi | 0.9756 |
| Sensitivitas (Recall, kelas malignant) | 0.9855 |
| Spesifisitas (kelas benign) | 0.9706 |
| Positive Predictive Value (Presisi) | 0.9444 |
| Negative Predictive Value | 0.9925 |
| Balanced Accuracy | 0.9780 |
Interpretasi. Model k-NN dengan \(k\) = 7 menggunakan 7 tetangga terdekat untuk setiap observasi testing. Pada confusion matrix, 200 dari 205 observasi testing diklasifikasikan dengan benar (68 True Positive dan 132 True Negative) sehingga akurasi sebesar 97,56%. Akurasi ini lebih tinggi dari akurasi dasar (selalu menebak benign) sebesar 66,34%. Terdapat 1 tumor ganas yang salah diprediksi sebagai jinak (False Negative), yaitu jenis kesalahan yang paling berbahaya secara klinis karena pasien berisiko tidak segera ditangani; sensitivitas menjadi 98,55%. Terdapat 4 tumor jinak yang salah diprediksi sebagai ganas (False Positive) sehingga spesifisitas menjadi 97,06%; kesalahan ini berdampak pada pemeriksaan lanjutan yang sebenarnya tidak diperlukan. Nilai Positive Predictive Value sebesar 94,44% berarti dari seluruh prediksi ganas, sebesar proporsi tersebut benar-benar ganas.
| benign | malignant | |
|---|---|---|
| benign | 133 | 1 |
| malignant | 3 | 68 |
| Metrik | Nilai |
|---|---|
| Akurasi | 0.9805 |
| Sensitivitas (Recall, kelas malignant) | 0.9855 |
| Spesifisitas (kelas benign) | 0.9779 |
| Positive Predictive Value (Presisi) | 0.9577 |
| Negative Predictive Value | 0.9925 |
| Balanced Accuracy | 0.9817 |
Interpretasi. Model k-NN dengan \(k\) = 9 menggunakan 9 tetangga terdekat untuk setiap observasi testing. Pada confusion matrix, 201 dari 205 observasi testing diklasifikasikan dengan benar (68 True Positive dan 133 True Negative) sehingga akurasi sebesar 98,05%. Akurasi ini lebih tinggi dari akurasi dasar (selalu menebak benign) sebesar 66,34%. Terdapat 1 tumor ganas yang salah diprediksi sebagai jinak (False Negative), yaitu jenis kesalahan yang paling berbahaya secara klinis karena pasien berisiko tidak segera ditangani; sensitivitas menjadi 98,55%. Terdapat 3 tumor jinak yang salah diprediksi sebagai ganas (False Positive) sehingga spesifisitas menjadi 97,79%; kesalahan ini berdampak pada pemeriksaan lanjutan yang sebenarnya tidak diperlukan. Nilai Positive Predictive Value sebesar 95,77% berarti dari seluruh prediksi ganas, sebesar proporsi tersebut benar-benar ganas.
| benign | malignant | |
|---|---|---|
| benign | 133 | 1 |
| malignant | 3 | 68 |
| Metrik | Nilai |
|---|---|
| Akurasi | 0.9805 |
| Sensitivitas (Recall, kelas malignant) | 0.9855 |
| Spesifisitas (kelas benign) | 0.9779 |
| Positive Predictive Value (Presisi) | 0.9577 |
| Negative Predictive Value | 0.9925 |
| Balanced Accuracy | 0.9817 |
Interpretasi. Model k-NN dengan \(k\) = 11 menggunakan 11 tetangga terdekat untuk setiap observasi testing. Pada confusion matrix, 201 dari 205 observasi testing diklasifikasikan dengan benar (68 True Positive dan 133 True Negative) sehingga akurasi sebesar 98,05%. Akurasi ini lebih tinggi dari akurasi dasar (selalu menebak benign) sebesar 66,34%. Terdapat 1 tumor ganas yang salah diprediksi sebagai jinak (False Negative), yaitu jenis kesalahan yang paling berbahaya secara klinis karena pasien berisiko tidak segera ditangani; sensitivitas menjadi 98,55%. Terdapat 3 tumor jinak yang salah diprediksi sebagai ganas (False Positive) sehingga spesifisitas menjadi 97,79%; kesalahan ini berdampak pada pemeriksaan lanjutan yang sebenarnya tidak diperlukan. Nilai Positive Predictive Value sebesar 95,77% berarti dari seluruh prediksi ganas, sebesar proporsi tersebut benar-benar ganas.
tab_banding <- hasil[, c("k", "Akurasi", "Sensitivitas", "Spesifisitas", "FN", "FP")]
kable(tab_banding, digits = 4, align = "c",
caption = "Perbandingan kinerja model k-NN pada data testing (kelas positif = malignant)")| k | Akurasi | Sensitivitas | Spesifisitas | FN | FP |
|---|---|---|---|---|---|
| 3 | 0.9659 | 0.9565 | 0.9706 | 3 | 4 |
| 5 | 0.9707 | 0.9710 | 0.9706 | 2 | 4 |
| 7 | 0.9756 | 0.9855 | 0.9706 | 1 | 4 |
| 9 | 0.9805 | 0.9855 | 0.9779 | 1 | 3 |
| 11 | 0.9805 | 0.9855 | 0.9779 | 1 | 3 |
Perbandingan menurut akurasi. Akurasi testing untuk \(k\) = 3, 5, 7, 9, dan 11 masing-masing adalah 96,59%, 97,07%, 97,56%, 98,05%, 98,05%. Akurasi tertinggi (98,05%) dicapai oleh model dengan \(k\) = 9, 11. Rentang akurasi antar-model hanya 1,46 poin persentase, yang setara dengan 3 observasi testing. Perbedaan yang tipis ini menunjukkan bahwa pada data ini kinerja keseluruhan k-NN relatif stabil untuk rentang k yang diuji, sehingga pemilihan k tidak boleh didasarkan pada akurasi saja.
Perbandingan menurut sensitivitas (False Negative). Sensitivitas untuk kelima model masing-masing 95,65%, 97,10%, 98,55%, 98,55%, 98,55% dengan jumlah False Negative 3, 2, 1, 1, 1. Sensitivitas tertinggi (98,55%, FN = 1) dicapai bersama oleh model dengan k = 7, 9, 11.
Perbandingan menurut spesifisitas (False Positive). Spesifisitas masing-masing 97,06%, 97,06%, 97,06%, 97,79%, 97,79% dengan jumlah False Positive 4, 4, 4, 3, 3. Rentang spesifisitas antar-model adalah 0,74 poin persentase.
plot_df <- rbind(
data.frame(k = hasil$k, Metrik = "Akurasi", Nilai = hasil$Akurasi),
data.frame(k = hasil$k, Metrik = "Sensitivitas", Nilai = hasil$Sensitivitas),
data.frame(k = hasil$k, Metrik = "Spesifisitas", Nilai = hasil$Spesifisitas)
)
ggplot(plot_df, aes(x = k, y = Nilai, color = Metrik)) +
geom_line(linewidth = 1) +
geom_point(size = 2.8) +
scale_x_continuous(breaks = k_set) +
scale_y_continuous(labels = scales::percent_format(accuracy = 0.1)) +
labs(title = "Akurasi, Sensitivitas, dan Spesifisitas menurut Nilai k",
subtitle = paste0("Data testing: ", nrow(test_x), " observasi (kelas positif = malignant)"),
x = "Jumlah tetangga terdekat (k)", y = "Nilai metrik", color = "") +
theme_minimal(base_size = 11) +
theme(plot.title = element_text(face = "bold", hjust = 0.5),
plot.subtitle = element_text(hjust = 0.5),
panel.grid.minor = element_blank())err_df <- rbind(
data.frame(k = factor(hasil$k), Jenis = "False Negative (ganas diprediksi jinak)", Jumlah = hasil$FN),
data.frame(k = factor(hasil$k), Jenis = "False Positive (jinak diprediksi ganas)", Jumlah = hasil$FP)
)
ggplot(err_df, aes(x = k, y = Jumlah, fill = Jenis)) +
geom_col(position = "dodge") +
geom_text(aes(label = Jumlah), position = position_dodge(width = 0.9), vjust = -0.3, size = 3.5) +
scale_fill_manual(values = c("#E57373", "#64B5F6")) +
labs(title = "Jumlah Kesalahan Klasifikasi menurut Nilai k",
x = "Jumlah tetangga terdekat (k)", y = "Jumlah observasi", fill = "") +
theme_minimal(base_size = 11) +
theme(plot.title = element_text(face = "bold", hjust = 0.5), legend.position = "bottom")Grafik garis memperlihatkan perubahan akurasi, sensitivitas, dan spesifisitas ketika \(k\) bertambah, sedangkan grafik batang memperlihatkan jumlah False Negative dan False Positive tiap model. Jika k diperbesar, keputusan semakin dipengaruhi kelas mayoritas (benign), sehingga secara teori sensitivitas dapat menurun (Fransiska, 2026). Nilai k terbaik pada grafik sebaiknya dilihat dari batang False Negative yang paling rendah.
Karena kesalahan False Negative (tumor ganas yang terdiagnosis jinak) lebih berbahaya daripada False Positive, nilai \(k\) optimal dipilih dengan urutan prioritas: (1) sensitivitas tertinggi atau False Negative terendah, (2) akurasi tertinggi, (3) spesifisitas tertinggi, dan (4) jika masih sama, \(k\) yang lebih besar karena batas keputusan lebih halus dan variansnya lebih rendah.
kable(hasil[ord, c("k", "Sensitivitas", "Akurasi", "Spesifisitas", "FN", "FP")],
digits = 4, align = "c", row.names = FALSE,
caption = "Peringkat nilai k berdasarkan prioritas sensitivitas, akurasi, dan spesifisitas")| k | Sensitivitas | Akurasi | Spesifisitas | FN | FP |
|---|---|---|---|---|---|
| 11 | 0.9855 | 0.9805 | 0.9779 | 1 | 3 |
| 9 | 0.9855 | 0.9805 | 0.9779 | 1 | 3 |
| 7 | 0.9855 | 0.9756 | 0.9706 | 1 | 4 |
| 5 | 0.9710 | 0.9707 | 0.9706 | 2 | 4 |
| 3 | 0.9565 | 0.9659 | 0.9706 | 3 | 4 |
Berdasarkan kriteria tersebut, nilai \(k\) paling optimal adalah \(k\) = 11 dengan sensitivitas 98,55% (False Negative = 1), akurasi 98,05%, dan spesifisitas 97,79% (False Positive = 3). Karena sensitivitas yang sama dicapai oleh beberapa nilai k (7, 9, 11), pemilihan dilanjutkan dengan membandingkan akurasi dan spesifisitas sesuai urutan prioritas. Model ini masih melewatkan 1 tumor ganas pada data testing, yang menunjukkan bahwa meskipun k sudah dioptimalkan, risiko False Negative belum sepenuhnya hilang dan hasil model perlu dikonfirmasi dengan pemeriksaan klinis lanjutan.
Nilai k optimal ini (k = 11) berbeda dengan Muhammad (2026) yang
memperoleh k = 5 sebagai nilai terbaik. Perbedaan dapat terjadi karena
data yang dipakai berbeda (di sini data BreastCancer dari mlbench dengan
9 prediktor, sedangkan penelitian tersebut memakai Wisconsin
Diagnostic dengan 30 fitur), pembagian data, dan kriteria pemilihan
yang di sini memprioritaskan sensitivitas. Karena data testing
hanya memuat 69 tumor ganas, selisih satu atau dua observasi dapat
mengubah urutan model. Pemilihan k pada praktikum ini karena
itu bersifat indikatif untuk pembagian data dengan
set.seed(12333), dan belum tentu sama bila pembagian data
diulang dengan seed lain.
## Confusion Matrix and Statistics
##
## Reference
## Prediction benign malignant
## benign 133 1
## malignant 3 68
##
## Accuracy : 0.9805
## 95% CI : (0.9508, 0.9947)
## No Information Rate : 0.6634
## P-Value [Acc > NIR] : <2e-16
##
## Kappa : 0.9566
##
## Mcnemar's Test P-Value : 0.6171
##
## Sensitivity : 0.9855
## Specificity : 0.9779
## Pos Pred Value : 0.9577
## Neg Pred Value : 0.9925
## Prevalence : 0.3366
## Detection Rate : 0.3317
## Detection Prevalence : 0.3463
## Balanced Accuracy : 0.9817
##
## 'Positive' Class : malignant
##
Output di atas adalah ringkasan lengkap
confusionMatrix() untuk model terbaik. Selain akurasi,
sensitivitas, dan spesifisitas, output ini memuat selang
kepercayaan 95% akurasi, nilai No Information Rate (akurasi
dasar bila selalu menebak kelas mayoritas), serta statistik Kappa. Nilai
Pos Pred Value adalah presisi kelas malignant, dan
Detection Rate adalah proporsi tumor ganas yang terdeteksi
benar terhadap seluruh data testing.
K-Nearest Neighbor (k-NN) adalah algoritma
klasifikasi non-parametrik berbasis instance yang menentukan
kelas data baru dengan majority voting dari k tetangga
terdekat berdasarkan metrik jarak, sehingga penskalaan fitur diperlukan.
Pada data Wisconsin Breast Cancer Database, pra-pemrosesan yang
dilakukan meliputi penghapusan kolom Id, penghapusan 16
observasi dengan missing value (tersisa 683 observasi),
pengubahan prediktor menjadi numerik, dan normalisasi min-max.
Data dibagi menjadi 478 data training (70%) dan 205 data
testing (30%) dengan set.seed(12333).
Berdasarkan perbandingan lima model (\(k\) = 3, 5, 7, 9, dan 11), akurasi testing berkisar antara 96,59% dan 98,05%, sensitivitas antara 95,65% dan 98,55%, serta spesifisitas antara 97,06% dan 97,79%. Dengan mempertimbangkan pentingnya meminimalkan False Negative, nilai \(k\) paling optimal adalah \(k\) = 11 dengan sensitivitas 98,55% (1 False Negative), akurasi 98,05%, dan spesifisitas 97,79%. Karena data testing berukuran terbatas, perbedaan satu atau dua observasi dapat mengubah urutan model, sehingga pemilihan nilai k perlu ditafsirkan dengan hati-hati.
Praktikan disarankan untuk mempelajari lebih lanjut mengenai program
RStudio melalui berbagai sumber pembelajaran, seperti buku, jurnal,
modul praktikum, maupun sumber belajar lainnya agar semakin memahami
penerapan k-NN. Pada penelitian selanjutnya, disarankan
menggunakan validasi silang (cross-validation) melalui
caret::train() atau pengulangan pembagian data dengan
beberapa nilai set.seed agar pemilihan k lebih
andal, memakai pembagian data berstrata
(createDataPartition()) agar proporsi kelas terjaga, serta
melakukan normalisasi dengan parameter (minimum dan maksimum) yang
dihitung dari data training saja untuk menghindari kebocoran
informasi. Peneliti juga dapat menurunkan ambang probabilitas keputusan
(prob = TRUE pada knn()) untuk menaikkan
sensitivitas, menambahkan metrik seperti AUC, dan membandingkan
k-NN dengan algoritma lain. Praktikan juga diharapkan lebih
teliti dalam melakukan pengolahan data dan penulisan kode program agar
dapat meminimalkan kesalahan selama praktikum.
Fransiska, H. (2026). Modul Praktikum Machine Learning dan Model Prediction. Universitas Bengkulu: Bengkulu.
Ardiansyah, L., & Irawan, B. (2026). Prediksi kanker payudara berbasis machine learning dengan analisis probabilitas klasifikasi. Jurnal Sintaks Logika, 6(1), 69–78. https://jurnal.umpar.ac.id/sylog/article/view/4294
Muhammad, M. R. (2026). Analisis perbandingan algoritma K-Nearest Neighbor (K-NN) dan Random Forest dalam klasifikasi kanker payudara. Prosiding SENTIMAT (Seminar Nasional Pendidikan Teknologi Informasi dan Pendidikan Matematika) FPMIPA 2026, IKIP PGRI Bojonegoro. https://prosiding.ikippgribojonegoro.ac.id/index.php/FPMIPA/article/view/5631
Pramudita, R., Safitri, N., & Nazah, V. Z. (2025). Studi komparatif algoritma machine learning dengan teknik bagging dan AdaBoost pada klasifikasi kanker payudara. Tematik: Jurnal Teknologi Informasi Komunikasi, 12(1), 102–108. https://doi.org/10.38204/tematik.v12i1.2435
Sari, D. P., & Brilliant, I. I. (2026). Penerapan algoritma particle swarm optimization untuk optimalisasi fuzzy k-nearest neighbor. Jurnal Kajian dan Terapan Matematika, 12(1), 1–10. https://doi.org/10.21831/jktm.v12i1.21133