◆版權聲明:本文出自胖喵~的博客,轉載必須注明出處。
轉載請注明出處:http://www.cnblogs.com/by-dream/p/7683126.html
前言
機器翻譯的評測,很大程度上會依賴評測集。制作一份好的評測集,遠遠沒有我們想象的那么簡單。
今天我就將自己制作評測集的經驗分享給大家。以一個制作“幾十句口語關於天氣的英中評測集”為例。
收集原句
首先收集指定數量的討論天氣的口語句子。這些句子都是都是通過花錢,找國外的朋友幫忙收集來的,因此這些英文句子非常的native。
人工評價
將收集來的原句用目前當下比較流行的翻譯引擎翻譯了一遍。這里選取了百度、有道、搜狗、google、騰訊翻譯君nmt2.0,然后將機器翻譯結果生成一個評測問卷,針對譯文的質量進行一個1—5分的打分:
一般打分需要專業的人士來打,並且對他們的結果進行一個相關度的計算,剔除非法的數據,這個過程我就不細說了。這是打分后的一個統計結果如下所示:
可以看到騰訊翻譯君的翻譯質量是最高的,人工可接受度達到了91%,其次分別是百度、有道、搜狗和google。因此我們的評測集在BLEU上的相關性也需要和這個結果保持一致。
譯文制作
接下來了解了各個翻譯引擎的好壞后,我們就可以開始制作評測集了,首先找專業的譯員對原句進行翻譯制作評測集,這里我找了英語專業的學生對原文進行了翻譯。然后我們用她翻譯的結果做為譯文,進行制作參考答案,這里需要注意的是,由於BLEU算法的特性,因此中文的譯文需要按單字切詞:
例如:“這個月的18號,我要去一趟Atlanta。” 轉化后為 “這 個 月 的 18 號 ,我 要 去 一 趟 Atlanta 。 ”
然后針對翻譯結果進行BLEU值的計算。
很明顯這個結果和人工評價的結果相差過大,那么究竟問題出在哪里了呢?
譯文分析、修改、迭代
根據BLEU算法的特性,我們知道BLEU的分值高低取決於翻譯譯文和參考譯文之間的相似度。於是我簡單看了一下,發現可能是句子過於短,ref的答案過於單一,不夠豐富導致的分值上有所差異,因此又增加了幾個ref的制作,具體是在各個翻譯引擎翻譯的基礎上,又進行修改,得到高質量的譯文。總共下來一共制作了9分ref。
此時得到的結果:
可以看到,和之前相比較分值雖然高了,但是和人工評價的一致性還是比較差,因此我們就需要對單句進行分析,看看具體是哪些句子造成了影響。
這里我用python的nltk實現了一個BLEU單句分析的腳本:
#-*- coding:utf-8 -*- import nltk import sys import codecs # 功能:傳入計算譯文單句BLEU的功能 # 調用方式:python 腳本.py 參考答案1+參考答案2 要分析的譯文 # 參數一:可以是多份譯文例如 t_tmq_ref0+t_tmq_ref1 用+連接即可 # 參數二:要計算的譯文 ''' nltk 簡單用法 print nltk.translate.bleu_score.corpus_bleu(['把 卷 子 往 后 傳'], ['把 這 些 紙 往 后 傳 。'],['把 這 些 床 單 遞 回 去 。'] ) print nltk.translate.bleu_score.corpus_bleu(['天 氣 很 好'], ['天 氣 很 不 錯']) print nltk.translate.bleu_score.sentence_bleu('天 氣 非 常 不 錯', '天 氣 很 不 錯' ) ''' reffiles = sys.argv[1] file2 = sys.argv[2] list_all_ref = [] list2 = [] # 讀取譯文 i = 0 for sen in open(file2): sen = sen.strip() if sen: list2.append(sen) i = i+1 else: print i, "is null" # 讀取ref for reffile in reffiles.split('+'): list_ref = [] for line in open(reffile): line = line.strip() if line: list_ref.append(line) list_all_ref.append(list_ref) setnum = len(list_all_ref) sentencenum = len(list_all_ref[0]) log = codecs.open("res_"+file2 , 'w', 'utf-8') # 單句計算 for j in range(0, sentencenum): refs = [] for i in range(0, setnum): refs.append(list_all_ref[i][j]) try: #print refs #print list2[j] BLEUscore = nltk.translate.bleu_score.corpus_bleu([refs], [list2[j]]) print j, BLEUscore log.write(str(BLEUscore)+'\n') except Exception as e: print 'except!',e break
利用腳本計算結果,如下所示
第一列是百度的譯文,第二列是百度單句的一個BLEU得分,第三列是騰訊翻譯君nmt2.0的BLEU得分,第四列是翻譯君的譯文。我們可以通過看句子找到一些分值不合理的句子,用紅色標注。
例如下面這句,很明顯百度的翻譯沒有翻譯君的好,但是BLEU分值卻高。
經過檢查參考譯文,發現有一份參考譯文中有低質量的翻譯句子。於是我們需要對這些句子再進行修改。當然如果人力不足和時間不足的情況下,這種現象無法避免。雖然可以通過要求第一遍制作就不出這些問題,但是真的很難。這里之所以列出這個方法,也是想說明,如果遇到這樣的問題,可以通過這樣一種方法來分析並且可以知道譯文是否的可靠。
好,我們根據剛才所說的方法,修正完所有的譯文后,再次重新計算bleu。
修正后的 百度和nmt2.0的分值對比為:
nmt2.0
BLEU = 77.71, 93.4/84.5/76.0/64.9 (BP=0.984, ratio=0.984, hyp_len=364, ref_len=370)
baidu
BLEU = 76.96, 92.4/82.4/73.1/64.4 (BP=0.995, ratio=0.995, hyp_len=369, ref_len=371)
從分值排名來看,這次更符合實際了,因此用同樣的方法處理了剩余的,最終得到了如下結果(注意這里的結果采取的是去掉和引擎相關的ref計算的BLEU,因此是兩兩比較):
根據分值,我們簡單看下和人工評價的相關性
很明顯,在百度和nmt2.0的比較重相關性不是高,於是我在想,是不是當時在中文分詞的時候影響了最終的數據結果,於是我決定用分詞代替中文單詞切詞的方式,再計算一次BLEU。
這次分詞效果和之前不一樣的是:
例如:“這個月的18號,我要去一趟Atlanta。” 轉化后為 “ 這個月 的 18號 , 我 要去 一趟 Atlanta 。 ”
計算的BLEU結果為:
這次可以看到nmt2.0和百度的分值已經稍微有些拉開了,但是有道和百度的排名卻換了一個位置。於是針對有道和百度,我對每個句子又進行了單句BLEU的分析,以及將人工評價的打分也列到這里進行對比:
我們單看上圖中標注的這句話,這句話應該被正確翻譯為 “ 我希望天氣能一直保持溫暖 ” ,因此人工評價的時候,考慮到“天氣”這個重要的詞沒有被翻譯出來,因此給打了2分,但是BLEU算法匹配到了大部分的詞,只是少了天氣,因此BLEU給出的分值不會很低,要比人工評價的結果高。因此我們看出BLEU算法針對翻譯的流暢度評價是一個比較好的打分,但是對於一些核心詞語的翻譯的重視度,BLEU算法卻忽略了,因此我覺得百度和有道的差距應該就在這里了 。
至此我們就算完成了一份偏流暢度的關於天氣口語評測的評測集。(所有數據)