TL;DR
Algoritma Naive Bayes adalah metode klasifikasi yang ngitung peluang tiap kategori buat sebuah data, lalu milih kategori dengan peluang terbesar. Dia disebut naive soalnya nganggap semua fitur saling bebas, asumsi yang jarang benar tapi hasilnya tetap akurat buat klasifikasi teks. Dengan Laplace smoothing, kata yang belum pernah muncul di data latih nggak bikin peluangnya jatuh ke nol.
Algoritma Naive Bayes adalah metode klasifikasi yang nebak kategori sebuah data dengan ngitung peluang tiap kategori, lalu ambil yang angkanya paling besar.
Buat klasifikasi teks kayak ulasan produk, algoritma ini masih jadi baseline yang susah dikalahin. Ringan, cepat, dan bisa kamu hitung manual pakai kalkulator biasa.
Di artikel ini aku bawa 10 ulasan toko online UMKM, hitung sampai ketemu angka 67,4%, terus cocokin hasilnya pakai scikit-learn biar kamu yakin hitungannya benar.
Naive Bayes adalah algoritma klasifikasi berbasis Teorema Bayes yang ngitung peluang sebuah data masuk ke tiap kelas, lalu milih kelas dengan peluang tertinggi. Dia disebut naive gara-gara nganggap semua fitur saling bebas satu sama lain. Asumsi itu jarang benar di dunia nyata, tapi hasil klasifikasinya tetap akurat.
Contoh paling gampang: kamu punya ribuan ulasan di marketplace. Kamu mau tau mana yang positif dan mana yang negatif tanpa baca satu-satu.
Naive Bayes belajar dari ulasan yang udah dilabeli manusia, lalu nebak label ulasan baru berdasarkan kata-kata yang muncul di dalamnya.
Kata naive datang dari asumsi bahwa kemunculan tiap kata nggak dipengaruhi kata lain di kalimat yang sama.
Padahal di ulasan asli, kata "pengiriman" dan "cepat" sering muncul bareng. Naive Bayes cuek sama fakta itu dan ngitung keduanya terpisah.
Anehnya, model ini tetap sering menang. Buat urusan nentuin kelas mana yang paling besar peluangnya, kesalahan asumsi tadi biasanya nggak ngubah urutan pemenangnya.
Rumus intinya cuma satu baris. Peluang sebuah kelas setelah lihat data sama dengan peluang kelas itu dikali peluang tiap fitur di dalam kelas tersebut.
P(kelas | kata1, kata2, ...) ∝ P(kelas) × P(kata1|kelas) × P(kata2|kelas) × ...
Simbol ∝ artinya "sebanding dengan". Kita nggak perlu penyebutnya, soalnya penyebut itu sama buat semua kelas dan nggak ngubah siapa yang menang.
Buat teks, P(kata|kelas) dihitung dari jumlah kemunculan kata itu di kelas tersebut dibagi total kata di kelas yang sama.
Ada satu tambahan wajib: Laplace smoothing. Kita nambahin 1 ke tiap hitungan kata, biar kata yang belum pernah muncul nggak bikin seluruh perkalian jadi nol.
P(kata|kelas) = (jumlah kata di kelas + 1) / (total kata di kelas + jumlah kata unik)
Aku pakai 10 ulasan dari dataset latihan toko_berkah, sebuah toko perlengkapan rumah tangga yang jualan di marketplace. Enam ulasan positif, empat negatif.
| No | Isi ulasan | Label |
|---|---|---|
| 1 | barang bagus pengiriman cepat | positif |
| 2 | kualitas bagus harga murah | positif |
| 3 | pengiriman cepat penjual ramah | positif |
| 4 | barang bagus penjual ramah | positif |
| 5 | harga murah barang bagus | positif |
| 6 | kualitas bagus pengiriman cepat | positif |
| 7 | barang rusak pengiriman lambat | negatif |
| 8 | kualitas jelek harga mahal | negatif |
| 9 | pengiriman lambat penjual cuek | negatif |
| 10 | barang rusak penjual cuek | negatif |
Ulasan yang mau kita tebak: "pengiriman lambat barang bagus". Sengaja aku pilih yang campur, biar kelihatan gimana algoritma ini ngambil keputusan.
Ini gampang. Tinggal bagi jumlah dokumen per kelas dengan total dokumen.
P(positif) = 6 / 10 = 0,6
P(negatif) = 4 / 10 = 0,4
Tiap ulasan di atas punya 4 kata. Jadi kelas positif punya 6 × 4 = 24 kata, kelas negatif punya 4 × 4 = 16 kata.
Kata unik di seluruh dataset ada 14: barang, bagus, pengiriman, cepat, kualitas, harga, murah, penjual, ramah, rusak, lambat, jelek, mahal, cuek.
| Kata | Muncul di positif | Muncul di negatif |
|---|---|---|
| barang | 3 | 2 |
| bagus | 5 | 0 |
| pengiriman | 3 | 2 |
| cepat | 3 | 0 |
| lambat | 0 | 2 |
| penjual | 2 | 2 |
| Total kata | 24 | 16 |
Perhatikan kata "lambat". Di kelas positif hitungannya nol. Tanpa smoothing, kelas positif langsung gugur di sini walau tiga kata lain mendukung.
Penyebutnya: 24 + 14 = 38 buat positif, dan 16 + 14 = 30 buat negatif.
Kelas positif:
P(pengiriman|pos) = (3+1)/38 = 4/38 = 0,1053
P(lambat|pos) = (0+1)/38 = 1/38 = 0,0263
P(barang|pos) = (3+1)/38 = 4/38 = 0,1053
P(bagus|pos) = (5+1)/38 = 6/38 = 0,1579
Kelas negatif:
P(pengiriman|neg) = (2+1)/30 = 3/30 = 0,1000
P(lambat|neg) = (2+1)/30 = 3/30 = 0,1000
P(barang|neg) = (2+1)/30 = 3/30 = 0,1000
P(bagus|neg) = (0+1)/30 = 1/30 = 0,0333
Skor positif = 0,6 × 0,1053 × 0,0263 × 0,1053 × 0,1579
= 0,0000276
Skor negatif = 0,4 × 0,1000 × 0,1000 × 0,1000 × 0,0333
= 0,0000133
Skor positif lebih besar. Jadi ulasan "pengiriman lambat barang bagus" diklasifikasi sebagai positif.
Bagi tiap skor dengan totalnya biar kebaca sebagai peluang.
Total = 0,0000276 + 0,0000133 = 0,0000409
Peluang positif = 0,0000276 / 0,0000409 = 0,674 → 67,4%
Peluang negatif = 0,0000133 / 0,0000409 = 0,326 → 32,6%
Angka 67,4% ini yang menarik. Model yakin ulasannya positif, tapi keyakinannya nggak penuh. Di sistem moderasi ulasan, ambang kayak gini biasanya dipakai buat nandain ulasan yang perlu dicek manusia.
Kalau kamu bikin aturan "apapun di bawah 80% masuk antrian review manual", ulasan ini bakal ketahan. Dan memang seharusnya gitu, soalnya isinya beneran campur.
Sepuluh baris kode ini ngasih angka yang sama persis dengan hitungan manual di atas.
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.naive_bayes import MultinomialNB
ulasan = [
"barang bagus pengiriman cepat",
"kualitas bagus harga murah",
"pengiriman cepat penjual ramah",
"barang bagus penjual ramah",
"harga murah barang bagus",
"kualitas bagus pengiriman cepat",
"barang rusak pengiriman lambat",
"kualitas jelek harga mahal",
"pengiriman lambat penjual cuek",
"barang rusak penjual cuek",
]
label = ["positif"] * 6 + ["negatif"] * 4
vec = CountVectorizer()
X = vec.fit_transform(ulasan)
model = MultinomialNB(alpha=1.0)
model.fit(X, label)
uji = vec.transform(["pengiriman lambat barang bagus"])
print(model.classes_)
print(model.predict(uji))
print(model.predict_proba(uji).round(3))
Hasilnya:
['negatif' 'positif']
['positif']
[[0.326 0.674]]
Sama persis. Parameter alpha=1.0 itu Laplace smoothing yang tadi kita hitung manual. Detail tiap variannya ada di dokumentasi resmi scikit-learn.
Coba ganti alpha=1.0 jadi alpha=0. Peluang positif langsung jatuh ke nol, dan model nebak negatif. Itu efek kata "lambat" yang hitungannya nol tadi.
Naive Bayes paling kuat di data teks berdimensi tinggi dengan jumlah contoh yang terbatas. Klasifikasi ulasan, filter spam, penyortiran tiket customer service, dan pelabelan topik artikel semuanya masuk kategori ini. Waktu latihnya hitungan detik walau datanya puluhan ribu baris.
| Situasi | Naive Bayes | Alternatif |
|---|---|---|
| Klasifikasi teks, data ratusan sampai ribuan | Pilihan pertama | Logistic Regression |
| Fitur saling berkorelasi kuat | Kurang cocok | Random Forest |
| Butuh interpretasi per fitur | Bagus, tinggal lihat log peluang | Decision Tree |
| Data angka kontinu tanpa pola normal | Hati-hati | Gradient Boosting |
Kalau kamu lagi nyusun skripsi dan butuh baseline yang gampang dipertanggungjawabkan di sidang, Naive Bayes pilihan aman. Semua langkahnya bisa kamu tulis manual di lampiran.
Satu hal lagi soal kualitas input. Ulasan yang isinya cuma emoji atau "mantap gan" nggak kasih sinyal apa-apa ke model. Bersihin dulu, dan pahami kenapa data quality nentuin batas atas akurasi yang bisa kamu capai.
Kalau datamu masih di spreadsheet dan jumlahnya di bawah seribu baris, kamu bisa bikin tabel hitungan tadi tanpa coding.
Pakai COUNTIFS buat ngitung berapa ulasan berlabel positif yang mengandung kata tertentu. Gabungkan dengan wildcard bintang di kriterianya, misalnya "*bagus*".
Buat total kata per kelas, SUMPRODUCT bisa nolongin karena dia bisa ngaliin dan nambahin array sekaligus.
Cara ini nggak sepraktis Python, tapi berguna banget waktu kamu lagi belajar. Kamu lihat sendiri angkanya bergerak, bukan cuma percaya output library.
Multinomial dipakai kalau fiturmu berupa hitungan, misalnya berapa kali sebuah kata muncul di ulasan. Bernoulli dipakai kalau kamu cuma peduli kata itu muncul atau nggak. Gaussian dipakai buat angka kontinu kayak harga atau umur, dan dia nganggap tiap fitur nyebar mengikuti kurva normal. Buat teks, Multinomial biasanya pilihan pertama.
Soalnya kamu ngaliin banyak angka yang semuanya di bawah 1. Sepuluh kata aja udah bikin hasilnya di kisaran 0,00000001. Di ulasan panjang, angkanya bisa lebih kecil dari batas presisi komputer dan berubah jadi nol. Makanya library kayak scikit-learn ngitung pakai logaritma, jadi perkalian berubah jadi penjumlahan.
Naive Bayes tahan data sedikit, jadi ratusan contoh per kelas biasanya udah kasih hasil lumayan. Yang lebih penting bukan jumlah totalnya, tapi keseimbangan antar kelas dan keberagaman katanya. Kalau kelas negatif cuma punya 20 ulasan sementara positif punya 500, model bakal condong nebak positif terus.
Tanpa smoothing, peluang kata itu jadi nol dan seluruh perkaliannya ikut nol, jadi kelas tersebut langsung gugur. Laplace smoothing nambahin 1 ke tiap hitungan biar nggak ada yang nol. Di scikit-learn ini diatur lewat parameter alpha yang defaultnya 1,0.
Cocok, asal kamu pilih varian yang benar. Buat data kategorikal kayak metode bayar atau kota, Multinomial atau Categorical Naive Bayes jalan bagus. Buat angka kontinu, pakai Gaussian. Yang perlu kamu sadari, asumsi antar fitur saling bebas jadi makin bermasalah kalau fiturmu berkorelasi kuat.
Tiga hal yang layak kamu bawa dari sini.
Pertama, Naive Bayes cuma ngitung peluang tiap kelas lalu ambil yang terbesar. Nggak ada sihir di dalamnya, dan kamu udah lihat sendiri semua angkanya.
Kedua, Laplace smoothing itu wajib. Tanpa dia, satu kata asing bisa ngerusak seluruh prediksi.
Ketiga, angka 67,4% tadi lebih berguna dari label "positif" doang. Simpan skor peluangnya, pakai buat nentuin mana yang perlu dicek manusia.
Mau lanjut? Baca uji chi-square buat ngecek hubungan antar variabel kategorikal, atau latihan narik data ulasan dari database di NgulikSQL.
Mau praktek langsung? Mulai latihan SQL gratis
Latihan interaktif, langsung di browser.
Kolom datetime nyimpen tanggal, jam, hari, semuanya nempel jadi satu. Accessor .dt di pandas ngeluarin tiap bagian jadi kolom sendiri buat dianalisa.
Nama toko ketik campur huruf besar-kecil, spasi nyasar di ujung, atau kode produk nempel jadi satu. Accessor .str di pandas ngerapiin semua itu tanpa loop.
Model machine learning cuma ngerti angka, bukan teks kayak merah atau biru. get_dummies ngubah kolom kategori jadi kolom 0/1 dalam satu baris kode.