Оценка машинного перевода — подробное объяснение алгоритма BLEU

искусственный интеллект Python алгоритм Microsoft

Заявление об авторских правах: эта статья взята из блога 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()