Соответствие записей на основе имени лица

Существуют ли какие-либо инструменты или методы, которые могут использоваться для сопоставления имени человека между двумя разными источниками данных?

В системах нет другой общей информации, и во многих случаях имена были введены по-разному.

Примеры неточных совпадений:

Король-младший, Мартин Лютер = Король, Мартин (исключить суффикс)
Эрвинг, д-р Дж. = Эрвинг, Дж. (Исключить префикс)
Обама, Барак Хусейн = Обама, Барак (исключить второе имя)
Pufnstuf, H.R. = Pufnstuf, Haibane Renmei (аббревиатуры матчей)
Танкенгин, Томас = Танкенгин, Том (совпадение с обычными прозвищами)
Flair, Rick "The Natureboy" = Flair, Natureboy (матч по прозвищу)

Ответы

Ответ 1

Мне пришлось использовать различные методы. Спасибо, указывая мне в правильном направлении. Надеюсь, следующее поможет кому-то другому решить эту проблему.

Удаление лишних символов

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

Использование:

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

Разделить имя на части

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

Использование:

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

Общие псевдонимы:

Я создал таблицу на основе этот список и использовал ее для соединения с эквивалентами эквивалентных имен.

Использование:

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

Фонетические алгоритмы (Jaro Winkler):

Удивительная статья, Beyond SoundEx - функции для нечеткого поиска в MS SQL Server, показывает, как установить и использовать SimMetrics в SQL Server. Эта библиотека позволяет находить относительное сходство между строками и включает в себя множество алгоритмов. В итоге я в основном использовал Jaro Winkler для соответствия именам.

Использование:

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

Ответ 2

Это очень сложная проблема - и есть много дорогостоящих инструментов, чтобы сделать это правильно.
Если вы когда-нибудь задавались вопросом, почему вы не можете зарегистрироваться на рейс, как Том, Дик или Гарри (или Билл)
Или почему списки "не летают" и списки наблюдателей террористов не работают - учтите:

(1) Муамар Каддафи
(2) Моаммар Каддафи
(3) Муаммар Каддафи
(4) Муаммар Каддафи
(5) Moammar El Kadhafi
(6) Муаммар Гадафи
(7) Муаммар аль-Кадафи
(8) Моамер Эль Каззафи
(9) Моамар аль-Каддафи
(10) Муаммар Аль-Катхафи
(11) Муамар Аль-Катхафи
(12) Mo'ammar el-Gadhafi
(13) Моамар Эль Каддафи
(14) Муамар аль-Каддафи
(15) Муаммар аль-Каддхафи
(16) Муамар Кадафи
(17) Моамар Каддафи
(18) Муаммар Каддхафи
(19) Муаммар Хаддафи
(20) Муамар аль-Хаддафи
(21) Муамар аль-Кадафи
(22) Муаммар Каддафи
(23) Муамар Гадафи
(24) Муаммар Каддафи
(25) Муамар Каддафи
(26) Муамар Каатфи
(27) Муаммар Геддафи
(28) Муамар аль-Каддафи
(29) Муаммар Хадафи
(30) Муаммар Кудхафи
(31) Муаммар аль-Каддафи
(32) Мулазим Аввал Муаммар Мухаммад Абу Миняр аль-Каддафи

И это просто официальное написание - оно не включает опечатки!

Ответ 3

Я часто использую алгоритмы типа soundex для такого типа ситуации. Попробуйте алгоритм Double Metaphone. Если вы используете SQL Server, существует некоторый исходный код для создания пользовательской функции.

Поскольку у вас есть транспонированные данные, вы можете немного его нормализовать, например, удалить все запятые и сортировать полученные слова по первой букве. Это даст вам лучший потенциал для сопоставления. В случае, когда слова были добавлены посередине, он становится немного более жестким. Вы можете подумать о том, чтобы сломать имя в словах, проверяя с помощью Double Metaphone, есть ли в другом столбце, которое соответствует, а затем собирает общее количество совпадений против слов, что скажет вам, насколько близки два столбца.

Я также отфильтровал бы общие слова, такие как доктор, г-жа, г-жа, г-жа и т.д., прежде чем выполнять сравнения.

Ответ 4

Вот несколько вариантов:

Фонетические алгоритмы...

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

Двойной метафон (http://en.wikipedia.org/wiki/Double_Metaphone)

Изменить расстояние (http://en.wikipedia.org/wiki/Levenshtein_distance)

Расстояние Яро-Винклера (http://en.wikipedia.org/wiki/Jaro-Winkler_distance)

Еще одна вещь, которую вы могли бы попробовать, - сравнить каждое слово (разделение на пространство и, возможно, дефис), с каждым словом в другом имени и посмотреть, сколько слов соответствует. Возможно, комбинируйте это с фонетическими алгоритмами для более нечеткого соответствия. Для огромного набора данных вы хотите проиндексировать каждое слово и сопоставить его с идентификатором имени. Для сокращения аббревиатуры вы можете сравнить только первую букву. Вы, вероятно, хотите игнорировать все, кроме букв, при сравнении слов.

Многие из фонетических алгоритмов имеют открытые исходные коды/образцы в Интернете.

Ответ 5

Метафон 3 - это третье поколение алгоритма Metaphone. Это повышает точность фонетического кодирования из 89% Double Метафон до 98%, как проверено на базе базы данных наиболее распространенных Английские слова, имена и неанглийские слова, знакомые на Северном Америка. Это создает чрезвычайно надежное фонетическое кодирование для Американские произношения.

Метафон 3 был разработан и разработан Лоуренсом Филипсом, который разработал и разработал оригинальный Метафон и Двойной Метафон алгоритмы.