Coincidencia de registros basado en Nombre de la persona
-
13-09-2019 - |
Pregunta
¿Hay herramientas o métodos que se pueden utilizar para la coincidencia de nombre de una persona entre dos fuentes de datos diferentes?
Los sistemas no tienen otra información común y los nombres se han introducido de forma diferente en muchos casos.
Ejemplos de partidos no exactas:
King, Martin Luther = King, Martin (excluir sufijo)
Erving, Dr. J. = Erving, J. (excluir prefijo)
Obama, Barak Hussein Obama =, Barak (excluir segundo nombre)
Pufnstuf, H. R. = Pufnstuf, Haibane Renmei (siglas de partido)
Tankengine, Thomas = Tankengine, Tom (partido de apodos comunes)
Estilo, Rick "el Natureboy" = estilo, Natureboy (partido en el apodo)
Solución
he tenido que usar una variedad de técnicas sugeridas. Gracias me apunta en la dirección (s) derecha. Con suerte, el siguiente le ayudará a otra persona con este tipo de problema a resolver.
La eliminación de exceso de caracteres
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
Uso:
--remove all non-alphanumeric and non-white space
dbo.fn_StripCharacters(@Value, , '^a-z^0-9 ')
nombre Dividir en partes
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
Los apodos comunes:
He creado una tabla basada en esta lista y lo utilizó para unirse en el nombre común equivalentes.
Uso:
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
algoritmos fonéticos (Jaro Winkler):
El artículo increíble, Más allá SoundEx - Funciones para la búsqueda difusa en MS SQL Server , se muestra cómo instalar y utilizar la biblioteca SimMetrics en SQL Server. Esta biblioteca le permite encontrar relativa similitud entre las cuerdas e incluye numerosos algoritmos. Terminé en su mayoría utilizando Jaro Winkler para coincidir con los nombres.
Uso:
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))
Otros consejos
Es un problema muy complejo - y hay una gran cantidad de herramientas costosas para hacerlo correctamente
.
Si alguna vez se preguntó por qué no se puede comprobar en un vuelo como Tom, Dick o Harry (o Bill)
O por qué no hay listas de exclusión aérea y terroristas listas de vigilancia no funcionan -Considere:
(1) Muammar Gadafi
(2) Mo'ammar Gadafi
(3) Muamar Gadafi
(4) Muamar Gadafi
(5) El Muamar Kadhafi
(6) Muamar Gadafi
(7) Muamar al Qadafi
(8) El Muamar Kazzafi
(9) Moamar al-Gaddafi
(10) Muamar al Qathafi
(11) Muammar Al Qathafi
(12) Mo'ammar el-Gadafi
(13) El Moamar Kadhafi
(14) Muammar al-Qadhafi
(15) Muamar al Qadhdhafi
(16) Muamar Qadafi
(17) Moamar Gadafi
(18) Muamar Qadhdhafi
(19) Muamar Gadafi
(20) Muammar al-Khaddafi
(21) Mu'amar al-Kadafi
(22) Muammar Ghaddafy
(23) Muammar Ghadafi
(24) Muamar Gadafi
(25) Muamar Gadafi
(26) Muammar Quathafi
(27) Muamar Gadafi
(28) Muamar Al-Gadafi
(29) Moamar Gadafi
(30) Muamar Qudhafi
(31) Muamar al Gadafi
(32) Mulazim Awwal Muamar Muhammad Abu Minyar al-Qadhafi
Y eso es simplemente la ortografía oficiales - que no incluye errores ortográficos
a menudo emplean algoritmos de tipo soundex para este tipo de situación. Pruebe el algoritmo doble Metaphone . Si está utilizando SQL Server, hay algo de código fuente para crear una función definida por el usuario.
Debido a que usted ha transpuesto de datos, es posible que desee para normalizar un poco, por ejemplo, eliminar todas las comas y los que puedan resultar palabras por la primera letra. Eso le dará un cierto potencial mejor adecuación. En el caso en que las palabras se han añadido en el medio, se hace un poco más difícil. Se podría considerar dividir un nombre en palabras, comprobando con doble Metaphone si hay una palabra en la otra columna que corresponda, y luego recoger el recuento total de partidos vs. palabras, que le dirá qué tan cerca están las dos columnas.
Me gustaría también filtrar las palabras comunes como el Dr., Sr., Sra., Sra., Etc., antes de hacer las comparaciones.
Aquí están algunas opciones:
algoritmos fonéticos ...
Soundex ( http://en.wikipedia.org/wiki/Soundex )
Doble Metaphone ( http://en.wikipedia.org/wiki/Double_Metaphone )
Editar Distancia ( http://en.wikipedia.org/wiki/Levenshtein_distance )
Jaro-Winkler Distancia ( http://en.wikipedia.org/wiki/Jaro- Winkler_distance )
Otra cosa que podría intentar sería comparar cada palabra (división en el espacio y quizá guión) con cada palabra en el otro nombre y ver cuántas palabras coinciden. Tal vez combinar esto con algoritmos fonéticos para adecuación, más difusa. Para un gran conjunto de datos, que se desea indexar cada palabra y hacerla coincidir con un nombre de identificación. Para abreviatura juego se podría comparar sólo la primera letra. Es posible que desee hacer caso omiso de cualquier cosa menos cartas Cuando se comparan las palabras también.
Muchos de los algoritmos fonéticos tienen código abierto / muestras en línea.
Metaphone 3 es la tercera generación del algoritmo Metaphone. Aumenta la precisión de codificación fonética del 89% de Doble Metaphone a 98% , como prueba contra una base de datos de los más comunes las palabras en inglés, y los nombres y palabras no inglesas conocidas en el norte America. Esto produce una codificación fonética extremadamente fiable para pronunciaciones americanas.
Metaphone 3 fue diseñado y desarrollado por Lawrence Philips, quien diseñado y desarrollado el original Metaphone y doble Metaphone algoritmos.