Сопоставление записей на основе Имени пользователя

StackOverflow https://stackoverflow.com/questions/988050

Вопрос

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

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

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

Кинг-младший, Мартин Лютер = Кинг, Мартин (исключить суффикс)
Эрвинг, доктор медицинских наукJ.= Эрвинг, Дж.(исключить префикс)
Обама, Барак Хусейн = Обама, Барак (исключить второе имя)
Пуфнштуф, Х.Р.= Pufnstuf, Хайбанэ Ренмэй (соответствующие сокращения)
Танкинжайн, Томас = Танкинжайн, Том (соответствуют распространенным прозвищам)
Флэр, Рик "Мальчик-натура" = Флэр, Мальчик-Натура (совпадает по прозвищу)

Это было полезно?

Решение

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

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

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

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

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

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

Замечательная статья, За пределами SoundEx — функции нечеткого поиска в MS SQL Server, показывает, как установить и использовать СимМетрикс библиотеку в SQL Server.Эта библиотека позволяет находить относительное сходство между строками и включает в себя множество алгоритмов.В итоге я в основном использовал Яро Винклер чтобы имена соответствовали.

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

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

Другие советы

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

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

И это только официальное написание, без опечаток!

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

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

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

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

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

Саундекс (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)

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top