KNeighborsClassifier dan GaussianNB adalah dua classifier yang mekanismenya paling sederhana di antara model scikit-learn, tetapi keduanya tetap digunakan sebagai baseline, yaitu titik pembanding pertama sebelum model yang lebih rumit dicoba. KNN mengklasifikasikan sampel berdasarkan tetangga terdekatnya, sedangkan GaussianNB menggunakan teorema Bayes dengan asumsi kemandirian fitur. Topik ini membahas mekanisme keduanya, sensitivitas KNN terhadap skala fitur dan jumlah tetangga, serta perbandingan tiga model termasuk DummyClassifier pada dataset breast_cancer.
KNN: klasifikasi dari tetangga terdekat#
K-nearest neighbors, yang lazim disingkat KNN, tidak membangun model parametrik apa pun. Pelatihannya hanya menyimpan seluruh data latih, sedangkan prediksi dilakukan dengan mencari k sampel data latih yang paling dekat dengan sampel baru, kemudian mengambil kelas yang paling banyak muncul di antara tetangga tersebut. Jarak yang digunakan secara bawaan adalah jarak Euclidean, sehingga definisi “terdekat” sepenuhnya bergantung pada skala setiap fitur. Parameter n_neighbors mengendalikan seberapa halus keputusannya, yaitu k kecil mengikuti data dengan rapat sedangkan k besar menghaluskan batas keputusan.
Sifat penyimpanan penuh ini disebut pembelajaran malas (lazy learning), karena seluruh pekerjaan komputasi berpindah dari saat pelatihan ke saat prediksi. Konsekuensinya, fit berjalan seketika, tetapi setiap prediksi harus menghitung jarak ke seluruh data latih, sehingga KNN menjadi lambat pada data yang besar. Model ini juga menolak masukan yang memuat nilai NaN karena perhitungan jaraknya menuntut seluruh fitur terisi. Kedua sifat itu menjadikan KNN praktis pada data kecil hingga menengah, dan kurang cocok pada data yang sangat besar.
GaussianNB: cepat dengan asumsi kemandirian#
GaussianNB berasal dari keluarga naive Bayes, yaitu classifier yang menerapkan teorema Bayes dengan asumsi kemandirian fitur, yakni menyatakan setiap fitur berkontribusi terhadap kelas secara terpisah tanpa saling memengaruhi. Nama naive, yang berarti naif, merujuk pada asumsi tersebut, karena pada data nyata fitur jarang benar-benar mandiri. GaussianNB memodelkan distribusi setiap fitur per kelas sebagai distribusi Gaussian, sehingga pelatihannya hanya menghitung rata-rata dan varians setiap fitur pada setiap kelas. Seluruh proses berlangsung dalam satu kali lewatan data, menjadikannya salah satu pelatihan tercepat di scikit-learn.
Asumsi yang keliru secara teori ternyata sering cukup baik dalam praktik. Untuk klasifikasi teks, seperti penyaringan pesan sampah berbasis hitungan kata, keluarga naive Bayes unggul secara historis dan masih menjadi baseline yang sah, dengan varian MultinomialNB yang dirancang untuk data hitungan. Pada data numerik, GaussianNB digunakan sebagai pembanding murah yang dapat dilatih dalam hitungan milidetik. Apabila model yang jauh lebih rumit hanya mengalahkan GaussianNB dengan selisih tipis, tambahan kompleksitas itu perlu dipertanggungjawabkan.
Tiga model pada breast_cancer#
Perbandingan yang adil melibatkan tiga tingkatan sekaligus, yaitu DummyClassifier sebagai batas bawah, GaussianNB sebagai model murah, dan KNN sebagai model berbasis jarak. KNN dijalankan di dalam pipeline dengan StandardScaler karena fitur breast_cancer berskala timpang. DummyClassifier digunakan dengan strategi most_frequent yang meniru tebakan kelas mayoritas, sesuai pembahasan modul API estimator. Seluruh model dilatih dan dinilai pada pemecahan data yang sama.
from sklearn.datasets import load_breast_cancer
from sklearn.dummy import DummyClassifier
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import GaussianNB
from sklearn.neighbors import KNeighborsClassifier
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
bc = load_breast_cancer()
X_train, X_test, y_train, y_test = train_test_split(
bc.data, bc.target, test_size=0.25, stratify=bc.target, random_state=42
)
# baseline yang hanya menebak kelas mayoritas
dummy = DummyClassifier(strategy="most_frequent", random_state=42)
dummy.fit(X_train, y_train)
# KNN membandingkan jarak antarsampel, sehingga fitur distandardisasi dahulu
knn = make_pipeline(StandardScaler(), KNeighborsClassifier(n_neighbors=5))
knn.fit(X_train, y_train)
# GaussianNB menghitung rata-rata dan varians per fitur per kelas
nb = GaussianNB()
nb.fit(X_train, y_train)
print(f"DummyClassifier (most_frequent): {dummy.score(X_test, y_test):.3f}")
print(f"KNN dengan scaling (k=5) : {knn.score(X_test, y_test):.3f}")
print(f"GaussianNB : {nb.score(X_test, y_test):.3f}")DummyClassifier (most_frequent): 0.629
KNN dengan scaling (k=5) : 0.979
GaussianNB : 0.937Baseline menebak kelas mayoritas saja dan mencapai 0.629, yang mencerminkan proporsi kelas jinak pada data ini. KNN mencapai 0.979 dan GaussianNB 0.937, sehingga keduanya mengalahkan baseline dengan selisih yang lebar. Skor KNN yang lebih tinggi membawa biaya yang lebih besar pula, yaitu kewajiban standardisasi dan komputasi jarak saat prediksi, sedangkan GaussianNB tidak menuntut keduanya. Perbedaan waktu pelatihan ketiganya nyaris tidak terasa pada data sekecil ini, dan perbedaannya baru terasa pada data yang jauh lebih besar. Pemilihan di antara KNN dan GaussianNB kemudian menjadi pertimbangan kebutuhan, bukan sekadar pencarian skor tertinggi.
Jumlah tetangga dan sensitivitas skala#
Dua sifat KNN diukur langsung pada data yang sama. Pengukuran pertama mengubah jumlah tetangga k, sedangkan pengukuran kedua membandingkan KNN dengan dan tanpa StandardScaler pada parameter yang identik.
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
bc = load_breast_cancer()
X_train, X_test, y_train, y_test = train_test_split(
bc.data, bc.target, test_size=0.25, stratify=bc.target, random_state=42
)
for k in [1, 5, 15, 50]:
model = make_pipeline(StandardScaler(), KNeighborsClassifier(n_neighbors=k))
model.fit(X_train, y_train)
print(f"k={k:>2}: train={model.score(X_train, y_train):.3f}, "
f"test={model.score(X_test, y_test):.3f}")k= 1: train=1.000, test=0.951
k= 5: train=0.969, test=0.979
k=15: train=0.969, test=0.958
k=50: train=0.948, test=0.937Pada k=1, setiap sampel data latih menjadi tetangga dirinya sendiri, sehingga akurasi train sempurna di 1.000 dan model murni menghafal, dengan akurasi test yang turun ke 0.951. Nilai tengah seperti k=5 mencapai test tertinggi di 0.979, sedangkan k=50 terlalu kasar dan menurunkan kedua skor sekaligus, yaitu 0.948 pada train dan 0.937 pada test. Pola ini menunjukkan bahwa k memerlukan penyetelan pada setiap dataset, dan nilai bawaan 5 merupakan titik awal yang wajar tanpa jaminan optimal.
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
bc = load_breast_cancer()
X_train, X_test, y_train, y_test = train_test_split(
bc.data, bc.target, test_size=0.25, stratify=bc.target, random_state=42
)
# kondisi pertama: KNN pada fitur mentah tanpa scaling
knn_tanpa = KNeighborsClassifier(n_neighbors=5)
knn_tanpa.fit(X_train, y_train)
akurasi_tanpa = knn_tanpa.score(X_test, y_test)
# kondisi kedua: scaler dilatih hanya pada data latih
knn_dengan = make_pipeline(StandardScaler(), KNeighborsClassifier(n_neighbors=5))
knn_dengan.fit(X_train, y_train)
akurasi_dengan = knn_dengan.score(X_test, y_test)
print(f"KNN k=5 tanpa scaling : {akurasi_tanpa:.3f}")
print(f"KNN k=5 dengan scaling: {akurasi_dengan:.3f}")KNN k=5 tanpa scaling : 0.930
KNN k=5 dengan scaling: 0.979Tanpa scaling, akurasi turun dari 0.979 menjadi 0.930, padahal algoritma, jumlah tetangga, dan pemecahan data tidak berubah sama sekali. Penyebabnya ada pada fitur worst area yang bergerak hingga ribuan, sehingga kuadrat selisihnya mendominasi jarak Euclidean dan menenggelamkan kontribusi fitur berskala kecil. Tetangga yang ditemukan pada data mentah hampir ditentukan oleh satu atau dua fitur saja. StandardScaler mengembalikan peran setiap fitur ke kedudukan yang sebanding, dan penjelasan lengkap mekanismenya ada pada topik Mengapa Scaling Diperlukan.
Kesalahan umum#
Kesalahan pertama adalah menjalankan KNN pada fitur berskala timpang tanpa scaling. Tidak ada error yang muncul karena prosesnya sah secara teknis, tetapi hasilnya menurun secara diam-diam, sebagaimana terukur selisih 0.979 berbanding 0.930 pada contoh di atas. Kebiasaan yang menjaga keamanannya adalah memasangkan setiap KNeighborsClassifier dengan StandardScaler sejak awal.
Kesalahan kedua adalah menolak GaussianNB hanya karena asumsi kemandiriannya memang dilanggar. Pelanggaran asumsi menurunkan keandalan probabilitas keluarannya, tetapi label kelasnya sering tetap akurat, sehingga model ini murah untuk dicoba dan murah untuk dibuang apabila hasilnya tidak memadai. Penilaian terhadapnya tetap diambil dari skor pada data uji dan bukan dari kepatuhan asumsinya secara teoretis.
Kesalahan ketiga adalah menganggap KNN murah hanya karena fit-nya seketika. Biaya komputasinya berpindah ke prediksi yang menghitung jarak ke seluruh data latih, sehingga prediksi massal pada data besar menjadi lambat dan membutuhkan struktur pencarian tetangga khusus atau penggantian model. Perkiraan biaya semacam ini layak disertakan sebelum KNN dipilih untuk beban kerja yang besar.
Ringkasan#
- KNN memprediksi kelas dari voting k tetangga terdekat, sensitif terhadap skala fitur, dan memindahkan seluruh biaya komputasinya ke saat prediksi.
- GaussianNB memodelkan setiap fitur per kelas sebagai distribusi Gaussian dengan asumsi kemandirian, sehingga pelatihannya sangat cepat dan layak menjadi baseline pertama.
- Pada breast_cancer, ketiga model menghasilkan 0.629 untuk DummyClassifier, 0.979 untuk KNN dengan scaling, dan 0.937 untuk GaussianNB.
- Parameter
kmemerlukan penyetelan, karena k kecil menghafal dan k besar menghaluskan hingga kehilangan informasi.
Referensi#
- 1.6. Nearest Neighbors — scikit-learn documentation — Bagian user guide yang mengulas algoritma tetangga terdekat dan pilihan jaraknya.
- 1.9. Naive Bayes — scikit-learn documentation — Bagian user guide yang mengulas seluruh varian naive Bayes, termasuk GaussianNB dan MultinomialNB.
- sklearn.neighbors.KNeighborsClassifier — scikit-learn documentation
— Rujukan parameter
n_neighbors,metric, dan perilaku prediksinya. - sklearn.naive_bayes.GaussianNB — scikit-learn documentation — Rujukan parameter dan atribut GaussianNB beserta contoh pemakaiannya.
- sklearn.datasets.load_breast_cancer — scikit-learn documentation — Dataset breast_cancer yang digunakan pada seluruh contoh topik ini.