機器翻譯評價指標BLEU介紹

原文鏈接:https://machinelearningmastery.com/calculate-bleu-score-for-text-python/

最近需要設計一個機器翻譯相關的試驗, 其中好多東西都不同, 先從基礎的評價指標來吧. 本文翻譯自Jason Brownlee的博客[1]. 可能會簡化一部分內容, 如有需要請讀者直接讀原文.

0. 前言

BLEU (其全稱爲Bilingual Evaluation Understudy), 其意思是雙語評估替補。所謂Understudy (替補),意思是代替人進行翻譯結果的評估。儘管這項指標是爲翻譯而發明的,但它可以用於評估一組自然語言處理任務生成的文本。

本教程中, 你將會學會使用Python中的NLTK庫來對待評估的文本求BLEU得分. 在本教程結束之後, 你應該知道:

  • 對BLEU的簡單介紹以及其計算方式的直覺介紹.
  • 如何使用Python中的NLTK庫來計算BLEU值.
  • 利用 待選文本(candidate text)參考文本(reference text) 的差異來分析其對BLEU值的影響.

讓我們開始吧~

1. 概述

本教程分爲4個部分:

  • ① BLEU
  • ② 計算BLEU的得分
  • ③ 累積和單獨的BLEU分數 (Cumulative and Individual BLEU Scores)
  • ④ 例子

2. Bilingual Evaluation Understudy: BLEU

在自然語言處理中的機器翻譯任務中, BLEU非常常見, 它是用於評估模型生成的句子(candidate)實際句子(reference)的差異的指標.
它的取值範圍在0.0到1.0之間, 如果兩個句子完美匹配(perfect match), 那麼BLEU是1.0, 反之, 如果兩個句子完美不匹配(perfect mismatch), 那麼BLEU爲0.0.
雖然這個指標不夠完美, 但是它有5個非常引人注目的好處(compelling benefits):

  • 計算代價小, 快.
  • 容易理解.
  • 與語言無關(這意味着你可以使用全世界任意的語言來測試).
  • 與人類評價結果高度相關.
  • 被學術界和工業界廣泛採用.

BLEU值是2002年由IBM 科學家 Kishore Papineni在其論文[2]中提出的: “BLEU: a Method for Automatic Evaluation of Machine Translation“.

BLEU方法的實現是分別計算candidate句reference句N-grams模型[3], 然後統計其匹配的個數來計算得到的. 顯然, 這種比較方法, 是與語序無關的.

論文對匹配的 N-grams 計數進行了修改,以確保它考慮到reference文本中單詞的出現,而非獎勵生成大量合理翻譯單詞的候選結果。本文將其稱爲修正的 N-grams 精度。

此外, 有一種改進版的通過normalize N-grams的改進版BLEU. 其目的是提升對多個句子組成的**塊(block)**提升翻譯效果.
在實踐中得到完美的分數是不太可能的,因爲翻譯結果必須與reference句完全匹配。甚至人工翻譯都不可能做到這一點。而且, 由於不同的數據集reference句的質量和數量不同, 所以跨數據集計算BLEU值可能帶來一些麻煩.

對機器翻譯來說, 我們可以使用BLEU得分來評價其它的語言生成任務, 比如:

  • 語言生成.
  • 圖像標題生成.
  • 文本總結.
  • 語音識別.

及其它.

3. 計算BLEU得分

Python自然語言工具包庫: NLTK, 提供了BLEU得分計算的實現, 所以如果你只是像譯者一樣使用的話, 可以先不去了解其內部的實現.

3.1 句子的BLEU值

NLTK提供了sentence_bleu()來評估一組candidate句reference句的BLEU得分情況. 其中, 這兩個句子都必須用一系列tokens表示:

注: 這個reference的形式有點像圖像檢索裏面的圖像gallery.

>>> from nltk.translate.bleu_score import sentence_bleu
>>> reference = [['this', 'is', 'a', 'test'], ['this', 'is' 'test']]
>>> candidate = ['this', 'is', 'a', 'test']
>>> score = sentence_bleu(reference, candidate)
>>> print(score)
1.0

這個例子的結果爲1.0, 因爲candidate與reference的第1個句子perfect match了.

3.2 Corpus(語料庫)的BLEU值

NLTK同樣提供了corpus_bleu()函數, 它用於來對多個句子比如一個段落甚至一篇文章進行得分評價.

參考句必須由一系列documents組成, 每個document都應該由一系列references組成, 同樣的, 每個句子都應該拆分爲一個個token. 如下, 其實比上一部分多了一個維度.

可能上面的解釋還是容易讓人困惑, 下面是一篇文檔的2個參考句的示例(我的理解: 比Sentence的都多加了一個維度):

# two references for one document
>>> from nltk.translate.bleu_score import corpus_bleu
>>> references = [[['this', 'is', 'a', 'test'], ['this', 'is' 'test']]]
>>> candidates = [['this', 'is', 'a', 'test']]
>>> score = corpus_bleu(references, candidates)
>>> print(score)

1.0

4. 累積BLEU和獨立BLEU

在NLTK中, 其允許用戶顯式指定不同的N-grams的權重以便來計算BLEU的值. 這使得用戶可以靈活的計算不同類型的BLEU值, 比如獨立的BLEU或者累積的BLEU.

4.1 獨立N-Gram得分

一個獨立的N-gram得分是對gram是否按特定順序排列的評估方式, 比如1-gram和2-gram (2-gram又成爲bigram)[3]:

# 1-gram individual BLEU
>>> from nltk.translate.bleu_score import sentence_bleu
>>> reference = [['this', 'is', 'small', 'test']]
>>> candidate = ['this', 'is', 'a', 'test']
>>> score = sentence_bleu(reference, candidate, weights=(1, 0, 0, 0))
>>> print(score)

0.75

>>> candidate = ['this', 'test', 'is', 'a']
>>> score = sentence_bleu(reference, candidate, weights=(1, 0, 0, 0))
>>> score
0.75

可以看到, 1-gram有3/4個詞完全對應上, 所以得分爲0.75, 那麼如果我們試試把candidate的順序打亂呢? 結果仍爲0.75~

下面, 作者測試了1-4gram如下:

>>> from nltk.translate.bleu_score import sentence_bleu
>>> reference = [['this', 'is', 'a', 'test']]
>>> candidate = ['this', 'is', 'a', 'test']
>>> print('Individual 1-gram: %f' % sentence_bleu(reference, candidate, weights=(1, 0, 0, 0)))
>>> print('Individual 2-gram: %f' % sentence_bleu(reference, candidate, weights=(0, 1, 0, 0)))
>>> print('Individual 3-gram: %f' % sentence_bleu(reference, candidate, weights=(0, 0, 1, 0)))
>>> print('Individual 4-gram: %f' % sentence_bleu(reference, candidate, weights=(0, 0, 0, 1)))


Individual 1-gram: 1.000000
Individual 2-gram: 1.000000
Individual 3-gram: 1.000000
Individual 4-gram: 1.000000

儘管我們可以計算獨立的BLEU值, 但是這種方式不是常規使用的方式, 而且獨立BLEU值的含義也比較有限. 因此, 下面我們引出累積BLEU值.

4.2 累積N-Gram得分

累積N-Gram得分指的是爲各個gram對應的權重加權, 來計算得到一個加權幾何平均(weighted geometric mean). 默認情況下, sentence_bleu()corpus_bleu()都是計算累積的4-gram BLEU分數的, 也稱之爲BLEU-4.
BLEU-4的加權策略如下: 1/4 (25%) 或者 0.25 對 1-gram, 2-gram, 3-gram and 4-gram 的得分.

# 4-gram cumulative BLEU
>>> from nltk.translate.bleu_score import sentence_bleu
>>> reference = [['this', 'is', 'small', 'test']]
>>> candidate = ['this', 'is', 'a', 'test']
>>> score = sentence_bleu(reference, candidate)
>>> score
1.0547686614863434e-154
>>> score = sentence_bleu(reference, candidate, weights=(0.25, 0.25, 0.25, 0.25))
>>> score
1.0547686614863434e-154

下面, 我們分別計算從BLEU-1到BLEU-4的累積N-Gram得分:

>>> print('Cumulative 1-gram: %f' % sentence_bleu(reference, candidate, weights=(1, 0, 0, 0)))
Cumulative 1-gram: 0.750000
>>> print('Cumulative 2-gram: %f' % sentence_bleu(reference, candidate, weights=(0.5, 0.5, 0, 0)))
Cumulative 2-gram: 0.500000
>>> print('Cumulative 3-gram: %f' % sentence_bleu(reference, candidate, weights=(0.33, 0.33, 0.33, 0)))
Cumulative 3-gram: 0.000000
>>> print('Cumulative 4-gram: %f' % sentence_bleu(reference, candidate, weights=(0.25, 0.25, 0.25, 0.25)))
Cumulative 4-gram: 0.000000

通常情況下, 我們會統計BLEU1BLEU4的累積值作爲評估 文本生成系統(text generation system) 的效果.

5. 樣例

本部分, 我們將對BLEU值的設計develop further intuition(通過一些例子), 以一個單句的例子爲例:

the quick brown fox jumped over the lazy dog

首先, 讓我們看看完美匹配的得分:

# prefect match
>>> from nltk.translate.bleu_score import sentence_bleu
>>> reference = [['the', 'quick', 'brown', 'fox', 'jumped', 'over', 'the', 'lazy', 'dog']]
>>> candidate = ['the', 'quick', 'brown', 'fox', 'jumped', 'over', 'the', 'lazy', 'dog']
>>> score = sentence_bleu(reference, candidate)
>>> print(score)

1.0

接下來, 我們把quick同意替換爲fast, 看看效果:

# one word different
...
>>> candidate = ['the', 'fast', 'brown', 'fox', 'jumped', 'over', 'the', 'lazy', 'dog']
>>> score = sentence_bleu(reference, candidate)
>>> print(score)
 	
0.7506238537503395

接着在此基礎上再改一個單詞, 把lazy 改成 sleepy

# two words different
...
>>> candidate = ['the', 'fast', 'brown', 'fox', 'jumped', 'over', 'the', 'sleepy', 'dog']
>>> score = sentence_bleu(reference, candidate)
>>> print(score)
 	
0.4854917717073234

可以看到, BLEU值出現了下降, 因爲match的對越來越少了. 現在, 我們可以試試這種形式: 將candidate句變短, 再跟reference進行比較

# 刪除candidate句子最後兩個單詞, 即讓candidate變短
...
>>> candidate = ['the', 'fast', 'brown', 'fox', 'jumped', 'over', 'the']
>>> score = sentence_bleu(reference, candidate)
>>> print(score)

0.7514772930752859

那麼, 如果 將candidate句變長, 再跟reference進行比較呢?

...
>>> candidate = ['the', 'quick', 'brown', 'fox', 'jumped', 'over', 'the', 'lazy', 'dog', 'from', 'space']
>>> score = sentence_bleu(reference, candidate)
>>> print(score)

0.7860753021519787

我們可以看到, 分數反而越來越高啦~, BLEU中的數學理論[2, 4]是相當簡單的,我也鼓勵你閱讀這篇論文,並探索自己在電子表格中計算句子水平分數。

6. 總結

在本教程中, 你會瞭解到BLEU的使用和得到一些基本的intuition關於其設計思路, 通過學習, 如下3點你應該掌握:

  • ① A gentle introduction to the BLEU score and an intuition for what is being calculated.
  • ② How you can calculate BLEU scores in Python using the NLTK library for sentences and documents.
  • ③ How to can use a suite of small examples to develop an intuition for how differences between a candidate and reference text impact the final BLEU score.

參考資料

[1] A Gentle Introduction to Calculating the BLEU Score for Text in Python
[2] BLEU: a Method for Automatic Evaluation of Machine Translation
[3] 蕉叉熵: N-grams說明
[4] BLEU 維基百科

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章