查找近似重复记录的技术

Ric*_*ton 46 duplicate-data r duplicate-removal fuzzy-comparison

我正在尝试清理一个数据库,这些数据库多年来获得了许多重复记录,名称略有不同.例如,在公司表中,有"Some Company Limited"和"SOME COMPANY LTD!"等名称.

我的计划是将违规表导出为R,将名称转换为小写,替换常见的同义词(如"limited" - >"ltd"),删除非字母字符然后agrep用来查看看起来相似的内容.

我的第一个问题是agrep只接受一个匹配的模式,并且循环每个公司名称以匹配其他公司名称的速度很慢.(有些待清理的表会有数十个,可能有数十万个要检查的名称.)

我已经非常简要地看了一下这个tm包(JSS文章),它看起来非常强大,但它主要用于分析大块文本,而不仅仅是名称.

我有一些相关的问题:

  1. tm包是否适合这类任务?

  2. 有更快的替代方案agrep吗?(所述函数使用Levenshtein编辑距离,传闻速度慢.)

  3. R中还有其他合适的工具,除了agreptm

  4. 我是否应该在R中执行此操作,还是应该直接在数据库中执行此类操作?(这是一个Access数据库,所以如果可能,我宁愿避免触摸它.)

Ric*_*ron 34

如果你只是做一些相对良好的小批量生产,那么包装中compare.linkage()或者compare.dedup()功能应该是一个很好的起点.但如果你有大批量,那么你可能不得不做更多的修修补补.RecordLinkage

我使用的功能jarowinkler(),levenshteinSim()以及soundex()RecordLinkage写我自己的函数,用我自己的权重方案(也,不如说是,你不能使用soundex()的大数据集RecordLinkage).

如果我有两个我想要匹配的名称列表("记录链接"),那么我通常将两者都转换为小写并删除所有标点符号.为了照顾"限制"与"LTD",我通常会从每个列表中创建第一个单词的另一个向量,这允许对第一个单词进行额外加权.如果我认为一个列表可能包含首字母缩略词(可能是ATT或IBM),那么我将首先简化其他列表.对于每个列表,我最终得到了一个字符串数据框,我想比较它在MySQL数据库中作为单独的表编写.

所以我最终没有太多的候选人,我LEFT OUTER JOIN这两个表必须在两个列表之间匹配(也许这是每个列表中的前三个字母或前三个字母和首字母缩略词中的前三个字母).然后我使用上述函数计算匹配分数.

您仍然需要进行大量的手动检查,但您可以对分数进行排序以快速排除不匹配.

  • +1用于解释如何规范化文本.所有经常被忽视的"第一步".tolower(),gsub().我通过查看摘要(as.factor(my_vector))并查看不匹配的内容来做类似的事情.有时它真的非常简单,写出这些线条可能比试图用正则表达式更加清晰. (5认同)
  • @AndrewMedico是的,看起来CRAN中的包不再有效.您可以从存档中获取以前的版本.我有义务成为包维护者吗? (2认同)

Eti*_*ine 9

也许谷歌精炼可能有所帮助.如果你有很多例外而且你还不知道它们,它看起来可能更合适.


lar*_*sga 6

你正在做的事情被称为记录联系,它已经是几十年来一个巨大的研究领域.幸运的是,有一大堆工具可以为这类东西做好准备.基本上,您可以将它们指向您的数据库,设置一些清洁和比较器(如Levenshtein或Jaro-Winkler或......),然后它们就会为您完成工作.

这些工具通常具有解决性能问题的特性,因此即使Levenshtein很慢,它们也可以快速运行,因为大多数记录对从未进行过比较.

上面的Wikipedia链接包含您可以使用的许多记录链接工具的链接.我亲自在Java中编写了一个名为Duke的程序,我已成功使用它.如果您想要大而且昂贵的东西,您可以购买主数据管理工具.