Поиск однокоренных слов в списке Python
Есть большой словарь. Где ключ - это ссылка на рецепт. А значение - это список ингредиентов. Пример:
dict {'https://random.com':['банан', 'яйца', 'мука', 'картофель']}
А есть запросы пользователя(в боте телеграм), которые я преобразую в список и сравниваю со списками в словаре и отдаю ссылку на рецепт, если есть попадание по запросу.
Так вот, многие рецепты не идут к пользователю, если нет точного попадания слов. Например, когда пользователь ввел:
['картошка', 'яйцо']
И он не получает рецепт, хотя он подходит. Подскажите, как можно организовать проверку в этом случае? Как искать только по части слова 'карто', 'яйц'? Подскажите пожалуйста хотя бы направление поиска, если не само решение. Спасибо
Ответы (2 шт):
Здесь стоит использовать алгоритм нечёткого сравнения строк. Вот пример:
from fuzzywuzzy import process
l = ['банан', 'яйца', 'мука', 'картофель']
print(process.extractOne("картошка", l)) # ('картофель', 59)
Второй элемент в кортеже — число от 0 до 100, которое показывает степень похожести слов. Например, можно считать, что ингредиенты одинаковые, если их похожесть >= 50.
Для повышения качества сравнения можно привести все слова в форму без окончаний:
from fuzzywuzzy import process
from nltk.stem.snowball import RussianStemmer
l = ['банан', 'яйца', 'мука', 'картофель']
stemmer = RussianStemmer()
stem_l = [stemmer.stem(x) for x in l] # ['бана', 'яйц', 'мук', 'картофел']
ingredient = stemmer.stem("картошка") # 'картошк'
print(process.extractOne(ingredient, stem_l)) # ('картофел', 67)
Не забудьте установить необходимые библиотеки:
pip install fuzzywuzzy
pip install nltk
Конечно, при таком подходе можно перепутать похожие ингредиенты. Например, посчитать что "горох" и "горошек" это одно и то же.
Неплохой вариант - использовать pymorphy2 с русским словарем (pymorphy2-dict-ru) или его форк pymorphy3, который, похоже, отличается только обновленными словарями. Как сказано в комментариях к вопросу, он может привести слово к начальной форме. Что и требуется: приводим все ингредиенты и сравниваем. Такой подход отлично работает в другом телеграмном боте (полнотекстовый морфологический поиск).