まとめ
- BLEU mengukur kualitas terjemahan dengan menghitung kesamaan n-gram antara kalimat kandidat dan kalimat referensi.
- Implementasi mencakup n-gram precision dan brevity penalty untuk memahami perilaku skor.
- Dibahas juga kelemahannya terhadap urutan kata dan sinonim, serta cara mengatasinya dengan referensi ganda.
1. Konsep BLEU #
- Hitung modified precision untuk n-gram dari 1 hingga 4 antara kandidat dan referensi.
- Ambil rata-rata logaritmik dari presisi dan ubah menjadi rata-rata geometrik.
- Terapkan brevity penalty jika kalimat kandidat lebih pendek dari referensi untuk menghukum pemotongan berlebihan.
Nilai BLEU berada pada rentang 0–1; semakin tinggi, semakin mirip dengan referensi.
2. Contoh Implementasi di Python 3.13 #
Contoh implementasi BLEU menggunakan pustaka standar Python saja.
from __future__ import annotations
import math
from collections import Counter
from collections.abc import Iterable, Sequence
def ngram_counts(tokens: Sequence[str], n: int) -> Counter[tuple[str, ...]]:
"""Hitung frekuensi n-gram dari daftar token."""
return Counter(tuple(tokens[i : i + n]) for i in range(len(tokens) - n + 1))
def modified_precision(
candidate: Sequence[str],
references: Iterable[Sequence[str]],
n: int,
) -> tuple[int, int]:
"""Hitung jumlah n-gram kandidat yang muncul di referensi."""
cand_counts = ngram_counts(candidate, n)
max_ref: Counter[tuple[str, ...]] = Counter()
for ref in references:
max_ref |= ngram_counts(ref, n)
overlap = {ng: min(count, max_ref[ng]) for ng, count in cand_counts.items()}
return sum(overlap.values()), max(1, sum(cand_counts.values()))
def brevity_penalty(candidate_len: int, reference_lens: Iterable[int]) -> float:
"""Hitung brevity penalty jika kalimat kandidat terlalu pendek."""
if candidate_len == 0:
return 0.0
closest_ref_len = min(reference_lens, key=lambda r: (abs(r - candidate_len), r))
ratio = candidate_len / closest_ref_len
if ratio > 1:
return 1.0
return math.exp(1 - 1 / ratio)
def bleu(candidate: str, references: Sequence[str], max_n: int = 4) -> float:
"""Hitung skor BLEU dari kalimat kandidat dan referensi."""
candidate_tokens = candidate.split()
reference_tokens = [ref.split() for ref in references]
precisions: list[float] = []
for n_value in range(1, max_n + 1):
overlap, total = modified_precision(candidate_tokens, reference_tokens, n_value)
precisions.append(overlap / total)
if min(precisions) == 0:
return 0.0
geometric_mean = math.exp(sum(math.log(p) for p in precisions) / max_n)
penalty = brevity_penalty(len(candidate_tokens), (len(ref) for ref in reference_tokens))
return penalty * geometric_mean
if __name__ == "__main__":
candidate_sentence = "the cat is on the mat"
reference_sentences = [
"there is a cat on the mat",
"the cat sits on the mat",
]
score = bleu(candidate_sentence, reference_sentences)
print(f"BLEU = {score:.3f}")
Hasil contoh:
BLEU = 0.638
3. Kelebihan #
- Mudah dan cepat diimplementasikan; telah lama digunakan sebagai tolok ukur penerjemahan mesin.
- Menggunakan beberapa referensi meningkatkan ketahanan terhadap parafrasa.
4. Keterbatasan #
- Sensitif terhadap urutan kata dan sinonim, sehingga terjemahan yang benar bisa mendapat skor rendah.
- Korelasi dengan penilaian manusia menurun pada teks panjang.
- Untuk bahasa seperti Jepang, lakukan tokenisasi atau pemisahan kata sebelum perhitungan.
Ringkasan #
- BLEU menilai kualitas terjemahan berdasarkan kesamaan n-gram dan brevity penalty.
- Dapat diimplementasikan langsung dengan Python 3.13 dan type hints untuk fleksibilitas tinggi.
- Gunakan bersama metrik lain seperti ROUGE atau METEOR untuk menilai keragaman dan kesamaan semantik.