Найти - Пользователи
Полная версия: Алгоримт поиска похожих слов Норвига
Начало » Python для экспертов » Алгоримт поиска похожих слов Норвига
1 2 3
lightcaster
Несколько офтоп, но может будет полезно. Я немного доработал алгоритм для поиска ошибок в двуязычном тексте. Все там, впрочем, довольно тривиально.

http://linguis.ru/art/spell

Что же касается “правильного” поиска слов - копайте в сторону автоматов и трансдьюсеров (finite state automata, transducer). Там же на сайте есть несколько примеров. Правда, на питоне наврятли это можно сделать оптимально. По крайней мере мои попытки с реализацией обходом по дереву были не оч. успешны.
Zubchick
вы выберите что-то одно, либо бинарный поиск http://algolist.manual.ru/search/bin_search.php либо хеш-поиск http://goo.gl/Z4a4

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

Если слова добавляются часто то лучше использовать хеш поиск. Описывал выше.

http://linguis.ru/art/spell
здововский сайт, добавил в закладки :D
lightcaster
Zubchick
здововский сайт, добавил в закладки
Спасиб. Буду добавлять новые посты, по мере возможности.
magasoft
lightcaster
http://linguis.ru/art/spell
Отличный сайт, также добавил в закладки, спасибо!
Zubchick
вы выберите что-то одно, либо бинарный поиск http://algolist.manual.ru/search/bin_search.php либо хеш-поиск http://goo.gl/Z4a4
Мой вариант бинарного зависает, ума не приложу почему.
Zubchick
Если слова в словарь добавляются редко, то отсортируйте его (создайте функцию добавления в словарь, которая будет добавлять слово в нужное место, так чтобы словарь оставался отсортированным) и ищите в нем (как написать сортировку смотрите по ссылке выше), работает быстро я гарантирую это
Т.е. даже если я ищу полным перебором через for in он будет работать быстре отсортированным?
Zubchick
полный перебор не может работать быстрее чем полный перебор :D

киньте сюда свою функцию бинарного поиска)
magasoft
Zubchick
киньте сюда свою функцию бинарного поиска)
Я предполагал что это и есть она самая =):
        i = 0
j = len(slovar)
m = int((i+j)/2)
for edit in edits:
while i<j:
m=int((i+j)/2)
if slovar[m] < x:
i = m+1
elif slovar[m] > x:
j = m
else:
resault.append(edit)
Zubchick
def edits1(word):
alphabet = u'йцукенгшзхъфвапролджэячсмитьбю'
s = [(word[:i], word[i:]) for i in range(len(word) + 1)]
deletes = [a + b[1:] for a, b in s if b]
transposes = [a + b[1] + b[0] + b[2:] for a, b in s if len(b)>1]
replaces = [a + c + b[1:] for a, b in s for c in alphabet if b]
inserts = [a + c + b for a, b in s for c in alphabet]
return deletes + transposes + replaces + inserts

def known(word): # похожие (отклонение на 1 букву)
return [e1 for e1 in edits1(word) if search(e1, DICTIONARY)]


def search(word, lst):
""" Eсть ли word в списке lst? """
l = 0
r = len(lst) - 1
while 1:
m = (l + r) // 2
if word < lst[m]:
r = m -1
elif word > lst[m]:
l = m + 1
else:
return True
if l > r :
return False
try it
magasoft
Zubchick
try it
Спасибо, это гораздо лучше.

Хотя все равно вся операция слишком тормозит. Может хранить словарь в файле? С файлами он должен по идее быстрее работать чем с базами. Сейчас я храню его в кеш таблице пользуясь встроенным кешем джанго.
Zubchick
всех быстрей он будет работать если он в памяти :)
если словарь всего 1н метр, так может имеет смысл считать его в память?

Но вообще оставшиеся тормоза в любом случае связаны с edit1 и тем что нам потом надо будет поискать len(edit1(word)) раз в словаре. А с этим уже особо ничего не попишешь… разве что другой алгоритм :)
magasoft
Zubchick
всех быстрей он будет работать если он в памяти
если словарь всего 1н метр, так может имеет смысл считать его в память?
Держать ее в глобальной переменной например?

Хм… на сервере в случае хранения словаря в памяти, то бишь в глобальной переменной все работает шустро, даже очень шустро…
Разве что не все варианты перебирает.
Боюсь этот алгоритм поиска вариантов как-то иначе работает в 2.4

Причем конкретно из этих вариантов:
 
alphabet = u'Iйцукенгшзхъфвапролджэячсмитьбю'
s = [(word[:i], word[i:]) for i in range(len(word) + 1)]
deletes = [a + b[1:] for a, b in s if b]
transposes = [a + b[1] + b[0] + b[2:] for a, b in s if len(b)>1]
replaces = [a + c + b[1:] for a, b in s for c in alphabet if b]
inserts = [a + c + b for a, b in s for c in alphabet]
edits = deletes + transposes + replaces + inserts
он ищет только deletes, т.е. находит слова с удаленной буквой. Может в 2.4 списки как-то иначе соединялись?
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB