Який алгоритм дає пропозиції в інструменті перевірки орфографії?


114

Який алгоритм зазвичай використовується при реалізації перевірки орфографії, яка супроводжується пропозиціями щодо слів?

Спочатку я подумав, що може мати сенс перевіряти кожне нове слово, набране (якщо його не знайти у словнику), на відстань Левенштейна від кожного іншого слова у словнику та повернення найкращих результатів. Однак, здається, це було б дуже неефективно, доводиться багато разів оцінювати весь словник.

Як це зазвичай робиться?

Відповіді:


203

Є хороший нарис Пітера Норвіга, як реалізувати коректор правопису. Це, головним чином, підхід грубої сили, пробуючи кандидатські рядки з заданою дистанцією редагування. ( Ось кілька порад, як можна покращити ефективність коректора орфографії за допомогою фільтра Bloom і швидшого хешування кандидата .)

Вимоги до перевірки орфографії слабкіші. Ви повинні лише з’ясувати, що слова немає у словнику. Ви можете використовувати фільтр Bloom для створення перевірки орфографії, яка споживає менше пам’яті. Старовинні версії описані в програмуванні перлів Джона Бентлі, використовуючи 64 кб для словника англійської мови.

BK-дерево являє собою альтернативний підхід. Приємна стаття тут .

Відстань Левеншштайна - не зовсім правильна відстань для редагування орфографії. Він знає лише вставку, видалення та заміну. Транспонування відсутня і створюється 2 для переміщення 1 символу (це 1 видалення та 1 вставка). Відстань Дамерау - Левенштейн - це правильна відстань для редагування.


2
+1 для відносно невідомої посилання BK-Tree. Ось так роблять такі компанії, як Google, які працюють із кількістю даних Real-World [TM].
NoozNooz42

2
Існує набагато краще пояснення БК-дерев тут .
Ян Бойд

17

Підхід для створення пропозицій, який я успішно використовував, але ніколи не бачив описаного ніде, - це попередньо обчислити пропозиції (під час створення словника) за допомогою "поганих" хеш-функцій.

Ідея полягає в тому, щоб переглянути типи орфографічних помилок, які люди роблять, і створити хеш-функції, які призначали б неправильне написання того ж відра, що і його правильне написання.

Наприклад, поширеною помилкою є використання неправильного голосного, як-от визначення, а не визначеного . Таким чином, ви проектуєте хеш-функцію, яка розглядає всі голосні як одну і ту ж букву. Простий спосіб зробити це спочатку "нормалізувати" вхідне слово, а потім поставити нормалізований результат за допомогою звичайної хеш-функції. У цьому прикладі нормалізуюча функція може скинути всі голосні, так і definiteстає dfnt. Потім "нормалізоване" слово хеширується з типовою хеш-функцією.

Вставте всі свої словникові слова в допоміжний індекс (хеш-таблицю) за допомогою цієї спеціальної хеш-функції. Відра в цій таблиці матимуть тривалі списки зіткнень, оскільки хеш-функція "погана", але ці списки зіткнення по суті є попередньо розрахованими пропозиціями.

Тепер, коли ви знайдете неправильно написане слово, ви шукаєте списки зіткнення для відра, на яке вводиться неправильне написання, в допоміжні індекси. Ta da: У вас є список пропозицій! Все, що вам потрібно зробити - це класифікувати слова на ньому.

На практиці вам знадобиться кілька допоміжних індексів з іншими хеш-функціями для обробки інших типів помилок, наприклад, перекладених літер, одинарних / подвійних літер і навіть спрощеного Soundex-подібного для лову фонетичних помилок. На практиці я виявив спрощену вимову, щоб пройти довгий шлях, і по суті застарів деякі з тих, які призначені для пошуку тривіальних помилок.

Отже, тепер ви шукаєте неправильні написання у кожному з допоміжних індексів і з'єднуєте списки зіткнень перед ранжуванням.

Пам'ятайте, що списки зіткнення містять лише слова, які є у словнику. За допомогою підходів, які намагаються створити альтернативні написання (як у статті про Пітера Норвіга), ви можете отримати (десятки) тисяч кандидатів, яких спочатку вам доведеться відфільтрувати до словника. При попередньо обчисленому підході ви отримаєте, можливо, кілька сотень кандидатів, і ви знаєте, що всі вони написані правильно, тому ви можете пропустити прямо до рейтингу.

Оновлення : з тих пір я знайшов опис алгоритму, подібний до цього, FAROO Розподілений пошук . Це все ще обмежений пошук за редагуванням, але це дуже швидко, тому що крок перед розрахунком працює як моя ідея "погані хеш-функції". FAROO просто використовує обмежену концепцію поганої хеш-функції.


Дякуємо за посилання на алгоритм SymSpell Faroos. Хоча обидва алгоритми попередньо розраховують можливі помилки та використовують хеш-таблицю для швидкого пошуку, головна відмінність полягає в тому, що SymSpell гарантує виявлення всіх можливих помилок написання до певної відстані редагування (в цьому відношенні SymSpell еквівалентний алгоритму Пітера Норвіга, просто 3..6 порядків швидше), тоді як ваш алгоритм використовує евристичний підхід, який виявить лише обмежений підмножина всіх теоретично можливих помилок написання (тому вартість попереднього розрахунку може бути нижчою).
Вовк Гарбе

Алгоритм SymSpell явно попередньо розраховує та зберігає можливі помилки, моя схема "поганого хешу" - ні. Для англійської мови тривіально додати лише один спрощений фонетичний хеш, який охоплює багато ґрунту (наприклад, "terradacktle" -> "pterodactyl", який має відстань редагування 6). Зрозуміло, якщо вам потрібні багатомовні пошуки, це може бути набагато складніше.
Адріан Маккарті

Абсолютно, використовуючи емпіричні знання про ймовірні помилки (і обмежуючи їх), ви економите час та простір перед розрахунком. Але для покриття всіх можливих помилок написання SymSpell потрібно попередньо обчислити лише невелику частину з них. Слово з 5 літер має близько 3 мільйонів можливих помилок написання в межах максимальної відстані редагування 3, але за допомогою SymSpell потрібно попередньо обчислити та зберегти лише 25 видалень. Це важливо для пошуку нечіткості / подібності, крім корекції орфографії, де немає емпіричних знань.
Вовк Гарбе

7

Алгоритм

  1. Візьміть неправильно написане слово як вхідне.
  2. Зберігайте список англійських слів разом з їх частотою у текстовому файлі.
  3. Вставте всі доступні англійські слова (які зберігаються у текстовому файлі) разом з їх частотами (вимірюйте, як часто слово використовується англійською мовою) у Термінальне дерево пошуку.
  4. Тепер проходьте по Тернальному пошуковому дереву -
    • Для кожного слова, що зустрічається на Термінальному дереві пошуку, обчисліть його відстань Левенштейна від неправильно написаного слова.
    • Якщо відстань Левенштейна <= 3, збережіть це слово в черзі пріоритетів.
    • Якщо два слова мають однакову відстань редагування, те, що має більш високу частоту, є теркою. Роздрукуйте 10 найпопулярніших елементів із черги за пріоритетом.

Оптимізація

  1. Ви можете виділити слова в піддерево поточного вузла, якщо відстань редагування підрядка вхідного слова від поточного слова буде більшою, ніж 3.
    Більш детальне пояснення та вихідний код ви можете знайти в проекті github .

Гм, відстань Левенштейна від "терки" до "більшої" в цьому випадку буде недостатньо, оскільки "терка" - це також словникове слово. ;-)
Тоні Брасунас

1
@TonyBrasunas, так, ти маєш рацію. Але програма насправді поверне список із 10 слів у разі введення "терки" в якості введення, і вона запропонує "терка" з відстанью редагування 0, а також "більша" з відстані редагування 1. Що може бути корисною. ;)
amarjeetAnand

Якщо один кандидат має відстань у 2, але це надзвичайно часто, а інший кандидат має відстань у 1, але вкрай рідко, як ви класифікуєте їх двох? У вищенаведеному підході рідкісний предмет завжди вигравав би, це правильний результат?
швидкісний літак

@speedplane Так. виграє рідкісний. І я думаю, що це правильний результат. Оскільки ми очікуємо найближче слово, засноване на написанні вхідного слова. Якщо ви все ще сумніваєтесь, подумайте так --- припустимо, є рідкісне слово, яке користувач написав правильно. Зараз його відстань 0, але частота дуже низька. Тепер у пропозиціях ми повинні перелічити це рідкісне слово (з відстані 0) вгорі (тому що найменше виграє відстань) та інші слова з відстані 1-2-3 внизу.
amarjeetAnand

3

Не потрібно знати точну відстань редагування кожного слова в словнику. Ви можете зупинити алгоритм після досягнення граничного значення та виключити слово. Це дозволить заощадити багато часу на обчислення.


1

Перевірку орфографії дуже просто здійснити, як в програмі орфографії Unix. Вихідний код доступний для всіх. Виправлення може бути задіяне, одна техніка - це редагування та ще раз перевірка, чи є це нове слово у словнику. Такі нові редагування можна групувати та показувати користувачеві.

У системі Unix використовується програма, написана Mc IllRoy. Альтернативний спосіб - використовувати Trie, який може бути корисним у випадку величезних файлів.

Для підходу unix потрібно дуже менше місця для величезного словника, оскільки він використовує алгоритм розсіювання хешу.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.