Uji akhir sebuah pengklasifikasi bukan akurasi pada data held-out, melainkan perilakunya pada teks yang benar-benar baru. Bagian penutup proyek ini membungkus model terlatih menjadi CLI sederhana: tanpa argumen, skrip memprediksi lima teks contoh bawaan; dengan argumen, skrip memprediksi teks apa pun yang diketik pengguna. Kita akan memeriksa kelima prediksi tersebut satu per satu, termasuk satu kasus yang mengandung negasi.
Skrip CLI Prediksi #
prediksi.py tidak menyalin kode pelatihan; skrip ini mengimpor latih_model dari latih.py sehingga model, vocabulary, dan panjang maksimum selalu konsisten dengan hasil Bagian 3:
"""CLI prediksi sentimen untuk teks ulasan baru.
Pemakaian:
python3 prediksi.py # 5 contoh bawaan
python3 prediksi.py "teks ulasan" ... # prediksi teks argumen
Model dilatih ulang lewat latih_model() dari latih.py (durasi beberapa
detik, deterministik), lalu dipakai untuk memprediksi teks yang belum
pernah dilihat pada saat pelatihan.
"""
import sys
import torch
from latih import NAMA_KELAS, latih_model
from model import peluang_kelas
from preprocessing import teks_ke_ids
CONTOH_TEKS = [
"kualitasnya bagus dan pengiriman cepat",
"paket tiba dalam kondisi rusak",
"apakah produk ini tersedia warna hitam",
"pelayanan tokonya memuaskan sekali",
"harga tidak sebanding dengan kualitas yang buruk",
]
def prediksi_teks(model, vocab, panjang_maks, teks):
"""Kembalikan (nama kelas, daftar peluang tiga kelas) untuk satu teks."""
ids = torch.tensor([teks_ke_ids(teks, vocab, panjang_maks)])
with torch.no_grad():
peluang = peluang_kelas(model(ids))[0].tolist()
return NAMA_KELAS[peluang.index(max(peluang))], peluang
def main():
model, vocab, pm, _ = latih_model(cetak=False)
daftar_teks = sys.argv[1:] if len(sys.argv) > 1 else CONTOH_TEKS
print("prediksi teks baru:")
for teks in daftar_teks:
kelas, peluang = prediksi_teks(model, vocab, pm, teks)
rincian = " | ".join(
f"{n} {p:.3f}" for n, p in zip(NAMA_KELAS, peluang))
print(f" '{teks}'")
print(f" -> {kelas} ({rincian})")
if __name__ == "__main__":
main()Skrip di atas menghasilkan keluaran berikut saat dijalankan di mesin uji (CPU, PyTorch 2.14):
Output yang Dihasilkan:
prediksi teks baru:
'kualitasnya bagus dan pengiriman cepat'
-> positif (negatif 0.000 | netral 0.000 | positif 1.000)
'paket tiba dalam kondisi rusak'
-> negatif (negatif 1.000 | netral 0.000 | positif 0.000)
'apakah produk ini tersedia warna hitam'
-> netral (negatif 0.000 | netral 1.000 | positif 0.000)
'pelayanan tokonya memuaskan sekali'
-> positif (negatif 0.000 | netral 0.000 | positif 1.000)
'harga tidak sebanding dengan kualitas yang buruk'
-> negatif (negatif 1.000 | netral 0.000 | positif 0.000)Mari kita telaah kode di atas baris per baris:
- Baris 20-26 (
CONTOH_TEKS): lima teks uji sengaja memuat tiga kelas sekaligus — pujian, keluhan, pertanyaan netral — plus satu kalimat dengan negasi ganda pada teks terakhir. - Baris 29-35 (
prediksi_teks): satu teks diubah menjadi id, dilewatkan ke model dalam modetorch.no_grad(), lalu logits diubahpeluang_kelas(softmax) menjadi tiga peluang yang berjumlah 1. Kelas dengan peluang terbesar dipilih lewatpeluang.index(max(peluang)). - Baris 37-46 (
main):sys.argv[1:]menampung teks dari baris perintah; bila kosong, daftar contoh bawaan yang dipakai. Pelatihan ulang memakan waktu beberapa detik dan hasilnya identik berkat seed tetap.
Memeriksa Lima Prediksi #
Kelima prediksi benar dan peluangnya tegas:
| Teks | Prediksi | Peluang |
|---|---|---|
| kualitasnya bagus dan pengiriman cepat | positif | 1.000 |
| paket tiba dalam kondisi rusak | negatif | 1.000 |
| apakah produk ini tersedia warna hitam | netral | 1.000 |
| pelayanan tokonya memuaskan sekali | positif | 1.000 |
| harga tidak sebanding dengan kualitas yang buruk | negatif | 1.000 |
Dua teks pertama mengombinasikan dua kata kunci dari kelas yang sama — model mengonfirmasi keduanya, bukan menebak dari satu kata. Teks ketiga berbentuk pertanyaan tanpa kata perasaan dan jatuh ke kelas netral, persis perilaku yang diharapkan dari vocabulary netral seperti “tersedia”. Teks kelima menarik karena memuat frasa “tidak sebanding” yang hanya muncul pada templat negatif saat pelatihan; embedding kata “tidak” dan “sebanding” belajar mendorong prediksi ke negatif walau mean pooling tidak memahami struktur kalimat.
Prediksi dari Baris Perintah #
Pengguna dapat langsung mengirim teksnya sendiri tanpa membuka kode:
python3 prediksi.py "pengiriman lambat sekali" "Budi senang karena barangnya awet"Output yang Dihasilkan:
prediksi teks baru:
'pengiriman lambat sekali'
-> negatif (negatif 1.000 | netral 0.000 | positif 0.000)
'Budi senang karena barangnya awet'
-> positif (negatif 0.000 | netral 0.000 | positif 1.000)Kedua teks di luar daftar contoh juga terklasifikasi benar dengan peluang penuh — nama tokoh “Budi” tidak mengganggu karena kata tersebut memang muncul pada data latih tanpa kaitan kelas.
Proyek analisis sentimen tuntas: dataset, preprocessing, model, training, evaluasi, test, dan CLI prediksi bekerja sebagai satu kesatuan yang deterministik. Isi laporan/LAPORAN.md dengan hasil eksekusi Anda sebagai dokumentasi akhir. Proyek berikutnya berpindah domain dari teks ke nilai berurutan: memprediksi deret waktu dengan LSTM.