50

我正在尝试清理一个数据库,多年来,该数据库已获得许多重复记录,名称略有不同。例如,在公司表中,有“Some Company Limited”和“SOME COMPANY LTD!”之类的名称。

我的计划是将有问题的表格导出到 R 中,将名称转换为小写,替换常见的同义词(如“limited”->“ltd”),去掉非字母字符,然后使用agrep来查看看起来相似的内容。

我的第一个问题是agrep它只接受一个模式来匹配,并且循环遍历每个公司名称以匹配其他公司名称很慢。(某些要清理的表将有数万甚至数十万个名称要检查。)

我已经非常简要地查看了该tm包(JSS 文章),它看起来非常强大,但适用于分析大块文本,而不仅仅是名称。

我有几个相关的问题:

  1. tm软件包是否适合此类任务?

  2. 有更快的替代方案agrep吗?(所述功能使用 Levenshtein 编辑距离,这很慢。)

  3. 除了agrep和之外,R 中还有其他合适的工具tm吗?

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

4

4 回答 4

34

如果你只是在做小批量,格式相对较好,那么compare.linkage()中的orcompare.dedup()函数应该是一个很好的起点。但是如果你有大批量,那么你可能需要做更多的修补。RecordLinkage

我使用函数jarowinkler()levenshteinSim()soundex()inRecordLinkage来编写我自己的函数,这些函数使用我自己的加权方案(同样,您不能将soundex()用于大数据集RecordLinkage)。

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

所以我不会有太多的候选人,我LEFT OUTER JOIN把这两个表放在两个列表之间必须匹配的东西上也许是每个列表中的前三个字母或首字母缩写词中的前三个字母和前三个字母)。然后我使用上述函数计算匹配分数。

您仍然需要进行大量人工检查,但您可以根据分数进行排序以快速排除不匹配项。

于 2011-07-13T19:24:08.857 回答
9

也许谷歌细化可以提供帮助。如果你有很多例外并且你还不知道它们,它看起来可能更合适。

于 2011-07-14T03:31:13.127 回答
6

您所做的称为记录链接,几十年来它一直是一个巨大的研究领域。对你来说幸运的是,有一大堆工具可以为这类事情做好准备。基本上,您可以将它们指向您的数据库,设置一些清理和比较器(如 Levenshtein 或 Jaro-Winkler 或...),它们会为您完成工作。

这些工具通常具有解决性能问题的功能,因此即使 Levenshtein 速度很慢,它们也可以快速运行,因为大多数记录对根本不会进行比较。

上面的 Wikipedia 链接包含指向您可以使用的许多记录链接工具的链接。我个人用 Java 编写了一个名为Duke的程序,我已经成功地用于此目的。如果您想要大而昂贵的东西,您可以购买主数据管理工具。

于 2012-09-26T08:37:19.603 回答
0

在您的情况下,编辑距离计算之类的方法可能会起作用,但是如果您需要在较大的基于文本的文档中找到附近的重复项,您可以尝试 http://www.softcorporation.com/products/neardup/

于 2013-04-07T10:54:13.287 回答