Appariement des enregistrements en fonction du nom de la personne

y a-t-il des outils ou des méthodes qui peuvent être utilisés pour apparier le nom d'une personne entre deux sources de données différentes?

les systèmes n'ont pas d'autres renseignements communs et les noms ont été entrés différemment dans de nombreux cas.

Exemples de non-correspondances exactes:

King Jr., Martin Luther = King, Martin (exclude suffix)

Erving, le Dr J. = Erving, J. (à l'exclusion de préfixe)

Obama, Barak Hussein = Obama, Barak (exclu moyen nom)

Pufnstuf, H. R. = Pufnstuf, Haibane Renmei (match abbreviations)

Tankengine, Thomas = Tankengine, Tom (match common nicknames)

Flair, Rick "la Natureboy" = Flair, Natureboy (match sur le pseudo)

16
demandé sur Brian Tompsett - 汤莱恩 2009-06-12 21:48:17

5 réponses

j'ai dû utiliser une variété de techniques suggérées. Merci de me pointer dans la bonne direction(s). J'espère que la suite va aider quelqu'un d'autre avec ce type de problème à résoudre.

suppression des caractères en excès

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

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

    RETURN @String

END

Utilisation:

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

Split nom dans les pièces

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

Utilisation:

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

Commune surnoms:

j'ai créé une table basée sur cette liste et l'a utilisé pour se joindre à nom commun équivalents.

Utilisation:

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

algorithmes phonétiques (Jaro Winkler):

L'incroyable article, Beyond SoundEx-Functions for Fuzzy search in MS SQL Server, montre comment installer et utiliser le SimMetrics bibliothèque dans le serveur SQL. Cette bibliothèque vous permet de trouver une similitude relative entre les cordes et comprend de nombreux algorithmes. J'ai fini le plus souvent en utilisant Jaro Winkler pour faire correspondre les noms.

Utilisation:

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))
14
répondu Even Mien 2009-06-19 16:37:38

C'est un problème très complexe, et il ya beaucoup d'outils coûteux de le faire correctement.

Si vous vous demandez pourquoi vous ne pouvez pas enregistrer sur un vol comme Tom, Dick ou Harry (ou Bill)

Ou pourquoi pas-listes d'interdiction de vol et des terroristes, des listes de surveillance ne fonctionnent pas -de considérer que:

(1) Mouammar Kadhafi

(2) Mouammar Kadhafi!--1-->
(3) Muammar Kaddafi--1-->
(4) Mouammar Kadhafi--1-->
(5) Moammar El Kadhafi--1-->
(6) Mouammar Gadafi

(7) mouammar al-Qadafi

(8) Moamer El Kazzafi

(9) Moamar al-Kadhafi--1-->
(10) mouammar Al Qathafi

(11) Muammar Al Qathafi

(12) Mouammar El-Kadhafi!--1-->
(13) Moamar El Kadhafi--1-->
(14) Mouammar Kadhafi--1-->
(15) mouammar al-Qadhdhafi

(16) mouammar Qadafi

(17) Moamar Kadhafi!--1-->
(18) mouammar Qadhdhafi

(19) Muammar Khaddafi!--1-->
(20) Mouammar Khaddafi

(21) Mou'amar al-Kadafi--1-->
(22) Muammar Ghaddafy--1-->
(23) Mouammar Ghadafi

(24) Mouammar Kadhafi--1-->
(25) Muamar Kaddafi!--1-->
(26) Muammar Quathafi!--1-->
(27) Muammar Gheddafi!--1-->
(28) Muamar Al-Kaddafi--1-->
(29) Moammar Khadafy--1-->
(30) Moammar Qudhafi!--1-->
(31) mouammar al-Kadhafi

(32) Mulazim Awwal Mu'mamar Muhammad Abu Minyar al-Kadhafi

et c'est juste l'orthographe officielle - il n'inclut pas les fautes de frappe!

2
répondu Martin Beckett 2010-07-22 20:21:01

j'emploie souvent des algorithmes de type soundex pour ce type de situation. Essayez l' Double Métaphone algorithme. Si vous utilisez SQL Server, il y a du code source pour créer une fonction définie par l'utilisateur.

parce que vous avez transposé des données, vous pouvez vouloir les normaliser un peu, par exemple, supprimer toutes les virgules et trier les mots résultants par première lettre. Que vous donnera une meilleure correspondance potentiel. Dans le cas où des mots ont été ajoutés au milieu, il obtient un peu plus en plus dure. Vous pourriez envisager de briser un nom en mots, vérifier avec une double Métaphone s'il y a un mot dans l'autre colonne qui correspond, et puis recueillir le nombre total de correspondances contre des mots, qui vous indiquera à quel point les deux colonnes sont proches.

je voudrais aussi filtrer les mots courants comme Dr, M., Mme, Mme, etc. avant de faire les comparaisons.

1
répondu RedFilter 2009-06-12 17:50:15

Voici quelques options:

algorithmes phonétiques...

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

Double Métaphone (http://en.wikipedia.org/wiki/Double_Metaphone)

Editer Distance (http://en.wikipedia.org/wiki/Levenshtein_distance)

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

autre chose vous pourrait essayer serait de comparer chaque mot (se divisant sur l'espace et peut-être tiret) avec chaque mot dans l'autre nom et de voir combien de mots correspondent. Peut-être combiner cela avec des algorithmes phonétiques pour une correspondance plus floue. Pour un ensemble de données énorme, vous voudriez indexer chaque mot et l'assortir avec un id de nom. Pour l'abréviation correspondant vous pourriez comparer juste la première lettre. Vous voulez probablement ignorer tout mais des lettres lorsque vous comparez des mots.

beaucoup d'algorithmes phonétiques ont open source / échantillons en ligne.

1
répondu jjxtra 2009-06-13 16:54:07

Métaphone 3 c'est la troisième génération de l'algorithme Metaphone. Il augmente la précision de l'encodage phonétique à partir des 89% de Double Metaphone 98%, testé par rapport à une base de données des plus communs Mots anglais, et noms et mots non anglais familiers dans le Nord Amérique. Ceci produit un encodage phonétique extrêmement fiable pour American prononciations.

La Métaphone 3 a été conçue et développée par Lawrence Philips, qui a conçu et développé la Métaphone originale et la double Métaphone algorithme.

1
répondu bjan 2013-02-06 04:43:17