Гость
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / нечеткий поиск / 7 сообщений из 7, страница 1 из 1
21.01.2020, 13:44
    #39916797
Troglodit
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
нечеткий поиск
пытаюсь реализовать нечеткий поиск.
Нашел статью
Пробовал триграммы, но результат неутешительный.
Пробовал использовать кастомный metaphone:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
CREATE OR REPLACE FUNCTION test.phoneme(
	in_lexeme text)
    RETURNS text
    LANGUAGE 'plpgsql'

    COST 100
    IMMUTABLE 
    
AS $BODY$
declare
  res varchar(100) DEFAULT '';
begin
  res := lower(in_lexeme);
  res := regexp_replace(res,'[ъь]','','g');
  res := regexp_replace(res,'(йо|ио|йе|ие)','и','g');
  res := regexp_replace(res,'[оыя]','а','g');
  res := regexp_replace(res,'[еёэ]','и','g');
  res := regexp_replace(res,'ю','у','g');
  res := regexp_replace(res,'б([псткбвгджзфхцчшщ]|$)','п\1','g');
  res := regexp_replace(res,'з([псткбвгджзфхцчшщ]|$)','с\1','g');
  res := regexp_replace(res,'д([псткбвгджзфхцчшщ]|$)','т\1','g');
  res := regexp_replace(res,'в([псткбвгджзфхцчшщ]|$)','ф\1','g');
  res := regexp_replace(res,'г([псткбвгджзфхцчшщ]|$)','к\1','g');  
  res := regexp_replace(res,'дс','ц','g');
  res := regexp_replace(res,'тс','ц','g');
  res := regexp_replace(res,'(.)\1','\1','g');
  return res;
exception
  when others then raise exception '%', sqlerrm;
end;
$BODY$;



Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
CREATE OR REPLACE FUNCTION test.metaphone(
	in_phonemes text)
    RETURNS text
    LANGUAGE 'plpgsql'

    COST 100
    IMMUTABLE 
    
AS $BODY$
begin
  return (
    select string_agg(q.lex,' ') from (
      select test.phoneme(lexeme) as lex from unnest(to_tsvector('simple', in_phonemes))	
      order by positions
    ) as q
  );
exception when others then
  raise '%', SQLERRM using errcode = SQLSTATE;
end;
$BODY$;



Код: sql
1.
2.
3.
4.
5.
6.
7.
SELECT 
name,
SIMILARITY(test.metaphone(name),test.metaphone('Ответ на все сущее'))
FROM test.sample
order by 
2 desc
LIMIT 100;


Результат также слабый.
Т.е. даже при изменении порядка следования символов в слове, уже выдает слабый результат.
Если же еще и заменить пару соседних букв,рядом расположенных на клавиатуре, совсем печально.
Может я его как то неправильно готовлю?
...
Рейтинг: 0 / 0
26.01.2020, 20:33
    #39918864
Swa111
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
нечеткий поиск
Troglodit,

У себя реализовывали через алгоритм расчета расстояния по алгоритму дамерау левенштейн для каждой компоненты ФИО. при этом допускается расстояние не больше 1 (грубо говоря не более одной опечатки). + Дополнительный словарь наиболее частых опечаток. для ускорения поиска (особенно фамилий) принято что пользователи в первой букве ни когда не ошибаются. Так как алгоритм самописный и перекочевал из оракла не оптимизированным время поиска довольно большое (база ~140тыс ФИО) около 0,5-1 сек. С точки зрения оператора не так много.

Когда точности поиска стало не достаточно (стали приходить документы где есть только Фамилия И.О. + должность) добавили разбор должностей. Должность разбивалась на лексемы, из нее выкидывались части в которых чаще всего делали ошибки (указание категории или двойные должности), затем убирались малозначимые слова (определяются опытно), затем убираются все гласные. Так же находим расстояние по дамерау-левенштейну (не более 1). Естественно должности смотрим только по тем у кого подходят ФИО.
...
Рейтинг: 0 / 0
26.01.2020, 23:35
    #39918907
Troglodit
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
нечеткий поиск
Swa111,
Спасибо за ответ.
Я пробовал использовать стандартную levenshtein, но результаты печальные, даже хуже чем все остальное.
В моем случае не фио и порядок слов может быть разным, да и ошибок более чем 2.
Но в моем случае те варианты, которые я пробовал давали плохой результат даже в когда все символы введены верно, но не
верен порядок.
Прмире.
Так же возможны стандартные ошибки в виде ввода похожих букв разных алфавитов.
Как то ограничить как с ФИО вряд ли получиться.
...
Рейтинг: 0 / 0
03.02.2020, 15:45
    #39921876
Ролг Хупин
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
нечеткий поиск
"нечеткий поиск" - это что?

это типа гугловского "Did you mean?" - поиска с опечатками?
...
Рейтинг: 0 / 0
03.02.2020, 22:59
    #39922076
Troglodit
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
нечеткий поиск
Ролг Хупин,
Да что то вроде этого.
...
Рейтинг: 0 / 0
04.02.2020, 01:00
    #39922090
Ы2
Ы2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
нечеткий поиск
Troglodit, результат similarity() имеет смысл, если длины сравниваемых строк хотя бы по 20—25 символов и примерно равны между собой. Эта функция хороша, если вам нужно найти предложения, чем-то похожие на заданное, напр., с теми же словами в другом порядке, с заменой одного—двух слов из многих, с парафразом и т.п.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
select
	similarity('В прошлый вторник Иванов купил будильник.', 'В прошлый вторник Иванов купил будильник.'),
	similarity('В прошлый вторник Иванов купил будильник.', 'Будильник Иванов купил в прошлый вторник .')
	similarity('В прошлый вторник Иванов купил будильник.', 'В прошлый вторник Иванову купили будильник.'),
	similarity('В прошлый вторник Иванов купил будильник.', 'В прошлый вторник Иванов купил штаны.'),
	similarity('В прошлый вторник Иванов купил будильник.', 'В прошлый вторник Иванова убили будильником.'),
	similarity('В прошлый вторник Иванов купил будильник.', 'В прошлый четверг Иванов купил будильник.')
;


levenshtein() же обычно хорош, когда у вас есть таблица всех словоформ, чтобы предлагать только то, что у вас точно есть.

Для нечеткого поиска вам, видимо, нужно построить «нечеткий индекс» — сделать что-то типа FTS по вашим метафонам.
...
Рейтинг: 0 / 0
04.02.2020, 11:41
    #39922188
Ролг Хупин
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
нечеткий поиск
Troglodit
Ролг Хупин,
Да что то вроде этого.


Тогда надо немного с другого конца заходить, читаем Норвига
https://norvig.com/spell-correct.html

Я когда-то по его алгоритму сделал корректор для SQL Server
...
Рейтинг: 0 / 0
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / нечеткий поиск / 7 сообщений из 7, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]