Здравствуйте, Nuzhny, Вы писали:
N>Как сопоставить слову вектор — вот тут я бы взял лёгкую нейросеть для текстовых эмбеддингов.
Да, вот тут единственно, что плохо понятно в твоём предложении.
Обычно длина "ключевых слов" небольшая (8 символов в среднем), плюс алфавит небольшой — 26 английских букв + 33 русских + 10 цифр плюс некие символы +-*/"(){}, которые все можно закодировать одним символом (раз всё равно потом на найденный список натравливаем Левенштейна), ну и сопоставить английские символы русским и сами русские символы ужать (и-й, е-ё), т.е. можно сделать преобразованный алфавит меньше 32 символов, это 5 бит на символ, т.е. средняя строка влезет в байтовое представление двух int32.
Моё предложенное решение такое:
Построить граф ДКА разбора всех "ключевых" слов. Граф состояний сделать однонаправленным, без циклов, т.е. будет дерево разбора.
Точное соответствие будет найдено за O(N), где N — длина строки.
Для нечёткого соответствия можно протягивать по этому дереву НКА, т.е. множить кол-во вариантов на каждом шаге, с накоплением количества отличий (разницы).
Алгоритм Левенштейна допускает любые опечатки плюс перестановки, т.е. коэфициент размножения кол-ва НКА-состояний на каждом шаге будет 32*2 (сколько символов в алфавите), в конечных состояниях будет список всех слов, которые при преобразовании алфавита дали нам текущую строку разбора — уже сильное ограничение.
При накоплении расстояния/ошибок на каждом шаге большинство НКА будет отваливаться если сделать как принято на практике максимальное расстояние 2. Т.е, грубо, оценка кол-ва протягиваемых НКА на каждом шаге будет 32*32.
Поэтому, есть еще идея допускать не произвольные опечатки, а только самые популярные, например, C-S, X-KS, U-Y, а так же соседние символы на обычной и мобильной клавиатуре (тоже источник опечаток). Т.е. коэф. размножения состояний НКА будет на порядок меньше 10*10.
Из готовых я видел нечеткое сравнение по индексу в библиотеке Lucene (есть джавовская и дотнетная версия), но там такие тормоза, что приплызд.
Поэтому, есть идея искать символ в 3 этапа:
Первый раз прогнать по дереву разбора ДКА-автомат (это даже быстрее, чем поиск по хеш-таблице) — будет найдено или нет точное соответствие.
Затем запуск описанного алгоритма с протягиванием НКА, а затем уже запуск полного нечеткого сравнения из Lucene, если "быстрый" алгоритм не нашёл соответствия.
Если рассуждать дальше, "быстрый" алгоритм можно ограничить, например, одной опечаткой и одной перестановкой, что даст совсем небольшое кол-во одновременно протягиваемых состояний НКА (примерно десяток), т.е. почти мгновенную его работу.
Итого, для полного соответствия будет мгновенный ответ, для 1-й ошибки — почти мгновенный, для более одной ошибки — медленнее всего.