Игорь, кроме стемминга есть и другие хорошие инструменты. Как вам (возможно даже хорошо) известно, есть достаточно исследованные (т.е. более-менее понятно что работает, что нет, и с какими свойствами) способы представления слов, фраз и текстов в виде векторов. Такими представлениями можно решить сразу несколько проблем, вот пара вариантов:
1. Синонимия, опечатки, исковерканные слова — представление слов character level embedding вектором (должен строится с учетом окружающего контекста) и поиск вектора с метрикой расстояния менее заданной. Так зацепим синонимы вместе с исковерканными словами.
2. Группировка похожего текста — представляем весь текст каждой статьи в виде summary вектора, и плотные кластера векторов представляем вектором максимально близким к центроиде в выдаче (с возможностью посмотреть остальные, если надо). Так в выдаче близкие по смыслу тексты будут предсталвены их самым ярким представителем. Можно векторы кластера агрегировать в один вектор summary (напр.барицентр) и сгенерировать текстовое описание (автоэнкодером например) всего кластера (любопытно было бы на это помотреть в крибруме).
3. Сортировка по релевантности — представляем и запрос тоже в виде summary вектора и используем расстояние вектора запроса до векторов статей в качестве одной из метрик релевантности. Можно и по вхождению близких character level embedding векторов тоже ранжировать (метрик обычно много, и нужная комбинация подбирается экспериментально).
4. Полисемия (т.е. за одним словом много значений, как в случае с поиском по Синодову выше) — для разрешения полисемии нужно в запрос добавить контекст, например «фамилия Синодов». При использовании character level embedding и ранжировании на дистанциях векторов вверху будут тексты про Синодова.
Интересно попробовать закодировать в вектора 3 параметра: контекст, негативный контекст, целевой запрос. И использовать соответствующим образом, пример с Синодовым: контекст = «фамилия, человек, роем.ру», негативный контекст = «собор, религия», целевой запрос = «Синодов». Можно придумать и другие варианты, как добавить контекст. Например, entity recognition делать на запросе и давать возможность уточнить entity, но тогда потребуется entity recognition по всем текстам делать, может это и плюс, т.к. для каждого текста сразу будут проиндексированы сущности в нём упоминаемые.
На всякий ключи для старта в гугле (то, что сегодня ещё модно/молодежно):
ELMo (character level embedding; вариант recurrent seq2seq архитектуры; требовательный к ресурсам),
BERT (не character level embedding, но кодирует слово n-грамами (BPE), т.е. в большой степени учитывает очепятки и слова вне словаря; архитектура transformer; менее требователен к ресурсам).
Чтобы всё это заработало нужен большой корпус текстов для обучения, ряд эспериментов с разными архитектурами и гиперпараметрами этих архитектур + вычислительные ресурсы на обучение и на непрерывную индексацию. Я думаю, в вашем случае всё это вполне доступно. Это тоже техдиру покажите :).
Дискуссии пользователя
Игорь, кроме стемминга есть и другие хорошие инструменты. Как вам (возможно даже хорошо) известно, есть достаточно исследованные (т.е. более-менее понятно что работает, что нет, и с какими свойствами) способы представления слов, фраз и текстов в виде векторов. Такими представлениями можно решить сразу несколько проблем, вот пара вариантов:
1. Синонимия, опечатки, исковерканные слова — представление слов character level embedding вектором (должен строится с учетом окружающего контекста) и поиск вектора с метрикой расстояния менее заданной. Так зацепим синонимы вместе с исковерканными словами.
2. Группировка похожего текста — представляем весь текст каждой статьи в виде summary вектора, и плотные кластера векторов представляем вектором максимально близким к центроиде в выдаче (с возможностью посмотреть остальные, если надо). Так в выдаче близкие по смыслу тексты будут предсталвены их самым ярким представителем. Можно векторы кластера агрегировать в один вектор summary (напр.барицентр) и сгенерировать текстовое описание (автоэнкодером например) всего кластера (любопытно было бы на это помотреть в крибруме).
3. Сортировка по релевантности — представляем и запрос тоже в виде summary вектора и используем расстояние вектора запроса до векторов статей в качестве одной из метрик релевантности. Можно и по вхождению близких character level embedding векторов тоже ранжировать (метрик обычно много, и нужная комбинация подбирается экспериментально).
4. Полисемия (т.е. за одним словом много значений, как в случае с поиском по Синодову выше) — для разрешения полисемии нужно в запрос добавить контекст, например «фамилия Синодов». При использовании character level embedding и ранжировании на дистанциях векторов вверху будут тексты про Синодова.
Интересно попробовать закодировать в вектора 3 параметра: контекст, негативный контекст, целевой запрос. И использовать соответствующим образом, пример с Синодовым: контекст = «фамилия, человек, роем.ру», негативный контекст = «собор, религия», целевой запрос = «Синодов». Можно придумать и другие варианты, как добавить контекст. Например, entity recognition делать на запросе и давать возможность уточнить entity, но тогда потребуется entity recognition по всем текстам делать, может это и плюс, т.к. для каждого текста сразу будут проиндексированы сущности в нём упоминаемые.
На всякий ключи для старта в гугле (то, что сегодня ещё модно/молодежно):
ELMo (character level embedding; вариант recurrent seq2seq архитектуры; требовательный к ресурсам),
BERT (не character level embedding, но кодирует слово n-грамами (BPE), т.е. в большой степени учитывает очепятки и слова вне словаря; архитектура transformer; менее требователен к ресурсам).
Чтобы всё это заработало нужен большой корпус текстов для обучения, ряд эспериментов с разными архитектурами и гиперпараметрами этих архитектур + вычислительные ресурсы на обучение и на непрерывную индексацию. Я думаю, в вашем случае всё это вполне доступно. Это тоже техдиру покажите :).