代码之家  ›  专栏  ›  技术社区  ›  Even Mien

基于人名的匹配记录

  •  16
  • Even Mien  · 技术社区  · 17 年前

    是否有任何工具或方法可用于在两个不同的数据源之间通过人名进行匹配?

    这些系统没有其他通用信息,在许多情况下输入的名称也不同。

    非精确匹配的示例:

    小金,马丁·路德=金,马丁(不包括后缀)

    奥巴马,巴拉克·侯赛因=奥巴马,巴拉克(不包括中间名)
    Pufnstuf,H.R.=Pufnstuf,Haibane Renmei(匹配缩写)

    天才,里克“自然男孩”=天才,自然男孩(绰号匹配)

    5 回复  |  直到 10 年前
        1
  •  15
  •   Even Mien    17 年前

    删除多余字符

    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
    

    常用昵称:

    this list 并将其用于连接通用名称等效项。

    用法:

    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 - Functions for Fuzzy Searching in MS SQL Server ,显示如何安装和使用 SimMetrics 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
  •  2
  •   Martin Beckett    16 年前

    这是一个非常复杂的问题,而且有很多昂贵的工具来正确地完成它。

    或者为什么禁飞名单和恐怖分子观察名单不起作用——考虑一下:

    (1) 穆阿迈尔·卡扎菲


    (4) 穆阿迈尔·卡扎菲
    (5) 摩阿迈尔·卡达菲


    (8) 穆阿默尔·卡扎菲
    (9) 卡扎菲
    (10) 穆阿迈尔·卡扎菲
    (11) 穆阿迈尔·卡扎菲
    (12) 穆阿迈尔·卡扎菲

    (14) 穆阿迈尔·卡扎菲
    (15) 穆阿迈尔·卡扎菲
    (16) 穆阿迈尔·卡扎菲
    (17) 穆阿马尔·卡扎菲
    (18) 穆阿迈尔·卡扎菲

    (20) 穆阿迈尔·哈达菲

    (22)穆阿迈尔·卡扎菲
    (23)穆阿迈尔·加达菲
    (24)穆阿迈尔·卡扎菲
    (25)穆阿马尔·卡达菲
    (26)穆阿迈尔·夸塔菲
    (27)穆阿迈尔·卡扎菲
    (28)穆阿马尔·卡达菲
    (29)穆阿迈尔·卡扎菲
    (30)Moammar Qudhafi

    (32)Mulazim Awwal Mu'ammar Muhammad Abu Minyar al-Qadhafi

    这只是官方拼写,不包括拼写错误!

        3
  •  1
  •   D'Arcy Rittich    17 年前

    对于这种情况,我经常使用soundex类型的算法。试试 Double Metaphone 算法。如果您使用的是SQL Server,则有一些源代码可用于创建用户定义的函数。

    因为您已经转置了数据,所以可能需要对其进行一点规范化,例如,删除所有逗号并按第一个字母对结果字进行排序。这将给你一些更好的匹配潜力。在中间添加了单词的情况下,它变得更难了。你可以考虑把名字分解成单词,用双隐喻检查是否有一个单词在另一个列中匹配,然后收集匹配项与单词的总体计数,这将告诉你这两个列有多接近。

    在进行比较之前,我还会过滤掉常见的单词,如Dr.,Mr.,Ms.,Mrs.,等等。

        4
  •  1
  •   jjxtra    17 年前

    语音算法。。。

    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 )

    你可以尝试的另一件事是将每个单词(空格分隔,可能连字符)与另一个名字中的每个单词进行比较,看看有多少单词匹配。也许可以结合语音算法进行更多的模糊匹配。对于一个庞大的数据集,您可能需要索引每个单词并将其与名称id匹配。对于缩写匹配,您可以只比较第一个字母。当你比较单词时,你可能想忽略除了字母以外的任何东西。

    许多语音算法都有在线开源/示例。

        5
  •  1
  •   bjan    13 年前

    Metaphone 3 是第三代的变音算法。 它将语音编码的准确率从双精度的89%提高到了89% 变音到 98% ,根据最常见的 英语单词,以及在北方熟悉的名称和非英语单词 美国这产生了一个非常可靠的语音编码

    Metaphone 3由Lawrence Philips设计和开发 算法。

    推荐文章