是否有任何工具或方法可用于在两个不同数据源之间按人名匹配?
系统没有其他常见信息,并且在许多情况下输入的名称也不同。
非完全匹配的示例:
小王,马丁路德=国王,马丁(不包括后缀)答案 0 :(得分:14)
我不得不使用各种建议的技术。谢谢指出我正确的方向。希望以下内容可以帮助其他人解决这类问题。
删除多余字符
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展示了如何在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))
答案 1 :(得分:2)
这是一个非常复杂的问题 - 并且有很多昂贵的工具可以正确地完成它 如果你想知道为什么你不能像Tom,Dick或Harry(或Bill)那样登机 或者为什么禁飞名单和恐怖分子观察名单不起作用 - 考虑:
(1)Muammar Qaddafi
(2)Mo'ammar Gadhafi
(3)Muammar Kaddafi
(4)Muammar Qadhafi
(5)Moammar El Kadhafi
(6)Muammar Gadafi
(7)Mu'ammar al-Qadafi
(8)Moamer El Kazzafi
(9)Moamar al-Gaddafi
(10)Mu'ammar Al Qathafi
(11)Muammar Al Qathafi
(12)Mo'ammar el-Gadhafi
(13)Moamar El Kadhafi
(14)Muammar al-Qadhafi
(15)Mu'ammar al-Qadhdhafi
(16)Mu'ammar Qadafi
(17)Moamar Gaddafi
(18)Mu'ammar Qadhdhafi
(19)Muammar Khaddafi
(20)Muammar al-Khaddafi
(21)Mu'amar al-Kadafi
(22)Muammar Ghaddafy
(23)Muammar Ghadafi
(24)Muammar Ghaddafi
(25)Muamar Kaddafi
(26)Muammar Quathafi
(27)Muammar Gheddafi
(28)Muamar Al-Kaddafi
(29)Moammar Khadafy
(30)Moammar Qudhafi
(31)Mu'ammar al-Qaddafi
(32)Mulazim Awwal Mu'ammar Muhammad Abu Minyar al-Qadhafi
这只是官方拼写 - 它不包括拼写错误!
答案 2 :(得分:1)
我经常在这种情况下使用soundex类型的算法。试试Double Metaphone算法。如果您使用的是SQL Server,则可以使用一些源代码来创建用户定义的函数。
由于您已转换数据,因此您可能需要对其进行一些标准化,例如,删除所有逗号以及按首字母排序的结果。这将为您提供更好的匹配潜力。如果在中间添加了单词,则会变得更加困难。您可以考虑将名称分为单词,使用Double Metaphone检查其他列中是否有匹配的单词,然后收集匹配与单词的总数,这将告诉您两列的接近程度。
在进行比较之前,我还会过滤出博士,先生,女士,太太等常用词。
答案 3 :(得分:1)
以下是一些选项:
语音算法......
Soundex(http://en.wikipedia.org/wiki/Soundex)
Double Metaphone(http://en.wikipedia.org/wiki/Double_Metaphone)
修改距离(http://en.wikipedia.org/wiki/Levenshtein_distance)
Jaro-Winkler距离(http://en.wikipedia.org/wiki/Jaro-Winkler_distance)
你可以尝试的另一件事是将每个单词(在空格上分裂,也可能是连字符)与另一个名字中的每个单词进行比较,看看有多少单词匹配。也许将它与语音算法结合起来进行更多的模糊匹配。对于庞大的数据集,您可能希望索引每个单词并将其与名称ID匹配。对于缩写匹配,您可以只比较第一个字母。除了比较单词之外,你可能想要忽略除字母之外的任何内容。
许多语音算法都有在线开源/样本。
答案 4 :(得分:1)
Metaphone 3是Metaphone算法的第三代。 它从双倍的89%提高了语音编码的准确性 Metaphone要 98%,对最常见的数据库进行测试 北方熟悉的英语单词,名称和非英语单词 美国。这产生了非常可靠的语音编码 美国发音。
Metaphone 3由Lawrence Philips设计和开发 设计并开发了原版Metaphone和Double Metaphone 算法