BAB I PENDAHULUAN

1.1 Latar Belakang Masalah

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.

1.2 Rumusan Masalah

Berdasarkan latar belakang, rumusan masalah yang dapat disimpulkan adalah sebagai berikut:

  1. Bagaimana konsep fundamental, formulasi matematis, dan prinsip kerja algoritma K- Nearest Neighbors (k-NN) sebagai metode non-parametrik supervised leraning*?
  2. Bagaimana penskalaan fitur (feature scaling) dalam komputasi berbasis metrik jarak (distance metrics)?
  3. Bagaimana mengimplementasikan algoritma K-NN secara terstruktur dan mandiri menggunakan bahasa pemrograman R dengan pustaka class dan caret?
  4. Bagaimana mengevaluasi performa model klasifikasi menggunakan Confusion Matrix, Akurasi (Accuracy), Sensitivitas (Sensitivity), Spesifisitas (Specificity), dan Positive Predictive Value?
  5. Bagaimana ekpslorasi optimasi hiperparameter nilai K (hyperparameter tuning) serta memvisualisasikan kurva performanya menggunakan paket ggplot2?

1.3 Tujuan Penelitian

Berdasarkan rumusan masalah tersebut, tujuan yang dapat disimpulkan adalah sebagai berikut:

  1. Memahami konsep konsep fundamental, formulasi matematis, dan prinsip kerja algoritma K- Nearest Neighbors (k-NN) sebagai metode non-parametrik supervised learning*.
  2. Memahami pentingnya penskalaan fitur (feature scaling) dalam komputasi berbasis metrik jarak (distance metrics).
  3. Mengimplementasikan algoritma K-NN secara terstruktur dan mandiri menggunakan bahasa pemrograman R dengan pustaka class dan caret?
  4. Mengevaluasi performa model klasifikasi menggunakan Confusion Matrix, Akurasi (Accuracy), Sensitivitas (Sensitivity), Spesifisitas (Specificity), dan Positive Predictive Value?
  5. Melakukan ekpslorasi optimasi hiperparameter nilai K (hyperparameter tuning) serta memvisualisasikan kurva performanya menggunakan paket ggplot2?

BAB II TINJAUAN PUSTAKA

2.1 K-Nearest Neighbor (k-NN)

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.

2.2 Batas Kesalahan Cover-Hart

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.

2.3 Kompromi Bias-Varians dan Pemilihan Nilai k

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.

2.4 Metrik Jarak

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.

2.5 Penskalaan Fitur

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%).

2.6 Evaluasi Model

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.

2.7 Data Wisconsin Breast Cancer Database

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.

BAB III METODE PENELITIAN

3.1 Sumber Data

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.

3.2 Variabel Penelitian

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.

3.3 Skenario Analisis

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

3.4 Langkah-langkah Analisis

  1. Mulai.
  2. Memanggil package yang diperlukan (class, caret, mlbench, ggplot2, dan knitr).
  3. Memuat data BreastCancer, lalu memeriksa struktur, ringkasan, distribusi kelas, dan missing value.
  4. Pra-pemrosesan: menghapus kolom Id, menghapus observasi dengan missing value, mengubah prediktor menjadi numerik, dan menormalisasi prediktor dengan min-max.
  5. Membagi data menjadi 70% training dan 30% testing dengan sample() dan set.seed(12333).
  6. Membangun model k-NN dengan knn() untuk k = 3, 5, 7, 9, dan 11.
  7. Menyusun confusion matrix dengan confusionMatrix() (kelas positif = malignant) dan menghitung akurasi, sensitivitas, spesifisitas, serta nilai FN dan FP.
  8. Menginterpretasikan output setiap model.
  9. Membandingkan seluruh model dan menentukan k optimal dengan prioritas pada sensitivitas (meminimalkan FN).
  10. Menarik kesimpulan.
  11. Selesai.

3.5 Diagram Alir Penelitian

BAB IV HASIL DAN PEMBAHASAN

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.

4.1 Library

library(class)
library(caret)
library(mlbench)
library(ggplot2)
library(knitr)

Package class menyediakan fungsi knn(), caret untuk confusionMatrix(), mlbench untuk data BreastCancer, ggplot2 untuk visualisasi, dan knitr untuk menyajikan tabel.

4.2 Eksplorasi Data

data(BreastCancer, package = "mlbench")
bc_raw <- BreastCancer
head(bc_raw)
##        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
str(bc_raw)
## '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 ...
dim(bc_raw)
## [1] 699  11
summary(bc_raw)
##          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.

table(bc_raw$Class)
## 
##    benign malignant 
##       458       241
round(prop.table(table(bc_raw$Class)) * 100, 2)
## 
##    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.

colSums(is.na(bc_raw))
##              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.

4.3 Pra-pemrosesan Data

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)")

par(mfrow = c(1, 1))

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.

4.4 Membagi Data Training dan Testing

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
cat("Dimensi Data Uji (Test)   :", nrow(test_x), "baris,", ncol(test_x), "fitur\n")
## 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")
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.

4.5 Pembentukan Model k-NN

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) <- NULL

Kelima model berhasil dibentuk. Hasil setiap model disajikan pada subbab berikut.

4.6 Hasil k-NN untuk Setiap Nilai k

4.6.1 k = 3

tampil(1)
Confusion matrix data testing (k = 3); baris = prediksi, kolom = aktual
benign malignant
benign 132 3
malignant 4 66
Metrik evaluasi data testing (k = 3)
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.

4.6.2 k = 5

tampil(2)
Confusion matrix data testing (k = 5); baris = prediksi, kolom = aktual
benign malignant
benign 132 2
malignant 4 67
Metrik evaluasi data testing (k = 5)
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.

4.6.3 k = 7

tampil(3)
Confusion matrix data testing (k = 7); baris = prediksi, kolom = aktual
benign malignant
benign 132 1
malignant 4 68
Metrik evaluasi data testing (k = 7)
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.

4.6.4 k = 9

tampil(4)
Confusion matrix data testing (k = 9); baris = prediksi, kolom = aktual
benign malignant
benign 133 1
malignant 3 68
Metrik evaluasi data testing (k = 9)
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.

4.6.5 k = 11

tampil(5)
Confusion matrix data testing (k = 11); baris = prediksi, kolom = aktual
benign malignant
benign 133 1
malignant 3 68
Metrik evaluasi data testing (k = 11)
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.

4.7 Tabel Perbandingan Metrik Evaluasi

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)")
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.

4.8 Penentuan Nilai k Optimal

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")
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.

print(cm_list[[i_best]])
## 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.

BAB V KESIMPULAN

5.1 Kesimpulan

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.

5.2 Saran

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.

DAFTAR PUSTAKA

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