Urutkan hasil teks
Hitung TF-IDF dengan tangan, lihat kenapa skor mentah gampang ditipu, lalu pahami normalisasi panjang dan saturasi term di BM25.
Pertanyaan
Dari seribu dokumen yang cocok, mana yang layak tampil di posisi pertama, dan kenapa?
Setelah baca ini, kamu bisa menghitung skor TF-IDF dan BM25 untuk contoh kecil, menjelaskan peran
parameter k1 dan b, dan memperkirakan dokumen mana yang naik atau turun kalau parameternya
diubah.
Prasyarat dan contoh
Kamu sudah paham inverted index dan posting list (M11.01). Matematika yang dipakai cuma logaritma dan pembagian.
Query "ayam pedas" cocok dengan 400 dokumen. Pengguna jarang membuka halaman kedua, jadi urutannya sama pentingnya dengan kecocokannya. Hitungan paling polos: urutkan berdasarkan berapa kali "ayam" muncul. Dokumen yang menulis "ayam ayam ayam ..." sepuluh kali lalu menang. Itulah yang perlu diperbaiki.
Mekanisme
Anggap korpus berisi N = 1.000 dokumen. Term "ayam" ada di df = 100 dokumen, "pedas" di df = 10.
1. TF-IDF. Dua ide: term yang sering muncul di dokumen itu penting (TF), dan term yang jarang di korpus itu lebih membedakan (IDF).
idf(t) = ln(N / df)
idf(ayam) = ln(1000 / 100) = 2,303
idf(pedas)= ln(1000 / 10) = 4,605
skor = jumlah dari tf(t) x idf(t)
Dokumen X menyebut "ayam" 10 kali, tanpa "pedas". Dokumen Y menyebut masing-masing sekali.
X = 10 x 2,303 = 23,03
Y = 1 x 2,303 + 1 x 4,605 = 6,91
X menang walau nggak menjawab setengah query. TF mentah tumbuh linear tanpa batas, dan ini bisa dimanipulasi (keyword stuffing).
2. BM25. Memperbaiki dua hal: kenaikan TF melandai, dan panjang dokumen dihitung.
idf(t) = ln(1 + (N - df + 0,5) / (df + 0,5))
tfNorm = tf x (k1 + 1) / (tf + k1 x (1 - b + b x dl / avgdl))
skor = jumlah dari idf(t) x tfNorm(t)
Parameter umum: k1 = 1,2 dan b = 0,75. dl panjang dokumen, avgdl rata-rata panjang.
Dengan dl = avgdl, tfNorm menjadi tf x 2,2 / (tf + 1,2):
| tf | tfNorm | | --- | ------ | | 1 | 1,00 | | 2 | 1,38 | | 3 | 1,57 | | 10 | 1,96 |
Batas atasnya k1 + 1 = 2,2. Itulah saturasi: kemunculan ke-10 hampir nggak menambah apa-apa
dibanding kemunculan ke-3. Hitung ulang dengan idf BM25 (ayam = 2,299, pedas = 4,557):
X = 2,299 x 1,96 = 4,52
Y = 2,299 x 1 + 4,557 x 1 = 6,86
Sekarang Y menang, sesuai intuisi.
3. Normalisasi panjang. Dokumen panjang punya peluang lebih besar memuat sebuah term hanya
karena panjang. Parameter b mengatur seberapa kuat hukumannya. Ambil tf = 2:
dl = avgdl: penyebut2 + 1,2 x 1 = 3,2, tfNorm = 4,4 / 3,2 = 1,38.dl = 2 x avgdl: penyebut2 + 1,2 x 1,75 = 4,1, tfNorm = 4,4 / 4,1 = 1,07.
Dokumen sepanjang dua kali rata-rata kehilangan sekitar seperlima nilai term-nya. Dengan b = 0
panjang nggak dihitung, dengan b = 1 dihukum penuh.
4. Field dan boost. Judul biasanya lebih menentukan daripada isi. Praktik umum: hitung skor per field lalu beri bobot (judul x 3, isi x 1). Bobot ini tebakan sampai kamu mengukurnya (M11.06).
Saat rancangan ini gagal
- IDF tergantung korpus. Di toko yang hanya menjual ayam, "ayam" ada di 90% dokumen dan idf-nya hampir nol. Skor bergeser kalau komposisi korpus berubah.
- Statistik beda antar shard. Setiap shard menghitung df sendiri, jadi dokumen yang sama bisa punya skor berbeda tergantung penempatannya (M11.05).
- Parameter default dianggap benar.
k1 = 1,2danb = 0,75cocok untuk teks umum. Untuk judul pendek,bbesar justru merugikan, dan untuk dokumen yang tergolong seragam panjangnya,bhampir nggak berpengaruh. - Relevansi bukan hanya teks. Resep populer dan baru sering lebih berguna daripada yang skor teksnya sedikit lebih tinggi. Sinyal itu perlu masuk ranking, tapi harus terukur.
Contoh tandingan: katalog 3.000 produk dengan judul 2 sampai 4 kata. Panjang hampir seragam, TF hampir selalu 1, jadi saturasi dan normalisasi panjang nggak mengubah urutan. Yang menentukan hasil adalah IDF dan bobot field.
Latihan
Korpus N = 500, avgdl = 100 token. Query "kopi gayo". df(kopi) = 50 dan df(gayo) = 5. Pakai idf
BM25, k1 = 1,2, b = 0,75. Dokumen P: dl = 100, tf(kopi) = 6, tf(gayo) = 0. Dokumen Q: dl = 100,
tf(kopi) = 1, tf(gayo) = 1. Hitung skor keduanya dan sebut yang menang.
Lihat pembahasan
idf(kopi) = ln(1 + (500 - 50 + 0,5) / (50 + 0,5)) = ln(9,92) = 2,295
idf(gayo) = ln(1 + (500 - 5 + 0,5) / (5 + 0,5)) = ln(91,09) = 4,512
dl = avgdl, jadi tfNorm = tf x 2,2 / (tf + 1,2)
tfNorm(6) = 13,2 / 7,2 = 1,833
tfNorm(1) = 2,2 / 2,2 = 1,000
P = 2,295 x 1,833 = 4,21
Q = 2,295 x 1 + 4,512 x 1 = 6,81
Q menang. Walau P menyebut "kopi" enam kali, saturasi membatasi kontribusinya di bawah 1,833 kali idf, sedangkan Q membawa term langka "gayo".
Jawaban yang bagus juga menyebut asumsi: kedua dokumen sepanjang rata-rata, jadi b nggak
berpengaruh, dan hasilnya akan berubah kalau P jauh lebih pendek dari Q.
Terkait
- Sebelumnya: M11.01 Bangun inverted index.
- Lanjut ke M11.03 Dukung pengalaman pencarian.
- Statistik df per shard dibahas lagi di M11.05.
- Lab L11 mengizinkan kamu mengubah
k1danbdan melihat posisi dokumen bergeser. Belum tersedia.
Catatan
- Asumsi: skor dihitung per term dengan rumus BM25 klasik (varian Lucene memakai idf yang sama dengan contoh di sini). Implementasi lain punya variasi kecil.
- Yang nggak dibahas: BM25F untuk banyak field, language model, dan learning to rank.
- Semua angka dibulatkan, jadi hasil hitung tanganmu bisa berbeda di digit terakhir.
- Terakhir ditinjau: 26 Oktober 2026.