Representasi Teks: Bag of Words, N-gram, dan TF-IDF
Pada sesi ini mahasiswa mulai masuk ke pertanyaan yang sangat penting, yaitu bagaimana teks bisa diubah menjadi angka. Komputer tidak bisa langsung menghitung kalimat seperti manusia membacanya. Karena itu kita memerlukan cara untuk mengubah dokumen menjadi fitur numerik. Fitur inilah yang nanti dipakai oleh model untuk belajar.
Ibaratnya, pada sesi 2 kita sudah membersihkan bahan makanan. Pada sesi 3 kita mulai menimbang, mengukur, dan menuliskan komposisinya agar bisa diolah lebih lanjut. Teks yang sudah rapi akan kita ubah menjadi representasi angka menggunakan BoW, N-gram, dan TF-IDF.
Kenapa teks harus diubah menjadi angka
Kalau manusia membaca dua kalimat, kita bisa langsung merasa bahwa kalimat itu mirip atau tidak. Misalnya kalimat “aplikasi ini sangat membantu” dan “aplikasi ini sangat berguna” terasa dekat maknanya. Namun komputer perlu bentuk yang lebih terstruktur. Salah satu cara paling awal dan paling penting adalah menghitung kata-kata yang muncul di dalam dokumen.
Bayangkan ada tiga warung makan. Kita ingin membandingkan menunya. Cara paling sederhana adalah mencatat berapa kali tiap bahan muncul di masing-masing warung, misalnya nasi, ayam, mie, teh, dan kopi. Representasi teks bekerja dengan ide yang mirip. Kita membuat daftar kata, lalu menghitung seberapa sering kata itu muncul pada tiap dokumen.
Karena itu, representasi teks adalah jembatan antara bahasa manusia dan perhitungan mesin. Jika jembatan ini tidak dibangun dengan baik, model berikutnya juga akan sulit bekerja dengan baik.
Peta konsep sesi 3
| Konsep | Makna mudahnya | Kapan berguna |
|---|---|---|
| Bag of Words | Menghitung berapa kali kata muncul dalam dokumen. | Saat ingin representasi sederhana dan cepat. |
| N-gram | Menghitung gabungan kata berurutan, bukan hanya satu kata. | Saat urutan kata penting, misalnya “tidak bagus”. |
| TF-IDF | Memberi bobot lebih besar pada kata penting dan lebih kecil pada kata yang terlalu umum. | Saat ingin fitur yang lebih informatif daripada hitungan mentah. |
| Sparse vector | Vektor yang sangat panjang tetapi kebanyakan isinya nol. | Hampir selalu muncul pada representasi teks klasik. |
| Cosine similarity | Mengukur arah kemiripan dua vektor. | Saat ingin membandingkan dua dokumen. |
Bag of Words dengan contoh yang sangat sederhana
Misalkan kita punya tiga kalimat berikut. “aplikasi bagus”, “aplikasi lambat”, dan “fitur aplikasi bagus”. Dari tiga kalimat itu, kita kumpulkan kata unik yang muncul, misalnya aplikasi, bagus, lambat, dan fitur. Lalu setiap kalimat diubah menjadi hitungan kata.
Dokumen 1: aplikasi bagus -> [1, 1, 0, 0]
Dokumen 2: aplikasi lambat -> [1, 0, 1, 0]
Dokumen 3: fitur aplikasi bagus -> [1, 1, 0, 1]Urutan vektor di atas bisa dibayangkan sebagai [aplikasi, bagus, lambat, fitur]. Jadi angka 1 artinya kata itu muncul, angka 0 artinya tidak muncul. Jika kata muncul dua kali, nilainya bisa menjadi 2.
Nama Bag of Words artinya “kantong kata”. Disebut seperti kantong karena urutan kata sering diabaikan. Yang dilihat lebih dulu adalah isi katanya, bukan susunannya.
Kelebihan dan kelemahan Bag of Words
Kelebihan
Sangat mudah dipahami, cepat dibuat, dan cocok untuk pengantar. Mahasiswa cepat melihat bagaimana teks bisa berubah menjadi angka.
Kelemahan
Urutan kata sering hilang. Kalimat “tidak bagus” dan “bagus” bisa terlihat mirip jika model hanya melihat kata tanpa konteks urutan.
Inilah alasan kita perlu mengenal N-gram. N-gram membantu komputer menangkap gabungan kata yang berurutan sehingga makna seperti “tidak bagus” bisa tetap terlihat.
Mengenal N-gram
Unigram
Satu kata per fitur. Contoh dari kalimat “aplikasi sangat bagus” adalah aplikasi, sangat, dan bagus.
Bigram
Dua kata berurutan per fitur. Contohnya aplikasi sangat dan sangat bagus.
Trigram
Tiga kata berurutan per fitur. Contohnya aplikasi sangat bagus.
Kalau unigram ibarat menghitung bahan satuan, bigram dan trigram ibarat menghitung pasangan atau rangkaian bahan yang sering muncul bersama. Kadang justru pasangan inilah yang paling penting untuk makna.
Kenapa TF-IDF sering terasa lebih pintar daripada hitungan biasa
Pada Bag of Words, kata yang sering muncul akan mendapat nilai tinggi. Masalahnya, kata yang sering muncul belum tentu penting. Misalnya pada kumpulan berita kampus, kata “kampus”, “mahasiswa”, atau “sistem” mungkin muncul di hampir semua dokumen. Jika semua kata umum itu terus diberi bobot besar, model sulit membedakan dokumen satu dengan yang lain.
Bayangkan kita ingin mengenali mahasiswa dari isi tasnya. Barang seperti buku tulis mungkin hampir semua orang punya, jadi kurang membantu membedakan. Tetapi barang seperti kalkulator teknik, stetoskop, atau kuas gambar lebih khas. TF-IDF bekerja mirip begitu. Kata yang terlalu umum nilainya ditekan, kata yang lebih khas nilainya dinaikkan.
TF berarti term frequency, yaitu seberapa sering kata muncul dalam satu dokumen. IDF berarti inverse document frequency, yaitu ukuran seberapa jarang kata itu muncul pada seluruh dokumen. Gabungan keduanya membantu menonjolkan kata yang penting.
Sparse vector dengan bahasa sederhana
Saat jumlah kosakata makin banyak, panjang vektor juga ikut membesar. Misalnya ada 5.000 kata unik dalam seluruh dataset, maka satu dokumen bisa direpresentasikan sebagai vektor sepanjang 5.000 kolom. Tetapi satu dokumen biasanya hanya berisi sedikit kata dari total 5.000 itu. Artinya sebagian besar nilainya nol.
Itulah yang disebut sparse vector, yaitu vektor yang kebanyakan elemennya nol. Pada data teks, kondisi ini sangat umum. Karena itu scikit-learn menyimpan hasil vectorizer dalam format sparse matrix agar lebih hemat memori.
Praktikum 1: Mengubah teks menjadi angka dengan CountVectorizer
Kode berikut adalah contoh lengkap yang cukup enak dipakai di kelas. Mahasiswa bisa langsung melihat daftar kosakata, bentuk matriks fitur, dan isi vektornya.
import pandas as pd
from sklearn.feature_extraction.text import CountVectorizer
corpus = [
"aplikasi kampus sangat membantu",
"aplikasi kampus sering lambat",
"fitur krs pada aplikasi sangat membantu",
"login aplikasi kampus kadang gagal"
]
vectorizer = CountVectorizer()
X = vectorizer.fit_transform(corpus)
fitur = vectorizer.get_feature_names_out()
df_bow = pd.DataFrame(X.toarray(), columns=fitur)
print("Daftar fitur:")
print(fitur)
print("\nMatriks BoW:")
print(df_bow)Dari kode ini mahasiswa biasanya mulai paham bahwa satu dokumen berubah menjadi satu baris angka. Setiap kolom mewakili kata tertentu. Nilainya menunjukkan jumlah kemunculan kata itu pada dokumen.
Praktikum 2: Menggunakan N-gram agar urutan kata ikut diperhatikan
Contoh ini penting untuk menunjukkan bahwa kata “tidak bagus” berbeda dengan “sangat bagus”. Jika hanya unigram, keduanya sama-sama punya kata “bagus”. Dengan bigram, pasangan katanya ikut terbaca.
import pandas as pd
from sklearn.feature_extraction.text import CountVectorizer
corpus = [
"aplikasi ini bagus",
"aplikasi ini tidak bagus",
"fitur login sangat bagus",
"fitur login tidak stabil"
]
vectorizer_bigram = CountVectorizer(ngram_range=(1, 2))
X_bigram = vectorizer_bigram.fit_transform(corpus)
fitur_bigram = vectorizer_bigram.get_feature_names_out()
df_bigram = pd.DataFrame(X_bigram.toarray(), columns=fitur_bigram)
print("Jumlah fitur:", len(fitur_bigram))
print("Contoh fitur:")
print(fitur_bigram[:20])
print("\nMatriks unigram + bigram:")
print(df_bigram)Perhatikan nanti akan muncul fitur seperti “ini bagus”, “tidak bagus”, “sangat bagus”, dan “login tidak”. Dari sini mahasiswa bisa melihat bahwa urutan kata bisa membawa makna tambahan.
Praktikum 3: Menghitung TF-IDF dan melihat kata dominan
Pada contoh berikut, kita tidak hanya menghitung jumlah kata, tetapi juga bobot pentingnya. Setelah itu kita cari kata dengan bobot tertinggi pada tiap dokumen agar mahasiswa bisa melihat kata dominannya.
import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
corpus = [
"aplikasi kampus sangat membantu mahasiswa",
"aplikasi kampus sering lambat saat login",
"fitur krs membantu mahasiswa memilih mata kuliah",
"login sering gagal saat server sibuk"
]
vectorizer = TfidfVectorizer()
X_tfidf = vectorizer.fit_transform(corpus)
fitur = vectorizer.get_feature_names_out()
df_tfidf = pd.DataFrame(X_tfidf.toarray(), columns=fitur)
print(df_tfidf.round(3))
for i, row in df_tfidf.iterrows():
top_terms = row.sort_values(ascending=False).head(5)
print(f"\nDokumen {i+1}:")
print(top_terms)Dengan kode ini, mahasiswa bisa melihat bahwa kata yang paling dominan pada dokumen tertentu tidak selalu kata yang paling sering muncul di semua dokumen.
Praktikum 4: Mengukur kemiripan dua dokumen dengan cosine similarity
Setelah teks diubah menjadi vektor, kita bisa menghitung kemiripan. Salah satu ukuran yang paling sering dipakai adalah cosine similarity. Nilainya biasanya antara 0 sampai 1. Semakin mendekati 1, semakin mirip arah vektornya.
import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
corpus = [
"aplikasi kampus membantu pengisian krs",
"sistem kampus membantu proses krs online",
"cuaca hari ini sangat cerah"
]
vectorizer = TfidfVectorizer()
X = vectorizer.fit_transform(corpus)
similarity_matrix = cosine_similarity(X)
df_similarity = pd.DataFrame(similarity_matrix,
index=[f"Doc_{i+1}" for i in range(len(corpus))],
columns=[f"Doc_{i+1}" for i in range(len(corpus))])
print(df_similarity.round(3))Biasanya dokumen 1 dan dokumen 2 akan punya kemiripan lebih tinggi karena sama-sama membahas sistem kampus dan KRS, sedangkan dokumen 3 cenderung jauh karena membahas cuaca.
Studi kasus mini: mencari ulasan yang mirip
Bayangkan ada banyak komentar mahasiswa. Pihak kampus ingin tahu apakah komentar baru itu mirip dengan komentar lama tentang login, KRS, atau server. Dengan TF-IDF dan cosine similarity, sistem sederhana sudah bisa membantu mencari komentar yang paling dekat.
Langkah 1
Bersihkan teks dan ubah menjadi TF-IDF.
Langkah 2
Hitung cosine similarity antara komentar baru dan komentar lama.
Langkah 3
Ambil komentar yang nilainya paling tinggi sebagai dokumen paling mirip.
Inilah fondasi penting untuk semantic search versi awal. Walaupun belum secanggih embedding modern, pendekatan ini sudah sangat berguna untuk memperkenalkan ide pencarian berbasis kemiripan.
Contoh notebook mini yang lebih lengkap
Jika dosen ingin satu contoh yang bisa dijalankan dari awal sampai akhir, kode berikut cukup cocok. Di dalamnya ada BoW, TF-IDF, dan cosine similarity sekaligus.
import pandas as pd
from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
# data sederhana
ulasan = [
"aplikasi krs mudah digunakan",
"aplikasi krs sering lambat saat jam sibuk",
"login ke sistem akademik cukup mudah",
"server sering error saat pengisian krs"
]
# 1. Bag of Words
cv = CountVectorizer()
X_bow = cv.fit_transform(ulasan)
df_bow = pd.DataFrame(X_bow.toarray(), columns=cv.get_feature_names_out())
print("=== BAG OF WORDS ===")
print(df_bow)
# 2. TF-IDF
tfidf = TfidfVectorizer()
X_tfidf = tfidf.fit_transform(ulasan)
df_tfidf = pd.DataFrame(X_tfidf.toarray(), columns=tfidf.get_feature_names_out())
print("\n=== TF-IDF ===")
print(df_tfidf.round(3))
# 3. Similarity
sim = cosine_similarity(X_tfidf)
df_sim = pd.DataFrame(sim, columns=[f"Doc{i+1}" for i in range(len(ulasan))],
index=[f"Doc{i+1}" for i in range(len(ulasan))])
print("\n=== COSINE SIMILARITY ===")
print(df_sim.round(3))
# 4. kata dominan tiap dokumen
print("\n=== KATA DOMINAN TIAP DOKUMEN ===")
for i, row in df_tfidf.iterrows():
print(f"Dokumen {i+1}:", row.sort_values(ascending=False).head(3).to_dict())Dari satu notebook kecil ini saja mahasiswa sudah bisa mendapatkan tiga keterampilan penting, yaitu membuat fitur, membaca bobot kata, dan mengukur kemiripan dokumen.
Kesalahan umum mahasiswa pada sesi 3
Kesalahan pertama adalah mengira nilai TF-IDF yang besar berarti kata itu bagus. Padahal nilai besar hanya berarti kata itu penting untuk dokumen tersebut. Kesalahan kedua adalah mengira sparse matrix itu error, padahal justru itu format normal pada data teks. Kesalahan ketiga adalah terlalu cepat membandingkan model sebelum memahami fitur yang dipakai.
Kalau fitur masih salah, model yang bagus pun bisa terlihat biasa saja. Jadi sesi 3 ini sebenarnya sangat penting. Ia menentukan “kacamata” yang dipakai model saat melihat teks.
Diskusi Mahasiswa dengan Sistem LLM
Tanyakan materi yang masih terkait Pembelajaran Mesin untuk Teks dan AI Generatif.
Pembahasan dibatasi pada topik mata kuliah ini. Pertanyaan di luar tema akan ditolak secara otomatis.