Соответствующие записи основаны на имени человека - PullRequest
16 голосов
/ 12 июня 2009

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

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

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

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

Ответы [ 5 ]

14 голосов
/ 19 июня 2009

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

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

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

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

В удивительной статье 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 голосов
/ 31 марта 2010

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

(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) Мулазим Аввал Муаммар Мухаммад Абу Миньяр Каддафи

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

1 голос
/ 06 февраля 2013

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

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

1 голос
/ 12 июня 2009

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

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

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)

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

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

1 голос
/ 12 июня 2009

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

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

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

...