/ / Dopasowanie logiki rozmytej - sql, sql-server, tsql, sql-server-2012, dopasowywanie ciągów znaków

Dopasowywanie logiki rozmytej - sql, sql-server, tsql, sql-server-2012, dopasowywanie ciągów znaków

Tak więc szukam implementacji logiki rozmytejdopasowanie w mojej firmie i problemy z uzyskaniem dobrych wyników. Na początek próbuję dopasować nazwy firm do nazw znajdujących się na liście dostarczonej przez inne firmy.
Moją pierwszą próbą było użycie soundex, ale wygląda na to, że soundex porównuje tylko kilka pierwszych dźwięków w nazwie firmy, więc dłuższe nazwy firm były zbyt łatwo zdezorientowane.
Pracuję teraz nad moją drugą próbą użyciaporównanie odległości w levensterze. Wygląda obiecująco, zwłaszcza jeśli najpierw usunę interpunkcję. Jednak nadal nie mogę znaleźć duplikatów bez zbyt wielu fałszywych alarmów.
Jednym z problemów, które mam, są firmy takie jakwidgetsco vs widgets inc. Tak więc, jeśli porówna się podciągi o długości krótszej nazwy, pobieram też rzeczy takie jak BBC University i kampus Uniwersytetu CBC. Podejrzewam, że rozwiązaniem może być wynik wykorzystujący kombinację odległości i najdłuższego wspólnego podciągu.
Czy ktoś zdołał zbudować algorytm, który dokonuje takiego dopasowania z ograniczonymi fałszywymi pozytywami?

Odpowiedzi:

0 dla odpowiedzi № 1

Chcesz użyć czegoś takiego jak Levenshtein Distance lub inny algorytm porównywania ciągów znaków. Możesz rzucić okiem na ten projekt na Codeplex.

http://fuzzystring.codeplex.com/


0 dla odpowiedzi nr 2

Czy używasz programu Access? Jeśli tak, rozważ znak "*" bez cudzysłowów. Jeśli używasz programu SQL Server, użyj znaku "%", ale to naprawdę nie jest logika rozmyta, to naprawdę operator Like .Jeśli naprawdę potrzebujesz logiki rozmytej, wyeksportuj zestaw danych do programu Excel i załaduj AddIn z poniższego adresu URL.

https://www.microsoft.com/en-us/download/details.aspx?id=15011

Przeczytaj uważnie instrukcje. To na pewno działa, i działa świetnie, ale musisz postępować zgodnie z instrukcjami i nie jest to całkowicie intuicyjne.Pierwszy raz próbowałem, nie postępowałem zgodnie z instrukcjami i zmarnowałem dużo czasu próbując dostać to działa. W końcu zorientowałem się, i działało świetnie !!


0 dla odpowiedzi № 3

Mieliśmy dobre wyniki pod względem nazwy i adresudopasowywanie za pomocą funkcji Metaphone stworzonej przez Lawrence Philips. Działa to podobnie jak Soundex, ale tworzy wzór dźwiękowy / spółgłoskowy dla całej wartości. Może się to okazać użyteczne w połączeniu z innymi technikami, szczególnie jeśli możesz usunąć trochę puchu jak "co". i "inc." jak wspomniano w innych komentarzach:

create function [dbo].[Metaphone](@str as nvarchar(70), @KeepNumeric as bit = 0)
returns nvarchar(25)
/*
Metaphone Algorithm

Created by Lawrence Philips.
Metaphone presented in article in "Computer Language" December 1990 issue.

*********** BEGIN METAPHONE RULES ***********
Lawrence Philips" RULES follow:
The 16 consonant sounds:
|--- ZERO represents "th"
|
B  X  S  K  J  T  F  H  L  M  N  P  R  0  W  Y
Drop vowels

Exceptions:
Beginning of word: "ae-", "gn", "kn-", "pn-", "wr-"   ----> drop first letter
Beginning of word: "wh-"                              ----> change to "w"
Beginning of word: "x"                                ----> change to "s"
Beginning of word: vowel or "H" + vowel               ----> Keep it

Transformations:
B ----> B       unless at the end of word after "m", as in "dumb", "McComb"
C ----> X       (sh) if "-cia-" or "-ch-"
S       if "-ci-", "-ce-", or "-cy-"
SILENT if "-sci-", "-sce-", or "-scy-"
K       otherwise
K       "-sch-"
D ----> J       if in "-dge-", "-dgy-", or "-dgi-"
T       otherwise
F ----> F
G ---->         SILENT if   "-gh-" and not at end or before a vowel
"-gn" or "-gned"
"-dge-" etc., as in above rule
J       if "gi", "ge", "gy" if not double "gg"
K       otherwise
H ---->         SILENT  if after vowel and no vowel follows
or "-ch-", "-sh-", "-ph-", "-th-", "-gh-"
H       otherwise
J ----> J
K ---->         SILENT if after "c"
K       otherwise
L ----> L
M ----> M
N ----> N
P ----> F       if before "h"
P       otherwise
Q ----> K
R ----> R
S ----> X       (sh) if "sh" or "-sio-" or "-sia-"
S       otherwise
T ----> X       (sh) if "-tia-" or "-tio-"
0       (th) if "th"
SILENT if "-tch-"
T       otherwise
V ----> F
W ---->         SILENT if not followed by a vowel
W       if followed by a vowel
X ----> KS
Y ---->         SILENT if not followed by a vowel
Y       if followed by a vowel
Z ----> S
*/


as
begin
declare @Result varchar(25)
,@str3  char(3)
,@str2  char(2)
,@str1  char(1)
,@strp  char(1)
,@strLen tinyint
,@cnt   tinyint

set @strLen = len(@str)
set @cnt = 0
set @Result = ""

-- Preserve first 5 numeric values when required
if @KeepNumeric = 1
begin
set @Result = case when isnumeric(substring(@str,1,1)) = 1
then case when isnumeric(substring(@str,2,1)) = 1
then case when isnumeric(substring(@str,3,1)) = 1
then case when isnumeric(substring(@str,4,1)) = 1
then case when isnumeric(substring(@str,5,1)) = 1
then left(@str,5)
else left(@str,4)
end
else left(@str,3)
end
else left(@str,2)
end
else left(@str,1)
end
else ""
end

set @str = right(@str,len(@str)-len(@Result))
end

--Process beginning exceptions
set @str2 = left(@str,2)

if @str2 = "wh"
begin
set @str  = "w" + right(@str , @strLen - 2)
set @strLen =   @strLen - 1
end
else
if @str2 in("ae", "gn", "kn", "pn", "wr")
begin
set @str = right(@str , @strLen - 1)
set @strLen = @strLen - 1
end



set @str1 = left(@str,1)

if @str1 =  "x"
set @str  = "s" + right(@str , @strLen - 1)
else
if @str1 in ("a","e","i","o","u")
begin
set @str = right(@str, @strLen - 1)
set @strLen = @strLen - 1
set @Result = @Result + @str1
end

while @cnt <= @strLen
begin
set @cnt = @cnt + 1
set @str1 = substring(@str,@cnt,1)

set @strp = case when @cnt <> 0
then substring(@str,(@cnt-1),1)
else " "
end

-- Check if the current character is the same as the previous character.
-- If we are keeping numbers, only compare non-numeric characters.
if case when @KeepNumeric = 1 and @strp = @str1 and isnumeric(@str1) = 0 then 1
when @KeepNumeric = 0 and @strp = @str1 then 1
else 0
end = 1
continue    -- Skip this loop

set @str2 = substring(@str,@cnt,2)

set @Result = case when @KeepNumeric = 1 and isnumeric(@str1) = 1
then @Result + @str1
when @str1 in("f","j","l","m","n","r")
then @Result + @str1
when @str1 = "q"
then @Result + "k"
when @str1 = "v"
then @Result + "f"
when @str1 = "x"
then @Result + "ks"
when @str1 = "z"
then @Result + "s"
when @str1 = "b"
then case when @cnt = @strLen
then case when substring(@str,(@cnt - 1),1) <> "m"
then @Result + "b"
else @Result
end
else @Result + "b"
end
when @str1 = "c"
then case when @str2  = "ch" or substring(@str,@cnt,3) = "cia"
then @Result + "x"
else case when @str2 in("ci","ce","cy") and @strp <> "s"
then @Result + "s"
else @Result + "k"
end
end
when @str1 = "d"
then case when substring(@str,@cnt,3) in ("dge","dgy","dgi")
then @Result + "j"
else @Result + "t"
end
when @str1 = "g"
then case when substring(@str,(@cnt - 1),3) not in ("dge","dgy","dgi","dha","dhe","dhi","dho","dhu")
then case when @str2 in("gi", "ge","gy")
then @Result + "j"
else case when @str2 <> "gn" or (@str2 <> "gh" and @cnt+1 <> @strLen)
then @Result + "k"
else @Result
end
end
else @Result
end
when @str1 = "h"
then case when @strp not in ("a","e","i","o","u") and @str2 not in ("ha","he","hi","ho","hu")
then case when @strp not in ("c","s","p","t","g")
then @Result + "h"
else @Result
end
else @Result
end
when @str1 = "k"
then case when @strp <> "c"
then @Result + "k"
else @Result
end
when @str1 = "p"
then case when @str2 = "ph"
then @Result + "f"
else @Result + "p"
end
when @str1 = "s"
then case when substring(@str,@cnt,3) in ("sia","sio") or @str2 = "sh"
then @Result + "x"
else @Result + "s"
end
when @str1 = "t"
then case when substring(@str,@cnt,3) in ("tia","tio")
then @Result + "x"
else case when @str2 = "th"
then @Result + "0"
else case when substring(@str,@cnt,3) <> "tch"
then @Result + "t"
else @Result
end
end
end
when @str1 = "w"
then case when @str2 not in("wa","we","wi","wo","wu")
then @Result + "w"
else @Result
end
when @str1 = "y"
then case when @str2 not in("ya","ye","yi","yo","yu")
then @Result + "y"
else @Result
end
else @Result
end
end

return @Result

end