2009-06-12 8 views
15

Gibt es Tools oder Methoden, die für die Zuordnung von Namen zwischen zwei verschiedenen Datenquellen verwendet werden können?Übereinstimmende Datensätze basierend auf Personenname

Die Systeme haben keine anderen allgemeinen Informationen und die Namen wurden in vielen Fällen unterschiedlich eingegeben.

Beispiele für nicht-exakte Treffer:

King Jr., Martin Luther = König, Martin (auszuschließen Suffix)
Erving, Dr. J. = Erving, J. (auszuschließen Präfix)
Obama, Barak Hussein = Obama, Barak (auszuschließen Mittelname)
Pufnstuf, HR = Pufnstuf, Haibane Renmei (Match Abkürzungen)
tankengine, Thomas = tankengine, Tom (Match gemeinsamen Spitznamen)
Flair, Rick "die Natureboy" = Flair , Natureboy (Übereinstimmung mit Spitzname)

Antwort

14

Ich musste eine Vielzahl von Techniken vorgeschlagen haben. Danke, dass sie mich in die richtige Richtung weisen. Hoffentlich hilft das folgende jemand anderen mit dieser Art von Problem zu lösen.

Entfernen überschüssigen Zeichen

CREATE FUNCTION [dbo].[fn_StripCharacters] 
(
    @String NVARCHAR(MAX), 
    @MatchExpression VARCHAR(255) 
) 
RETURNS NVARCHAR(MAX) 
AS 
BEGIN 
    SET @MatchExpression = '%['[email protected]+']%' 

    WHILE PatIndex(@MatchExpression, @String) > 0 
     SET @String = Stuff(@String, PatIndex(@MatchExpression, @String), 1, '') 

    RETURN @String 

END 

Verbrauch:

--remove all non-alphanumeric and non-white space 
dbo.fn_StripCharacters(@Value, , '^a-z^0-9 ') 

Split Name in Teile

CREATE FUNCTION [dbo].[SplitTable] (@sep char(1), @sList StringList READONLY) 
RETURNS @ResultList TABLE 
    (
     [ID] VARCHAR(MAX), 
     [Val] VARCHAR(MAX) 
    ) 
AS 
BEGIN 

declare @OuterCursor cursor 
declare @ID varchar(max) 
declare @Val varchar(max) 

set @OuterCursor = cursor fast_forward for (SELECT * FROM @sList) FOR READ ONLY 

open @OuterCursor 

fetch next from @OuterCursor into @ID, @Val 

while (@@FETCH_STATUS=0) 
begin 

    INSERT INTO @ResultList (ID, Val) 
    select @ID, split.s from dbo.Split(@sep, @Val) as split 
      where len(split.s) > 0 

    fetch next from @OuterCursor into @ID, @Val 
end 

close @OuterCursor 
deallocate @OuterCursor 

CREATE FUNCTION [dbo].[Split] (@sep char(1), @s varchar(8000)) 
RETURNS table 
AS 
RETURN (
    WITH Pieces(pn, start, stop) AS (
     SELECT 1, 1, CHARINDEX(@sep, @s) 
     UNION ALL 
     SELECT pn + 1, stop + 1, CHARINDEX(@sep, @s, stop + 1) 
     FROM Pieces 
     WHERE stop > 0 
    ) 
    SELECT pn, 
     LTRIM(RTRIM(SUBSTRING(@s, start, 
      CASE WHEN stop > 0 
        THEN stop-start 
        ELSE 8000 
      END))) AS s 
    FROM Pieces 
) 

RETURN 

Verbrauch:

--create split name list 
DECLARE @NameList StringList 

INSERT INTO @NameList (ID, Val) 
SELECT id, firstname FROM dbo.[User] u 
WHERE PATINDEX('%[^a-z]%', u.FirstName) > 0 

----remove split dups 
select u.ID, COUNT(*) 
from dbo.import_SplitTable(' ', @NameList) splitList 
INNER JOIN dbo.[User] u 
ON splitList.id = u.id 

Gemeinsame Spitznamen:

habe ich eine Tabelle basierend auf this list und verwendet es auf gemeinsamen Namen Äquivalente zu verbinden.

Verbrauch:

SELECT u.id 
, u.FirstName 
, u_nickname_maybe.Name AS MaybeNickname 
, u.LastName 
, c.ID AS ContactID from 
FROM dbo.[User] u 
INNER JOIN nickname u_nickname_match 
ON u.FirstName = u_nickname_match.Name 
INNER JOIN nickname u_nickname_maybe 
ON u_nickname_match.relatedid = u_nickname_maybe.id 
LEFT OUTER JOIN 
(
    SELECT c.id, c.LastName, c.FirstName, 
     c_nickname_maybe.Name AS MaybeFirstName 
    FROM dbo.Contact c 
    INNER JOIN nickname c_nickname_match 
    ON c.FirstName = c_nickname_match.Name 
    INNER JOIN nickname c_nickname_maybe 
    ON c_nickname_match.relatedid = c_nickname_maybe.id 
    WHERE c_nickname_match.Name <> c_nickname_maybe.Name 
) as c 
ON c.AccountHolderID = ah.ID 
     AND u_nickname_maybe.Name = c.MaybeFirstName AND u.LastName = c.LastName 
WHERE u_nickname_match.Name <> u_nickname_maybe.Name 

Phonetik Algorithmen (Jaro Winkler):

Der erstaunliche Artikel, Beyond SoundEx - Functions for Fuzzy Searching in MS SQL Server, zeigt, wie die SimMetrics Bibliothek in SQL Server installieren und zu verwenden. Diese Bibliothek ermöglicht es Ihnen, eine relative Ähnlichkeit zwischen Strings zu finden und enthält zahlreiche Algorithmen. Ich landete meistens Jaro Winkler, um die Namen zu vergleichen.

Verbrauch:

SELECT 
u.id AS UserID 
,c.id AS ContactID 
,u.FirstName 
,c.FirstName 
,u.LastName 
,c.LastName 
,maxResult.CombinedScores 
from 
(
    SELECT 
     u.ID 
    , 
     max(
      dbo.JaroWinkler(lower(u.FirstName), lower(c.FirstName)) 
      * dbo.JaroWinkler(LOWER(u.LastName), LOWER(c.LastName)) 
     ) AS CombinedScores 
    FROM dbo.[User] u, dbo.[Contact] c 
    WHERE u.ContactID IS NULL 
    GROUP BY u.id 
) AS maxResult 
INNER JOIN dbo.[User] u 
ON maxResult.id = u.id 
INNER JOIN dbo.[Contact] c 
ON maxResult.CombinedScores = 
dbo.JaroWinkler(lower(u.FirstName), lower(c.FirstName)) 
* dbo.JaroWinkler(LOWER(u.LastName), LOWER(c.LastName)) 
+0

Dies muss die umfassendste Antwort auf SO sein - es ist ein Problem, das ich in Code gelöst habe, aber nie in reinem Sql - sehr elegant. – MrTelly

+0

@MrTelly Danke. Ich musste allerdings auf die CLR für die SimMetrics-Bibliothek zurückgreifen. Hoffentlich rettet dies jemand anderem bei seinem Konvertierungsprojekt. –

1

Ich verwende oft Soundex-Algorithmen für diese Art von Situation. Versuchen Sie den Double Metaphone Algorithmus. Wenn Sie SQL Server verwenden, gibt es Quellcode zum Erstellen einer benutzerdefinierten Funktion.

Da Sie Daten transponiert haben, möchten Sie sie möglicherweise etwas normalisieren, z. B. alle Kommas entfernen und die Wörter nach dem ersten Buchstaben sortieren. Dadurch erhalten Sie ein besseres Anpassungspotenzial. Wenn Wörter in der Mitte hinzugefügt wurden, wird es etwas schwieriger. Sie könnten in Betracht ziehen, einen Namen in Wörter zu zerlegen, mit Double Metaphone zu überprüfen, ob ein Wort in der anderen passenden Spalte vorhanden ist, und dann die Gesamtzahl der Übereinstimmungen im Vergleich zu Wörtern zu sammeln, die Ihnen sagen, wie nahe die beiden Spalten sind.

Ich würde auch gemeinsame Wörter wie Dr., Herr, Frau, Frau usw. herausfiltern, bevor Sie die Vergleiche machen.

1

Hier sind einige Optionen:

Phonetic Algorithmen ...

Soundex (http://en.wikipedia.org/wiki/Soundex)

Double Metaphone (http://en.wikipedia.org/wiki/Double_Metaphone)

bearbeiten Entfernung (http://en.wikipedia.org/wiki/Levenshtein_distance)

Jaro- Winkler Entfernung (http://en.wikipedia.org/wiki/Jaro-Winkler_distance)

Eine andere Sache, die Sie versuchen könnten, wäre, jedes Wort (teilen auf Raum und möglicherweise Bindestrich) mit jedem Wort im anderen Namen zu vergleichen und zu sehen, wieviele Wörter zusammenpassen. Vielleicht kombinieren Sie dies mit phonetischen Algorithmen für mehr Fuzzy-Matching. Bei einem großen Datenbestand möchten Sie jedes Wort indizieren und mit einer Namens-ID abgleichen. Für den Abkürzungsvergleich können Sie nur den ersten Buchstaben vergleichen. Sie möchten wahrscheinlich alles außer Buchstaben ignorieren, wenn Sie Wörter auch vergleichen.

Viele der phonetischen Algorithmen haben Open Source/Samples online.

2

Es ist ein sehr komplexes Problem - und es gibt eine Menge von teueren Werkzeugen, um es richtig zu tun.
Wenn Sie jemals warum gefragt, nicht als Tom, Dick oder Harry (oder Bill) auf einem Flug einchecken können
Oder warum -consider no-fly-Listen und Terroristen-Listen sehen nicht funktionieren:

(1) Muammar Qaddafi
(2) Mo'ammar Gadhafi
(3) Muammar Kaddafi
(4) Muammar Qaddafis
(5) Moammar El Kadhafi
(6) Muammar Gadafi
(7) Mu'ammar al-Qadafi
(8) Moamer El Kazzafi
(9) Moamar al-Gaddafi
(10) Mu'ammar Al Qathafi
(11) Muammar Al Qathafi
(12) Mo'ammar el-Gadhafi
(13) Moamar El Kadhafi
(14) Muammar al-Qaddafis
(15) Mu'ammar al-Qadhdhafi
(16) Mu'ammar Qadafi
(17) Moamar Gaddafi
(18) Mu'ammar Qadhdhafi
(19) Muammar Khaddafi
(20) Muammar al -Khaddafi
(21) Mu'amar al-Kadafi
(22) Muammar Ghaddafy
(23) Muammar Ghadafi
(24) Muammar Ghaddafi
(25) Muamar Kaddafi
(26) Muammar Quathafi
(27) Muammar Gheddafi
(28) Muamar al-Kaddafi
(29) Moammar Khadafy
(30) Moammar Qudhafi
(31) Mu'ammar al-Qaddafi
(32) Mulazim AWW al Mu'ammar Muhammad Abu Minyar al-Qadhafi

Und das ist nur offizielle Schreibweisen - es enthält keine Tippfehler!

+0

Können Sie die Liste oder die Quelle angeben, wo solche Namen gefunden werden können? – bjan

1

Metaphone 3 ist die dritte Generation des Metaphone-Algorithmus. Es erhöht die Genauigkeit der Laut Codierung von der 89% der Doppel Metaphone zu 98%, wie eine Datenbank der häufigsten Wörter Englisch getestet, und die Namen und nicht-englischen Wörtern vertraut in Nord Amerika. Dies erzeugt eine extrem zuverlässige phonetische Codierung für die amerikanischen Aussprachen.

Metaphone 3 wurde entworfen und entwickelt von Lawrence Philips, der die ursprünglichen Metaphone und Doppel Metaphone Algorithmen entwickelt und entwickelt hat.

Verwandte Themen