Страница 1 из 3
					
				Нечёткий поиск
				Добавлено: 02 Июнь 2024, 5:56
				 Игорь Столяров
				Привет всем !
Вопрос простой и прямой: не пробовал ли кто-нибудь реализовать нечёткий поиск (например с заданным процентом подобия) ?
1. В принципе, алгоритмика известна, но я не математик. 

    Исходники есть на Java и Python ... Может быть тема поднималась где-то в архивах ClaMag ?
2. Конкретно меня сейчас интересует вопрос поиска подобных товаров (когда их названия записывают по-разному).
    Например: Сосиска в тесте, булочка с сосиской, сосиська запечённая в тесте и т.д.
3. В Clarion есть MATCH(). Опция Match:Soundex (по звучанию) не локализована, поиск по маске - это иное ...
Я не спрашиваю о готовом решении (хотя это было бы круто), но хотя бы направление туда, где рыба есть. 
Что бы не идти методом познания, на основе собственных ошибок. Заранее спасибо ! 

 
			 
			
					
				Нечёткий поиск
				Добавлено: 02 Июнь 2024, 9:00
				 finsoftrz
				Я давно пытался реализовать этот механизм для названий товаров и контрагентов. Именно в таком ключе, по проценту подобия. Делал алгоритм с разбиением на триады. Но, в целом, нормально не получилось, отлавливались только самые примитивные ситуации. В результате, просто отключил этот отчёт. Если удастся найти работающей решение, штука нужная и полезная.
			 
			
					
				Нечёткий поиск
				Добавлено: 02 Июнь 2024, 9:12
				 Игорь Столяров
				Спасибо ! Понял. Попробую спросить на хабе, может СуперКарл поможет ... 

 
			 
			
					
				Нечёткий поиск
				Добавлено: 02 Июнь 2024, 20:26
				 Ravenous
				Я делал на стороне БД (MSSQL, Oracle), в PostgreSQL есть 
pg_trgm  тоже нормально работает.
 
			 
			
					
				Нечёткий поиск
				Добавлено: 02 Июнь 2024, 22:18
				 kreator
				Логика простая. Данные должны храниться сейчас хотя бы в "формате" SQL. А там много чего есть. Если там нет, то надо теребить разработчиков таких серверов. Поиск правильно осуществлять на стороне сервера.
			 
			
					
				Нечёткий поиск
				Добавлено: 03 Июнь 2024, 8:01
				 finsoftrz
				Я несколько не так на триграммы разбивал. Надо будет попробовать алгоритм, как описано в psql, с добавлением пробелов. Так то все просто должно быть.
			 
			
					
				Нечёткий поиск
				Добавлено: 03 Июнь 2024, 8:21
				 Игорь Столяров
				finsoftrz писал(а): 03 Июнь 2024, 8:01
алгоритм, как описано в psql
 
Ссылу почитать опять засекретите ? 

 
			 
			
					
				Нечёткий поиск
				Добавлено: 03 Июнь 2024, 8:33
				 finsoftrz
				Игорь Столяров писал(а): 03 Июнь 2024, 8:21
finsoftrz писал(а): 03 Июнь 2024, 8:01
алгоритм, как описано в psql
 
Ссылу почитать опять засекретите ? 
 
В сообщении от Ravenous.
 
			 
			
					
				Нечёткий поиск
				Добавлено: 03 Июнь 2024, 8:44
				 Игорь Столяров
				Т.е. опять много шума из ничего ... 

В сообщении ведь применение встроенных методов, а не описание алгоритма. 

 
			 
			
					
				Нечёткий поиск
				Добавлено: 03 Июнь 2024, 8:46
				 finsoftrz
				В начале ("Примечание") вроде все понятно написано. Не?
			 
			
					
				Нечёткий поиск
				Добавлено: 03 Июнь 2024, 8:57
				 Игорь Столяров
				Ну не знаю. Наверно люди написавшие
Эта простая идея оказывается очень эффективной для измерения схожести слов на многих естественных языках.
понимают в этом. Можно попробовать сделать и посмотреть ...
 
			 
			
					
				Нечёткий поиск
				Добавлено: 03 Июнь 2024, 9:37
				 Ravenous
				
			 
			
					
				Нечёткий поиск
				Добавлено: 07 Июнь 2024, 15:18
				 finsoftrz
				Накидал тест алгоритма на коленке. 
Код: Выделить всё
form_r routine   !формирование отчета
  DATA
lor:queue queue, pre()
lor:idobj   long
lor:ind     long
lor:mass    string(3),dim(10000)
.
lor:symbols string(100)
lor:str     string(3)
lor:dl      long
lor:kolRep  long
lor:nameobjSel string(200)
lor:idobjSel   long
lor:indSel     long
lor:indMax     long
lor:massSel    string(3),dim(10000)
lor:massContr  long,dim(10000)
lor:i   long
lor:j   long
lor:k   long
lor:n   long
BasicProcess  BasicProcessType
  CODE
       lor:symbols='abcdefghijklmnopqrstuvwxyzабвгдеёжзийклмнопрстуфхцчшщъыьэюя0123456789'  !список анализируемых символов
       BasicProcess.Init(True,'Загрузка товаров',,,,,100,Records(tovar))
       set(tovar)
       loop
          next(tovar)
          if error()
             break
          .
          if ~BasicProcess.LoopStep()
             break
          .
          if tov:NoPost=1
             cycle
          .
          if tov:name=''
             cycle
          .
          tov:name=left(lower(tov:name))
          lor:nameobjSel=''
          lor:j=0
          loop lor:i=1 to len(clip(tov:name))
             if instring(tov:name[lor:i],clip(lor:symbols),1,1)>0
                lor:j+=1
                lor:nameobjSel[lor:j]=tov:name[lor:i]
             .
          .
          clear(lor:queue)
          lor:idobj=tov:id
          lor:dl=len(clip(lor:nameobjSel))
          lor:ind=0
          lor:k=1
          loop
             if lor:k>lor:dl
                break
             .
             lor:str=lor:nameobjSel[lor:k : lor:k+2]
             if lor:ind>9996
                break
             .
             lor:ind+=1
             lor:mass[lor:ind]='  ' & lor:str[1]
             lor:ind+=1
             lor:mass[lor:ind]=' ' & lor:str[1 : 2]
             lor:ind+=1
             lor:mass[lor:ind]=lor:str
             if lor:str[2 : 3]<>''
                lor:ind+=1
                lor:mass[lor:ind]=lor:str[2 : 3] & ' '
             .
             lor:k+=3
          .
          add(lor:queue)
       .
    BasicProcess.Kill()
    open(ProgressWindow)
    BasicProcess.Init(False,'Сопоставление',,?Progress:Thermometer,?Progress:Cancel,True,5,Records(lor:queue),?Progress:UserString)
    loop lor:i=1 to records(lor:queue)-1
       get(lor:queue,lor:i)
       if ~BasicProcess.LoopStep()
          break
       .
       lor:indSel=lor:ind
       lor:idobjSel=lor:idobj
       lor:massSel=lor:mass
       loop lor:j=lor:i+1 to records(lor:queue)
          get(lor:queue,lor:j)
          lor:kolRep=0
          lor:indMax=choose(lor:indSel>lor:ind,lor:indSel,lor:ind)
          clear(lor:massContr)
          loop lor:k=1 to lor:indSel
             loop lor:n=1 to lor:ind
                if lor:mass[lor:n]=lor:massSel[lor:k] and lor:massContr[lor:n]=0
                   lor:kolRep+=1
                   lor:massContr[lor:n]=1
                .
             .
          .
          lor:kolRep=lor:kolRep/lor:indMax*100
          if Loc:Proc<=lor:kolRep
             clear(Loc:Queue)
             Loc:IDObj1=lor:idobjSel
             Loc:IDObj2=lor:idobj
             Loc:ProcQ=lor:kolRep
             add(Loc:Queue)
          .
       .
    .
    free(lor:queue)
    BasicProcess.Kill()
    close(ProgressWindow)
 
			
				
			
 
					
		
		
		
			  
			 
			
					
				Нечёткий поиск
				Добавлено: 07 Июнь 2024, 16:02
				 kreator
				Почему паштет №6 "Корона Балтики" не имеет дубликата? наверно есть ещё над чем работать.
			 
			
					
				Нечёткий поиск
				Добавлено: 07 Июнь 2024, 16:06
				 finsoftrz
				kreator писал(а): 07 Июнь 2024, 16:02
Почему паштет №6 "Корона Балтики" не имеет дубликата? наверно есть ещё над чем работать.
 
Не понял.