我正在尝试清理多年来获得许多重复记录的数据库,名称略有不同。例如,在公司表中,有“Some Company Limited”和“SOME COMPANY LTD!”等名称。
我的计划是将违规表格导出为R,将名称转换为小写,替换常用同义词(如“limited” - >“ltd”),删除非字母字符,然后使用agrep
看看看起来很相似。
我的第一个问题是agrep
只接受一个匹配的模式,并且循环每个公司名称以匹配其他公司名称的速度很慢。 (有些待清理的表会有数十个,可能有数十万个要检查的名称。)
我已经非常简短地查看了tm
包(JSS article),它看起来非常强大,但它主要用于分析大块文本,而不仅仅是名称。
我有一些相关的问题:
tm
包是否适合此类任务?
agrep
是否有更快的替代方案? (所述功能使用
Levenshtein编辑距离很慢。)
除了agrep
和tm
之外,R还有其他合适的工具吗?
我是否应该在R中这样做,或者应该是这样的事情 直接在数据库中完成? (这是一个Access数据库,所以我会 如果可能的话,避免接触它。)
答案 0 :(得分:33)
如果您只是做一些格式相对较好的小批量,那么RecordLinkage
package中的compare.linkage()
或compare.dedup()
函数应该是一个很好的起点。但如果你有大批量,那么你可能不得不做更多的修修补补。
我使用jarowinkler()
中的函数levenshteinSim()
,soundex()
和RecordLinkage
编写我自己的函数,使用我自己的加权方案(也就是说,你也是不能将soundex()
用于RecordLinkage
的大数据集。
如果我有两个我想要匹配的名单(“记录链接”),那么我通常将两者都转换为小写并删除所有标点符号。为了照顾“限制”与“LTD”,我通常会从每个列表中创建第一个单词的另一个向量,这允许对第一个单词进行额外加权。如果我认为一个列表可能包含首字母缩略词(可能是ATT或IBM),那么我将首字母缩略词 - 另一个列表。对于每个列表,我最终得到了一个字符串数据框,我希望将其作为MySQL数据库中的单独表进行比较。
所以我最终没有太多候选人,我LEFT OUTER JOIN
这两个表在有的东西上匹配两个列表(也许这是每个列表中的前三个字母或前三个字母和首字母缩写词中的前三个字母)。然后我使用上述函数计算匹配分数。
你仍然需要进行大量的人工检查,但你可以对分数进行排序,以便快速排除不匹配。
答案 1 :(得分:9)
也许google refine可以提供帮助。如果你有很多例外而且你还不知道它们,它看起来可能更合适。
答案 2 :(得分:6)
你正在做的事情被称为record linkage,这已经是几十年来一直是一个巨大的研究领域。幸运的是,有一大堆工具可以为这类东西做好准备。基本上,您可以将它们指向您的数据库,设置一些清洁和比较器(如Levenshtein或Jaro-Winkler或......),然后它们就会为您完成工作。
这些工具通常具有解决性能问题的功能,因此即使Levenshtein很慢,它们也可以快速运行,因为大多数记录对从未进行过比较。
上面的Wikipedia链接提供了许多可以使用的记录链接工具的链接。我亲自在Java中编写了一个名为Duke的程序,我已成功使用它。如果您想要大而且昂贵的东西,您可以购买主数据管理工具。
答案 3 :(得分:0)
在您的情况下,编辑距离计算可能会起作用,但如果您需要在较大的基于文本的文档中找到近似重复项,则可以尝试 http://www.softcorporation.com/products/neardup/