У мене є текстові документи, які містять переважно списки предметів.
Кожен елемент - це група з декількох маркерів різних типів: ім’я, прізвище, прізвище, день народження, номер телефону, місто, окупація тощо. Маркер - це група слів.
Елементи можуть лежати на кількох рядках.
Елементи з документа мають приблизно однаковий синтаксис лексеми, але вони не обов'язково повинні бути абсолютно однаковими.
Вони можуть бути деякими більше / меншими лексемами між предметами, а також усередині предметів.
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
Мета - з'ясувати той синтаксис без попереднього знання про нього .
Відтепер нова марка вважається також лексемою. Потім документ може бути представлений у вигляді 1-розмірної послідовності лексем:
Тут повторювана послідовність була б 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 зліва.
Тепер ми можемо чітко побачити 2 чіткі діагональні лінії. У цій послідовності є 3 пункти (Item1, Item2, Item3). Найдовший рядок представляє відповідність між Item1 та Item2 та Item2 проти Item3. Другий найдовший являє собою відповідність між Item1 та Item3.
Зараз я не впевнений у найкращому способі використання цих даних. Це так просто, як взяти найвищі діагональні лінії?
Припустимо, це так.
Обчислимо середнє значення діагональної лінії, що починається від кожного маркера. Результат ми можемо побачити на наступному малюнку (вектор під матрицею):
Ясно є три локальні мінімуми, які відповідають початку кожного предмета. Виглядає фантастично!
Тепер додамо ще кілька недосконалостей у послідовності:
ABCGDEFGH ABCDEFGH TROLL ABCDEFGH
Ясна річ, наш вектор діагональних середніх розмірів заплутаний, і ми більше не можемо його використовувати ...
Моє припущення полягає в тому, що це можна було б вирішити за допомогою спеціалізованої функції відстані (замість Левенштейна), де вставка цілого блоку може бути не настільки штрафована. В цьому я не впевнений.
Висновок
Жодне з досліджуваних рішень на основі згортки, здається, не відповідає нашій проблемі.
Рішення на основі Левенштейна здається перспективним, тим більше, що воно сумісне з лексемами на основі ймовірності. Але я ще не впевнений у тому, як використовувати результати цього.
Буду дуже вдячний, якщо у вас є досвід роботи в суміжній галузі та кілька хороших підказок, які ви можете дати нам, або інші методи дослідження. Наперед Вам дякую.