2009-05-19 13 views
5

Potrzebuję kodu rozwiązania dla określonego wymagania, i chciałem wiedzieć, czy ktoś jest obeznany z gotową biblioteką, która może go osiągnąć, lub może skierować mnie na najlepsza praktyka. Opis:Algorytm porównywania słów (nie w porządku alfabetycznym)

Użytkownik wprowadza słowo, które ma być jedną z kilku ustalonych opcji (trzymam opcje na liście). Wiem, że dane wejściowe muszą należeć do elementu na liście, ale ponieważ jest to dane wprowadzane przez użytkownika, on/ona mógł popełnić błąd. Szukam algorytmu, który powie mi, jakie jest najbardziej prawdopodobne słowo, które użytkownik chciał powiedzieć. Nie mam żadnego kontekstu i nie mogę zmusić użytkownika do wyboru z listy (tj. Musi on być w stanie wprowadzić słowo swobodnie i ręcznie).

Załóżmy, że lista zawiera słowa „woda”, „Kwartał”, „piwo”, „buraki”, „piekło”, „Hello” i „Mrówkojad”.

Roztwór należy uwzględnić różne typy „normalnych” błędów:

  • prędkości typos (np podwojenie znaków spada znaki itp)
  • klawiatury typos sąsiedniokanałową znaków (na przykład „qater” do „woda „)
  • Non-native angielski literówki (np "quater" za«kwartał»)
  • i tak dalej ...

Oczywistym rozwiązaniem jest porównanie listu po literze i podanie "ciężaru karnego" dla każdej innej litery, dodatkowej litery i brakującej litery. Ale to rozwiązanie ignoruje tysiące "standardowych" błędów, które na pewno są gdzieś wymienione. Jestem pewien, że istnieją heurystyki, które zajmują się wszystkimi przypadkami, zarówno specyficznymi, jak i ogólnymi, prawdopodobnie przy użyciu dużej bazy standardowych niedopasowań (jestem otwarty na rozwiązania obciążające dane).

Koduję w języku Python, ale uważam, że to pytanie nie jest agnostyczne.

Wszelkie zalecenia/przemyślenia?

Odpowiedz

10

chcesz przeczytać, jak robi to google: http://norvig.com/spell-correct.html

Edycja: Niektórzy ludzie wymienionych algorytmów, które definiują metryki pomiędzy użytkownikiem danego słowa i słowa kandydata (Levenshteina, soundex). Nie jest to jednak kompletne rozwiązanie tego problemu, ponieważ potrzebna byłaby również baza danych do wydajnego przeprowadzania wyszukiwania nie sąsiadującego z euklidesami. Można to zrobić np. z drzewkiem okładki: http://hunch.net/~jl/projects/cover_tree/cover_tree.html

2

Czy brałeś pod uwagę algorytmy, które porównują dźwięki fonetyczne, takie jak soundex? Nie powinno być zbyt trudno tworzyć reprezentacje soundex listy słów, przechowywać je, a następnie uzyskać soundex danych wejściowych użytkownika i znaleźć najbliższy pasować tam.

6

Typowym rozwiązaniem jest obliczenie Levenshtein distance między danymi wejściowymi a tekstami ustalonymi. Odległość Levenshteina dwóch ciągów to liczba prostych operacji - wstawień, usunięć i podstawień pojedynczego znaku - wymaganych do przekształcenia jednego ciągu w drugi.

0

Chociaż może nie rozwiązać całego problemu, warto rozważyć użycie algorytmu soundex jako części rozwiązania. Szybkie wyszukiwanie google z "soundex" i "python" pokazało kilka implementacji pythonowych algorytmu.

0

Spróbuj wyszukać "Odległość od levenshteina" lub "odległość edycji".Zlicza liczbę operacji edycji (usuń, wstaw, zmień literę), które musisz przekształcić jedno słowo w drugie. Jest to powszechny algorytm, ale w zależności od problemu możesz potrzebować czegoś specjalnego o różnych wagach dla różnych rodzajów literówek.

1

Poszukaj algorytmu Bitap. Dobrze kwalifikuje się do tego, co chcesz zrobić, a nawet pochodzi z przykładu kodu źródłowego w Wikipedii.

1

Jeśli Twój zestaw danych jest naprawdę mały, wystarczy porównać odległość Levenshtein na wszystkich pozycjach niezależnie. Jeśli jest większy, musisz użyć systemu indeksowania BK-Tree lub podobnego. Artykuł, do którego się przyłączyłem, opisuje sposób odnajdywania dopasowań w obrębie danego dystansu Levenshteina, ale dość łatwo jest przystosować się do wyszukiwania najbliższego sąsiada (i pozostawiony jako ćwiczenie dla czytelnika;).

Powiązane problemy