Распознать грамматику в последовательности нечетких токенов

13

У меня есть текстовые документы, которые содержат в основном списки предметов.

Каждый элемент представляет собой группу из нескольких токенов разных типов: FirstName, LastName, BirthDate, PhoneNumber, City, Occupation и т. Д. Маркер представляет собой группу слов.

Предметы могут лежать на нескольких строках.

Элементы из документа имеют примерно одинаковый синтаксис токена, но они не обязательно должны быть одинаковыми.

Они могут быть больше / меньше токенов между Предметами, а также внутри Предметов.

FirstName LastName BirthDate PhoneNumber
Occupation City
FirstName LastName BirthDate PhoneNumber PhoneNumber
Occupation City
FirstName LastName BirthDate PhoneNumber
Occupation UnrecognizedToken
FirstName LastName PhoneNumber
Occupation City
FirstName LastName BirthDate PhoneNumber
City Occupation

Цель состоит в том, чтобы определить используемую грамматику, например,

Occupation City

и в конце идентифицируйте все Предметы, даже если они не совсем совпадают.

Чтобы оставаться короткими и удобочитаемыми, давайте использовать некоторые псевдонимы A, B, C, D, ... для обозначения этих типов токенов.

например

A B C
D F
A B C
D E F
F
A B C
D E E F
A C B
D E F
A B D C
D E F
A B C
D E F G

Здесь мы видим, что синтаксис элемента

A B C
D E F

потому что это тот, который лучше всего соответствует последовательности.

Синтаксис (типы токенов и заказы) может сильно варьироваться от одного документа к другому. например, другой документ может иметь этот список

D A
D A
D
D A
B
D A

Цель состоит в том, чтобы выяснить этот синтаксис без предварительного знания его .

Отныне новая строка также считается токеном. Затем документ может быть представлен в виде одномерной последовательности токенов:


Здесь повторяющаяся последовательность будет A B C Bпотому, что именно маркер создает наименьшее количество конфликтов.

Давайте немного усложним это. С этого момента каждый токен не имеет определенного типа. В реальном мире мы не всегда на 100% уверены в типе некоторых токенов. Вместо этого мы даем ему вероятность наличия определенного типа.

  A 0.2    A 0.0    A 0.1
  B 0.5    B 0.5    B 0.9     etc.
  C 0.0    C 0.0    C 0.0
  D 0.3    D 0.5    D 0.0

Вот абстрактный график того, чего я хочу достичь:

Рассмотренное решение A: Свертка патча токенов

Это решение состоит в применении свертки с несколькими патчами токенов, и выбирает тот, который создает наименьшее количество конфликтов.

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

Построить марковскую модель перехода между токенами

Недостаток: поскольку у марковской модели нет памяти, мы потеряем порядки перехода. Например, если повторяется последовательность A B C B D, мы теряем тот факт, что A-> B происходит до C-> B.

Построить дерево суффиксов

Это, кажется, широко используется в биологии для анализа нуклеиновых оснований (GTAC) в ДНК / РНК. Недостаток: Суффикс-деревья хороши для точного соответствия точных токенов (например, символов). У нас нет ни точных последовательностей, ни точных токенов.

Грубая сила

Попробуйте каждую комбинацию любого размера. Может действительно работать, но займет некоторое (долгое (долгое)) время.

Рассмотренное решение B: Построить таблицу левенштейновых расстояний суффиксов.

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

Функция расстояния - это расстояние Левенштейна, но мы сможем настроить его в будущем, чтобы учесть вероятность того, что он будет определенного типа, вместо того, чтобы иметь фиксированный тип для каждого токена.

Чтобы не усложнять эту демонстрацию, мы будем использовать токены фиксированного типа и классического Левенштейна для вычисления расстояния между токенами.

Например, давайте введем последовательность ввода ABCGDEFGH ABCDEFGH ABCDNEFGH.

Мы вычисляем расстояние каждого суффикса с каждым суффиксом (обрезается до одинакового размера):

for i = 0 to sequence.lengh
  for j = i to sequence.lengh
    # Create the suffixes
    suffixA = sequence.substr(i)
    suffixB = sequence.substr(j)
    # Make the suffixes the same size
    chunkLen = Math.min(suffixA.length, suffixB.length)
    suffixA = suffixA.substr(0, chunkLen)
    suffixB = suffixB.substr(0, chunkLen)
    # Compute the distance
    distance[i][j] = LevenshteinDistance(suffixA, suffixB)

Мы получаем, например, следующий результат (белый - небольшое расстояние, черный - большой):

Теперь очевидно, что любой суффикс по сравнению с самим собой будет иметь нулевое расстояние. Но нас не интересует суффикс (точное или частичное) сопоставления самого себя, поэтому мы обрезаем эту часть.

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

Нам нужно компенсировать это плавным штрафом, начиная справа (+ P) и линейно затухая влево.

Я пока не уверен, как выбрать хорошую функцию штрафа, которая бы подходила для всех случаев.

Здесь мы применяем (+ P = 6) штраф в крайнем правом углу, постепенно уменьшаясь до 0 слева.

Теперь мы можем ясно видеть, как появляются две четкие диагональные линии. В этой последовательности есть 3 предмета (Item1, Item2, Item3). Самая длинная строка представляет соответствие между Item1 против Item2 и Item2 против Item3. Второй самый длинный представляет соответствие между Item1 и Item3.

Теперь я не уверен, как лучше использовать эти данные. Это так же просто, как взять самые высокие диагональные линии?

Давайте предположим, что это так.

Давайте вычислим среднее значение диагональной линии, которая начинается с каждого токена. Мы можем увидеть результат на следующем рисунке (вектор ниже матрицы):

Ясно, что есть 3 локальных минимума, которые соответствуют началу каждого пункта. Выглядит фантастически!

Теперь давайте добавим еще несколько недостатков в последовательность: ABCGDEFGH ABCDEFGH TROLL ABCDEFGH

Очевидно, что наш вектор диагональных средних испорчен, и мы больше не можем его использовать ...

Мое предположение состоит в том, что это может быть решено с помощью специальной функции расстояния (вместо Левенштейна), где вставка целого блока может не так сильно наказываться. В этом я не уверен.

Вывод

Похоже, что ни одно из исследованных решений на основе свертки не соответствует нашей проблеме.

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

Я был бы очень признателен, если у вас есть опыт работы в смежной области, и пара полезных советов, которые мы можем вам дать, или другие методы для изучения. Заранее большое спасибо.

OoDeLally
источник
Вы рассматривали возможность использования авторегрессионной модели? en.wikipedia.org/wiki/Autoregressive_model
jcrudy
Я не очень понимаю, что вы хотите и почему. Но, возможно, алгоритмы сжатия могут помочь как-то.
Геренюк
1
Я добавил эксперимент, который я сделал сегодня, основываясь на расстоянии Левенштейна. Это выглядит многообещающе. Кроме того, я немного отредактировал введение, так что, надеюсь, оно станет более понятным. Спасибо за ваши предложения, я посмотрю.
OoDeLally
@Gerenuk Такой замечательный комментарий!
uhbif19

Ответы:

1

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

Например, оба были использованы в прошлом для моделирования генетических последовательностей, например, это и это .

ncasas
источник