Высокоточный алгоритм выравнивания слов в Python - PullRequest
5 голосов
/ 06 января 2020

Я работаю над проектом по построению высокоточного выравнивания слов между предложениями и их переводами на других языках, для измерения качества перевода. Мне известны Giza ++ и другие инструменты выравнивания слов, которые используются как часть конвейера для Статистического машинного перевода, но это не то, что я ищу. Я ищу алгоритм, который может отображать слова из исходного предложения в соответствующие слова в целевом предложении, прозрачно и точно, учитывая следующие ограничения:

  • два языка не имеют одинаковый порядок слов и порядок постоянно меняется
  • некоторые слова в исходном предложении не имеют соответствующих слов в целевом предложении, и наоборот
  • иногда слова в источнике соответствуют нескольким словам в целевом предложении и наоборот, и может быть отображение «многие ко многим»
  • могут быть предложения, в которых одно и то же слово используется в предложении несколько раз, поэтому необходимо выполнить выравнивание со словами и их индексами , а не только слова

Вот что я сделал:

  • Начнем со списка пар предложений, скажем Engli sh -German, с каждым предложением, разбитым на слова
  • Индексируйте все слова в каждом предложении и создайте инвертированный индекс для каждого слова (например, слово «мир» встречается в сенте). nces # 5, 16, 19, 26 ... et c), для исходного и целевого слов
  • Теперь этот инвертированный индекс может предсказать корреляцию между любым исходным словом и любым целевым словом в качестве пересечения между двумя словами, разделенными их союзом. Например, если слово tagret «Welt» встречается в предложениях 5, 16, 26,32, корреляция между (world, Welt) - это число индексов в пересечении (3), деленное на количество индексов в объединении ( 5) и, следовательно, корреляция составляет 0,6. Использование объединения дает более низкую корреляцию с высокочастотными словами, такими как «the», и соответствующими словами на других языках
  • Повторяйте итерацию по всем парам предложений и используйте индексы для исходных и целевых слов для данного пары предложений для создания корреляционной матрицы

Вот пример корреляционной матрицы между английским sh и немецким предложением. Мы можем видеть проблемы, обсужденные выше.

An example of the alignment between an English and German sentence, showing the correlations between words, and the green cells are the correct alignment points that should be identified by the word-alignment algorithm

На рисунке показан пример выравнивания между английским sh и немецким предложением, показывающий корреляцию между словами и зеленые ячейки - это правильные точки выравнивания, которые должны быть определены алгоритмом выравнивания слов.

Вот кое-что из того, что я пробовал:

  • В некоторых случаях возможно, что предполагаемый Выравнивание - это просто пара слов с самой высокой корреляцией в соответствующем столбце и строке, но во многих случаях это не так.
  • Я пробовал такие вещи, как алгоритм Дейкстры, чтобы нарисовать путь, соединяющий точки выравнивания, но, похоже, он не работает таким образом, потому что кажется, что вы можете переходить назад и вперед к более ранним словам в предложении из-за порядок слов, и нет разумного способа пропустить слова, для которых нет выравнивания.
  • Я думаю, что оптимальное решение будет включать в себя что-то вроде расширения прямоугольников, которые начинаются с наиболее вероятных соответствий и охватывают множество-много соответствий, и пропускают слова без выравнивания, но я не совсем уверен, что будет хороший способ реализовать это

Вот код, который я использую:

import random
src_words=["I","know","this"]
trg_words=["Ich","kenne","das"]
def match_indexes(word1,word2):
    return random.random() #adjust this to get the actual correlation value

all_pairs_vals=[] #list for all the source (src) and taget (trg) indexes and the corresponding correlation values
for i in range(len(src_words)): #iterate over src  indexes
    src_word=src_words[i] #identify the correponding src word
    for j in range(len(trg_words)): #iterate over trg indexes
        trg_word=trg_words[j] #identify the correponding trg word
        val=match_indexes(src_word,trg_word) #get the matching value from the inverted indexes of     each word (or from the data provided in the speadsheet)
        all_pairs_vals.append((i,j,val)) #add the sentence indexes for scr and trg, and the corresponding val

all_pairs_vals.sort(key=lambda x:-x[-1])  #sort the list in descending order, to get the pairs with the highest correlation first
selected_alignments=[]
used_i,used_j=[],[] #exclude the used rows and column indexes
for i0,j0,val0 in all_pairs_vals:
    if i0 in used_i: continue #if the current column index i0 has been used before, exclude current pair-value
    if j0 in used_j: continue #same if the current row was used before
    selected_alignments.append((i0,j0)) #otherwise, add the current pair to the final alignment point selection
    used_i.append(i0) #and include it in the used row and column indexes so that it will not be used again
    used_j.append(j0)

for a in all_pairs_vals: #list all pairs and indicate which ones were selected
    i0,j0,val0=a
    if (i0,j0) in selected_alignments: print(a, "<<<<")
    else: print(a)

Это проблематично c, потому что он не вмещает многие ко многим или даже выравнивания один ко многим, и в начале можно легко ошибиться, выбрав неправильную пару с наивысшей корреляцией, исключив ее строку и столбец из будущего выбора. Хороший алгоритм учитывает, что определенная пара имеет наивысшую корреляцию в соответствующей строке / столбце, но также учитывает близость к другим парам с высокими корреляциями.

Вот некоторые данные, которые вы можете попробовать, если хотите, они есть в листах Google: https://docs.google.com/spreadsheets/d/1-eO47RH6SLwtYxnYygow1mvbqwMWVqSoAhW64aZrubo/edit?usp=sharing

Ответы [ 2 ]

3 голосов
/ 06 января 2020

Согласование слов остается в некоторой степени открытым исследованием c. Вероятностные c модели, стоящие за Giza ++, довольно нетривиальны, см. http://www.ee.columbia.edu/~sfchang/course/svia/papers/brown-machine-translate-93.pdf

Существует множество существующих подходов, таких как:

* 1007. * реализовать "модели IBM", используемые Giza ++ самостоятельно (или, если вы смелы, попробуйте реализацию NLTK) реализовать (намного более простой) алгоритм, стоящий за fast_align https://www.aclweb.org/anthology/N13-1073/ реализовать некоторую форму выравнивания на основе HMM https://www.aclweb.org/anthology/C96-2141/ использовать глубокое обучение, там есть несколько возможностей; эта статья, кажется, содержит хороший обзор подходов https://www.aclweb.org/anthology/P19-1124.pdf (обычно люди пытаются использовать механизм внимания нейронных моделей МТ для этого)

Это очень сложно проблема машинного обучения, и хотя не исключено, что простые подходы, такие как ваш, могут работать, было бы неплохо сначала изучить существующую работу. При этом, мы увидели немало прорывов из удивительно простых методов в этой области, так что кто знает: -)

2 голосов
/ 10 января 2020

В последнее время были также две статьи, использующие двух / многоязычные вложения слов / контекстов для выравнивания слов. Оба они строят двудольный граф, в котором слова взвешиваются с учетом их расстояний внедрения, и используют алгоритмы графа для получения выравнивания.

Одна бумага выполняет максимальное совпадение между частями графа. Поскольку сопоставление не является симметричным, они делают это с обеих сторон и используют эвристику симметризации, аналогичную FastAlign.

В другом упоминается выравнивание, только кратко использующее минимально взвешенное покрытие края на графике. и использует его как выравнивание.

Оба они утверждают, что они лучше, чем FastAlign.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...