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)
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))
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!
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.
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.
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.