Also, ich bin auf der Suche nach Implementierung von Fuzzy Logic Matching in meiner Firma und habe Probleme, gute Ergebnisse zu bekommen. Für den Anfang versuche ich, Firmennamen mit denen auf einer Liste zu vergleichen, die von anderen Firmen geliefert wird.
Mein erster Versuch war es, soundex zu verwenden, aber es sieht so aus, als ob Soundex nur die ersten paar Töne im Firmennamen vergleicht, so dass lange Firmennamen zu leicht voneinander zu unterscheiden sind.
Ich arbeite jetzt an meinem zweiten Versuch mit dem Levtenstein Distanzvergleich. Es sieht vielversprechend aus, besonders wenn ich die Interpunktion zuerst entferne. Ich habe jedoch immer noch Probleme, Duplikate zu finden, ohne zu viele Fehlalarme.
Eines der Probleme, die ich habe, ist Unternehmen wie Widgetsco vs Widgets inc. Also, wenn ich den Teilstring der Länge des kürzeren Namens vergleiche, nehme ich auch Dinge wie BBC University und CBC University Campus auf. Ich vermute, dass eine Partitur, die eine Kombination aus Abstand und längster gemeinsamer Teilkette verwendet, die Lösung sein könnte.
Hat es jemand geschafft, einen Algorithmus zu erstellen, der eine solche Anpassung mit begrenzten Fehlalarmen durchführt?Fuzzy Logic Matching
Antwort
Sie möchten etwas wie Levenshtein Distance oder einen anderen String-Vergleichsalgorithmus verwenden. Vielleicht möchten Sie sich dieses Projekt auf Codeplex anschauen.
Ich mag Levenshtein Entfernung, aber das Problem ist, dass es nicht "unscharf" ist. Die Entfernung zwischen 'CBC University' und 'CBC University' ist 4, obwohl sie wahrscheinlich der gleiche Ort sind.Dieser SO-Post hat einen netten "unscharfen" Levenshtein [SQL Server Fuzzy Search mit Übereinstimmungsgrad] (http://stackoverflow.com/questions/26259117/sql-server-fuzzy-search-with-percentage-of-match) – user918967
Verwenden Sie Access? Wenn ja, betrachten Sie das Zeichen '*' ohne die Anführungszeichen. Wenn Sie SQL Server verwenden, verwenden Sie das Zeichen "%". Dies ist jedoch keine Fuzzy-Logik, es ist wirklich der Like-Operator. Wenn Sie wirklich Fuzzy-Logik benötigen, exportieren Sie Ihren Datensatz nach Excel und laden Sie das AddIn von der folgenden URL.
https://www.microsoft.com/en-us/download/details.aspx?id=15011
Lesen Sie die Anweisungen sehr sorgfältig. Es funktioniert definitiv, und es funktioniert gut, aber Sie müssen den Anweisungen folgen, und es ist nicht vollständig intuitiv. Als ich es das erste Mal ausprobierte, habe ich die Anweisungen nicht befolgt und viel Zeit verschwendet, um es zum Laufen zu bringen. Irgendwann habe ich es herausgefunden, und es hat super funktioniert !!
Wir haben gute Ergebnisse bei der Namens- und Adressanpassung mit einer Metaphone-Funktion erzielt, die von Lawrence Philips erstellt wurde. Es funktioniert ähnlich wie Soundex, erzeugt aber ein Klang-/Konsonantenmuster für den gesamten Wert. Sie können dies nützlich in Verbindung mit einigen anderen Techniken finden, vor allem, wenn Sie einige der Flaum wie 'co.' und "inc." Wie in anderen Kommentaren erwähnt:
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
- 1. F # und Fuzzy Logic
- 2. Fuzzy-Matching zu Referenztabelle
- 3. Best Fuzzy Matching-Algorithmus?
- 4. Fuzzy-Bit-Matching
- 5. Fuzzy Regex Matching in Julia
- 6. Fuzzy-Matching mit T-SQL
- 7. Algorithmus für Fuzzy-Matching Mehrere Wörter in einem Absatz
- 8. Elasticsearch Fuzzy-Matching-Optimierung für riesige Server/Server-Cluster
- 9. zwei Daten Merging Frames Fuzzy/Ungefähre String Matching in R
- 10. Fuzzy Matching Breiten- und Längengrad mit (etwas) Big Data
- 11. Emacs Fuzzy Autovervollständigung
- 12. Fuzzy Reguläre Ausdrücke
- 13. Powershell Logic
- 14. Fuzzy Scheduling
- 15. Fuzzy-Matching über eine Datenrahmenspalte anwenden und Ergebnisse in einer neuen Spalte speichern
- 16. Fuzzy-Matching von Zeilen zweier Datensätze ohne Verwendung einer For-Schleife
- 17. Fuzzy String Vergleich - Erkennen von Kurznamen
- 18. Python Boolean Logic Confusion
- 19. Adempiere Multiple Display Logic
- 20. MySQL Logic Count Operation
- 21. Business Logic Classes Naming
- 22. sas/sql Logic benötigt
- 23. Mod Rewrite Logic
- 24. OpenGL - Matrix Logic Error
- 25. Logic apps Auslöserhistorie
- 26. C# calulcation logic
- 27. PHP Conditional Logic
- 28. Erweiterte Django Template Logic
- 29. jQuery Toggle Width Logic
- 30. PHP Maths Logic
Die einzige Übereinstimmung, die ich je tun musste, basierte auf Teilstring-Matching, z. BBC Uni und BBC Universität. Dies setzt voraus, dass der Anfangsteil der Zeichenfolge unter allen Duplikaten identisch ist. Für Fälle wie: widgets inc würde ich zuerst die Abkürzungen der Entity-Typen entfernen. Wenn Sie andere verwandte Daten haben, z.B. Firmenadresse, CEO des Unternehmens, dann auch das kann verglichen werden, um eine Punktzahl der Wahrscheinlichkeit zu produzieren, dass zwei Unternehmen gleich sind. Ich würde mich darauf konzentrieren, die Daten zuerst zu normalisieren (indem ich Flusen entferne), bevor ich versuche, sie tatsächlich zu vergleichen. – Alex
Entfernen der Flusen ist in der Regel eine gute Übung, egal welchen Algorithmus Sie verwenden. – Yobik
Ich werde die Daten normalisieren. Für Fälle wie "Smith & Wesson", die zu "Smith and Wesson" passen, würde ich alle "&" zu "und" für die Zwecke eines Matches konvertieren. Ich würde auch versuchen, Entity-Typen und ihre Abkürzungen (inkl. Co.) Zu entfernen und zu überprüfen, ob dies falsche Positive ergibt. Wenn Daten komplexere Konstrukte aufweisen, z. "CompanyA trading as CompanyB", dann müssen sie geparst werden. IMO, Fuzzy Matching gut strukturierte Daten wie Firmennamen ist ein falsches Werkzeug für den Job. – Alex