2009-06-12 3 views
15

Esistono strumenti o metodi che possono essere utilizzati per la corrispondenza del nome di una persona tra due diverse origini dati?Record corrispondenti in base al Nome persona

I sistemi non hanno altre informazioni comuni ei nomi sono stati immessi in modo diverso in molti casi.

Esempi di corrispondenze non esatte:

King Jr., Martin Luther = re, Martin (escludere suffisso)
Erving, Dr. J. = Erving, J. (escludere prefisso)
Obama, Barak Hussein = Obama, Barak (escludere secondo nome)
Pufnstuf, HR = Pufnstuf, Haibane Renmei (partita abbreviazioni)
Tankengine, Thomas = Tankengine, Tom (partita soprannomi comuni)
Flair, Rick "il Junior.ai la" = Flair , Natureboy (match on nickname)

risposta

14

Ho dovuto usare una varietà di tecniche suggerite. Grazie, indicandomi nella giusta direzione. Speriamo che quanto segue possa aiutare qualcun altro a risolvere questo tipo di problema.

rimuovendo i caratteri in eccesso

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 

Usage:

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

nome Spalato in parti

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 

Uso:

--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 

soprannomi comuni:

ho creato una tabella basata su this list e lo ha utilizzato per unire in equivalenti di nome comune.

Usage:

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 

algoritmi fonetici (Jaro Winkler):

L'articolo incredibile, Beyond SoundEx - Functions for Fuzzy Searching in MS SQL Server, mostra come installare e utilizzare la libreria SimMetrics in SQL Server. Questa libreria ti consente di trovare la somiglianza relativa tra stringhe e include numerosi algoritmi. Ho finito per lo più usando Jaro Winkler per abbinare i nomi.

Usage:

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

Questa deve essere la risposta più completa su SO: è un problema che ho risolto nel codice ma mai in puro Sql: molto elegante. – MrTelly

+0

@MrTelly Grazie. Però dovevo ricorrere al CLR per la libreria SimMetrics. Si spera che ciò salverà qualcun altro a causa del loro progetto di conversione. –

1

Spesso utilizzo algoritmi di tipo soundex per questo tipo di situazione. Prova l'algoritmo Double Metaphone. Se si utilizza SQL Server, esiste un codice sorgente per creare una funzione definita dall'utente.

Poiché i dati sono stati trasposti, è consigliabile normalizzarli un po ', ad esempio rimuovere tutte le virgole e ordinare le parole risultanti per prima lettera. Ciò ti darà un potenziale di corrispondenza migliore. Nel caso in cui le parole sono state aggiunte nel mezzo, diventa un po 'più difficile. Potresti considerare la possibilità di suddividere un nome in parole, verificando con Double Metaphone se c'è una parola nell'altra colonna che corrisponde e quindi raccogliere il conteggio complessivo delle corrispondenze con le parole, che ti diranno quanto sono vicine le due colonne.

Vorrei anche filtrare parole comuni come Dr., Mr., Ms., Mrs., ecc., Prima di fare i confronti.

1

Ecco alcune opzioni:

algoritmi fonetici ...

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

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

Modifica Distanza (http://en.wikipedia.org/wiki/Levenshtein_distance)

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

Un'altra cosa che si potrebbe provare sarebbe quella di confrontare ogni parola (dividendo su spazio e forse trattino) con ogni parola nell'altro nome e vedere quante parole corrispondono. Forse combinare questo con gli algoritmi fonetici per una corrispondenza più sfocata. Per un enorme set di dati, dovresti indicizzare ogni parola e abbinarla con un nome id. Per la corrispondenza delle abbreviazioni è possibile confrontare solo la prima lettera. Probabilmente vuoi ignorare tutto tranne le lettere quando confronti anche le parole.

Molti degli algoritmi fonetici hanno open source/campioni online.

2

E 'un problema molto complesso - e ci sono un sacco di strumenti costosi per farlo correttamente.
Se vi siete mai chiesti il ​​motivo per cui non è possibile il check-in su un volo come Tom, Dick o Harry (o Bill)
Oppure, perché no-fly list e terroristi guardano liste non funzionano -Considerare:

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

E questa è solo l'ortografia ufficiale - non include errori di battitura!

+0

puoi fornire l'elenco o la fonte in cui trovare tali nomi? – bjan

1

Metaphone 3 è la terza generazione dell'algoritmo di Metaphone. aumenta l'accuratezza della codifica fonetica dal 89% di Double Metaphone al 98%, come testato con un database di più comuni parole in inglese, e nomi e le parole non in lingua inglese familiari in Nord America. Questo produce una codifica fonetica estremamente affidabile per le pronunce americane .

Metaphone 3 è stato progettato e sviluppato da Lawrence Philips, che progettato e sviluppato il originali algoritmi Metaphone e Double Metaphone .