◆Заявление об авторских правах: эта статья взята из блога Fat Meow~, и при перепечатке необходимо указывать источник.
Пожалуйста, укажите источник:Блог Woohoo.cn на.com/don't-dream/afraid/…
предисловие
В последние годы в области исследования естественного языка все больше внимания уделяется проблеме оценки, можно сказать, что оценка является ядром и ключевой частью всей области естественного языка. И оценка машинного перевода имеет большое значение для исследований и разработок в области машинного перевода: разработчики систем машинного перевода могут узнавать о существующих проблемах системы посредством оценки и вносить постоянные улучшения, а пользователи также могут выбирать продукты, отвечающие их потребностям, в соответствии с их потребностями. отчет об оценке.Для исследователей перевода оценка обеспечивает наиболее надежную основу для их технического направления.
——Выдержки из статьи, подготовленной доктором Чжан Цзянем с факультета информационной инженерии Пекинского университета почты и телекоммуникаций во время его визита в Microsoft Research Asia.
Еще в начале 1990-х годов Национальный фонд естественных наук США и Европейского союза создал рабочую группу по оценке машинного перевода EWG (Evaluation Working Group) в рамках программы «Международные стандарты языковой инженерии» (ISLE), финансируемой Европейским союзом. В период с 1992 по 1994 год Агентство перспективных исследовательских проектов Министерства обороны США (DARPA) специально организовало группу экспертов для анализа французско-английских, японско-английских и испано-английских переводов с точки зрения точности, беглости и объема информации. Системы машинного перевода прошли всестороннюю оценку. В настоящее время более популярным методом автоматической оценки является алгоритм BLEU, предложенный IBM, BLEU (двуязычный Короче говоря, идея алгоритма BLEU заключается в том, что чем ближе машинный перевод к результату человеческого перевода, тем выше качество перевода. Таким образом, алгоритм оценки заключается в том, как определить сходство между машинным переводом и эталонным переводом.
Давайте посмотрим на конкретные детали алгоритма BLEU:
N-gram
BLEU использует правило сопоставления N-грамм, принцип относительно прост, то есть сравнение отношения сходства n групп слов между переводом и эталонным переводом.
Например:
Оригинал: Сегодня хорошая погода.
Машинный перевод: Сегодня хороший день
Человеческий перевод: Сегодня яДа хорошийday
При использовании сопоставления 1 грамм:
Можно видеть, что в машинном переводе всего 6 слов, и все 5 слов попали в эталонный перевод, тогда его степень соответствия 1 грамму составляет 5/6.
Возьмем для примера 3 грамма:
Видно, что машинный перевод можно разделить на четыре 3-граммовые фразы, две из которых могут попасть в эталонный перевод, тогда его 3-граммовая степень соответствия равна 2/4.
По аналогии мы можем легко реализовать программу для обхода и вычисления степени соответствия N-граммы. Вообще говоря, результат 1 грамм показывает, сколько слов в тексте было переведено отдельно, поэтому он отражает точность перевода, а когда мы вычисляем более 2 граммов, результат чаще отражает беглость перевода. перевода, чем выше значение, тем лучше читаемость статьи.
отзывать
Упомянутый выше метод легче понять и проще реализовать, но он не учитывает скорость отзыва.Вот очень простой пример:
Оригинал: Кот стоит на земле
Машинный перевод: the the the the
Человеческий перевод: Кот стоит на земле
При вычислении 1-грамма в переводе появляются все, поэтому степень соответствия равна 4/4, но очевидно, что максимальное количество вхождений в искусственном переводе всего 2 раза, поэтому алгоритм BLEU корректирует алгоритм этого значения в первую очередь вычисляется максимальное количество возможных вхождений n-граммы в переводе:
Count — это количество вхождений N-грамм в машинном переводе, Max_Ref_Count — максимальное количество вхождений N-грамм в эталонном переводе, а окончательный статистический результат принимает меньшее из двух значений. Затем разделите результат сопоставления на количество N-грамм машинного перевода. Таким образом, для приведенного выше примера пересмотренная статистика 1 грамма равна 2/4.
Обозначим все машинно-переведенное предложение, подлежащее обработке, как Ci, а стандартный ответ как Si=si1,...sim (m означает, что имеется m эталонных ответов)
n-грамм представляет собой набор фраз длиной n слов, пусть Wk — это k-я n-грамма.
Например, такое предложение «Я родом из Китая»,Первые 2 грамма: я пришел; вторые 2 грамма: пришли из; третьи 2 грамма: из китая;
Hk(Ci) представляет количество вхождений в выбранном переводе Ci перевода Wk.
Hk(Sij) представляет количество раз, когда Wk появляется в стандартном ответе Sij.
Таким образом, точность каждого порядка N-граммов можно рассчитать по следующей формуле:
maxi∈mhk(sij) представляет максимальное количество раз, когда определенная n-грамма появляется в нескольких стандартных ответах.
∑i∑kmin(hk(ci),maxj∈mhk(sij)) представляет минимальное количество вхождений n-грамм в переведенном тексте и стандартный ответ
штрафной коэффициент
Приведенного выше алгоритма достаточно для эффективной оценки перевода, но степень соответствия N-граммы может улучшаться по мере того, как длина предложения становится короче, поэтому возникает такая проблема: механизм перевода переводит только часть предложения в предложении И перевод является более точным, то его степень соответствия все равно будет очень высокой. Чтобы избежать такой систематической ошибки при подсчете очков, BLEU вводит штрафной коэффициент за длину (штраф за краткость) в окончательном результате подсчета очков.
Формула расчета АД приведена выше. лк означает Указывает длину машинного перевода, а ls представляет эффективную длину эталонного ответа.При наличии нескольких эталонных переводов выберите длину, ближайшую к переводу перевода. Когда длина переведенного текста больше длины эталонного перевода, штрафной коэффициент равен 1, что означает отсутствие штрафа, и штрафной коэффициент рассчитывается только в том случае, если длина машинного перевода меньше эталонного ответа.
СИНИЙ
Поскольку точность каждой статистики N-грамм уменьшается экспоненциально с увеличением порядка, чтобы сбалансировать эффект статистики каждого порядка, среднее геометрическое используется для усреднения, а затем взвешивания, а затем умножается на коэффициент штрафа за длину. чтобы получить окончательную формулу оценки:
Система-прототип BLEU использует равномерное взвешивание, то есть Wn=1/N. Верхний предел N равен 4, то есть учитывается только точность в 4 грамма.
Пример
Перевод (кандидат)
Going to play basketball this afternoon ?
Справочный ответ (Ссылка)
Going to play basketball in the afternoon ?
Длина перевода, грамм: 7 Длина эталонного ответа, грамм: 8
Посмотрите сначала на 1-грамм.Кроме слова this, которое не попало, все остальные попали.Поэтому:
Р1 = 6/7 = 0,85714...
Другие граммы аналогичны:
Р2 = 4/6 = 0,6666..
Р3 = 2/5 = 0,4
Р4 = 1/4 = 0,25
Затем рассчитайте logPn, вот тот, который поставляется с python:
Сумма ∑logPn равна -2,8622, умноженная на Wn, то есть разделенная на 4, получается 0,7156.
BP = e^(1-8/7) примерно равно 0,867
BLEU = 0,867 * e^((P1 + P2 + P3 + P4)/4) = 0,867*0,4889 = 0,4238
Изначально планировал реализовать код на питоне сам, но оказалось, что это уже сделал иностранный брат, снял его и немного изменил содержание, вот вам для ознакомления
#-*- coding:utf-8 -*-
import sys
import codecs
import os
import math
import operator
import json
# 如果是一份答案的话,务必在答案的后面加上.txt python Bleu.py Candidate ref.txt
# 如果是多份答案的话,把多份答案放到一个文件夹中 python Bleu.py Candidate 文件夹
def fetch_data(cand, ref):
""" Store each reference and candidate sentences as a list """
references = []
if '.txt' in ref:
reference_file = codecs.open(ref, 'r', 'utf-8')
references.append(reference_file.readlines())
else:
for root, dirs, files in os.walk(ref):
for f in files:
reference_file = codecs.open(os.path.join(root, f), 'r', 'utf-8')
references.append(reference_file.readlines())
candidate_file = codecs.open(cand, 'r', 'utf-8')
candidate = candidate_file.readlines()
return candidate, references
def count_ngram(candidate, references, n):
clipped_count = 0
count = 0
r = 0
c = 0
for si in range(len(candidate)):
# Calculate precision for each sentence
#print si
ref_counts = []
ref_lengths = []
#print references
# Build dictionary of ngram counts
for reference in references:
#print 'reference' + reference
ref_sentence = reference[si]
ngram_d = {}
words = ref_sentence.strip().split()
ref_lengths.append(len(words))
limits = len(words) - n + 1
# loop through the sentance consider the ngram length
for i in range(limits):
ngram = ' '.join(words[i:i+n]).lower()
if ngram in ngram_d.keys():
ngram_d[ngram] += 1
else:
ngram_d[ngram] = 1
ref_counts.append(ngram_d)
# candidate
cand_sentence = candidate[si]
cand_dict = {}
words = cand_sentence.strip().split()
limits = len(words) - n + 1
for i in range(0, limits):
ngram = ' '.join(words[i:i + n]).lower()
if ngram in cand_dict:
cand_dict[ngram] += 1
else:
cand_dict[ngram] = 1
clipped_count += clip_count(cand_dict, ref_counts)
count += limits
r += best_length_match(ref_lengths, len(words))
c += len(words)
if clipped_count == 0:
pr = 0
else:
pr = float(clipped_count) / count
bp = brevity_penalty(c, r)
return pr, bp
def clip_count(cand_d, ref_ds):
"""Count the clip count for each ngram considering all references"""
count = 0
for m in cand_d.keys():
m_w = cand_d[m]
m_max = 0
for ref in ref_ds:
if m in ref:
m_max = max(m_max, ref[m])
m_w = min(m_w, m_max)
count += m_w
return count
def best_length_match(ref_l, cand_l):
"""Find the closest length of reference to that of candidate"""
least_diff = abs(cand_l-ref_l[0])
best = ref_l[0]
for ref in ref_l:
if abs(cand_l-ref) < least_diff:
least_diff = abs(cand_l-ref)
best = ref
return best
def brevity_penalty(c, r):
if c > r:
bp = 1
else:
bp = math.exp(1-(float(r)/c))
return bp
def geometric_mean(precisions):
return (reduce(operator.mul, precisions)) ** (1.0 / len(precisions))
def BLEU(candidate, references):
precisions = []
for i in range(4):
pr, bp = count_ngram(candidate, references, i+1)
precisions.append(pr)
print 'P'+str(i), ' = ',round(pr, 2)
print 'BP = ',round(bp, 2)
bleu = geometric_mean(precisions) * bp
return bleu
if __name__ == "__main__":
candidate, references = fetch_data(sys.argv[1], sys.argv[2])
bleu = BLEU(candidate, references)
print 'BLEU = ',round(bleu, 4)
out = open('bleu_out.txt', 'w')
out.write(str(bleu))
out.close()