Question

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

Les systèmes ont pas d'autres informations communes et les noms ont été saisis différemment dans de nombreux cas.

Des exemples de correspondances non exactes:

King Jr., Martin Luther = King, Martin (exclure le suffixe)
Erving, le Dr J. = Erving, J. (préfixe exclure)
Obama, Barak Hussein Obama =, Barak (exclure le nom du milieu)
Pufnstuf, H.R. = Pufnstuf, Ailes Grises (abréviations match)
Tankengine, Thomas = Tankengine, Tom (match de surnoms communs)
Flair, Rick "le Natureboy" = Flair, Natureboy (match sur surnom)

Était-ce utile?

La solution

Je devais utiliser une variété de techniques proposées. Merci me pointant dans la bonne direction (s). Si tout va bien, ce qui suit vous aidera quelqu'un d'autre avec ce type de problème à résoudre.

Suppression de 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 ')  

nom de Split en parties

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

surnoms communs:

J'ai créé une table basée sur cette liste et l'a utilisé pour joindre le 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'article étonnant, Au-delà SoundEx - Fonctions pour la recherche floue dans MS SQL Server , montre comment installer et utiliser la bibliothèque SimMetrics dans SQL Server. Cette bibliothèque vous permet de trouver relative similitude entre les chaînes et comprend de nombreux algorithmes. J'ai fini par la plupart du temps 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))

Autres conseils

Il est un problème très complexe - et il y a beaucoup d'outils coûteux de le faire correctement
. Si vous jamais demandé pourquoi vous ne pouvez pas vérifier sur un vol comme Tom, Dick ou Harry (ou Bill)
Ou pourquoi pas-mouche des listes et des terroristes listes de surveillance ne fonctionnent pas -examiner:

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

Et c'est juste orthographes officielles - il ne comprend pas les fautes de frappe

Voici quelques options:

algorithmes phonétiques ...

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

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

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

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

Une autre chose que vous pourriez essayer serait de comparer chaque mot (fractionnement de l'espace et peut-être trait d'union) avec chaque mot dans l'autre nom et voir combien de mots correspondent. Peut-être combiner avec des algorithmes phonétiques pour la correspondance plus floue. Pour un vaste ensemble de données, vous voulez indexer chaque mot et correspondre avec un identifiant de nom. Pour abréviation vous pouvez comparer correspondant juste la première lettre. Vous voulez sans doute ignorer quoi que ce soit, mais des lettres lorsque vous comparez des mots aussi bien.

La plupart des algorithmes phonétiques ont open source / échantillons en ligne.

  

Metaphone 3 est la troisième génération de l'algorithme Metaphone.   Il augmente la précision du codage phonétique de 89% de Double   Metaphone 98% , tel que testé contre une base de données les plus courantes   mots anglais, et les noms et les mots non anglais familiers dans le Nord   Amérique. Cela produit un codage phonétique extrêmement fiable pour   prononciations américains.

     

Metaphone 3 a été conçu et développé par Lawrence Philips, qui   conçu et développé le Metaphone original et double Metaphone   algorithmes.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top