我有两个名字和一个地址的'记录'(基本上是CSV字符串)。我需要找到彼此相似的记录:基本上,名称和地址部分都看起来“相似”,好像它们是由人类解释的。
我使用了这篇优秀博客文章中的想法:http://knol.google.com/k/simple-simhashing#来编写一个简单的SimHash。如果两个或多个字符串的SimHash结果相同,我将该子集的所有记录传递给细粒度匹配程序,该程序为O(n ^ 2),它将该集的每个记录与每个其他记录进行比较。 / p>
对于SimHash部分,我有参数,我可以定义数据报大小(基本上是字符串大小为n的滑动窗口)和用于确定需要使用多少(随机)哈希的迭代次数SimHash计算。到目前为止,数据报大小为4并使用4个哈希来计算SimHash。我尝试过各种其他组合,但到目前为止这个组合效果最好。
我遇到的问题是这个方法在我拥有的数据集中找到了大约80%的重复项。我知道这是因为我已经验证了整个数据集与上面提到的缓慢的O(n ^ 2)完全匹配。对于小于10 ^ 4的数据集,O(n ^ 2)匹配器是可以的,但很快变得不可行,因为我需要运行大小为10 ^ 8的集合。
关于如何提高SimHash准确性的任何想法,建议或想法,以便更多的“相似”记录被标记为相同的SimHash数字?
编辑: 在SimHashing之前,我将所有![0-9A-Z]字符大写并删除。 应该匹配的事例(拼写错误是有意的):
这里1和2相似,3不是。输出应为:1 + 2
答案 0 :(得分:3)
在您试图想要改变sim哈希值之前,您是否尝试过针对该问题应用特定于域的知识?
您的算法是否有错过的对列表?他们有什么共同点吗?
您是否尝试过删除大写字母,将昵称转换为全名,删除中间名,扩展N,E,S,W以及北,南,东,西,扩展到街道等等?
答案 1 :(得分:0)
Simhash不适用于此目的,因为它仅适用于近重复检测,在这种检测中,差异很小,特征的大部分相同。请参阅我在simhash and solving the hamming distance problem上的教程。
更好的方法是minhash, possibly with LSH。看来,最好将用于散列的功能生成为字符的带状疱疹(长度可能为4),而不是 words 的带状疱疹。
鉴于此类短文本字段,并且鉴于单词顺序可能不太可能发生太大变化,因此您还应考虑包括终止带状疱疹:从文本字段开始和结尾的带状疱疹包含少于正常字符数,加上终止标记。这倾向于对短文本(例如,英文)的拼写差异更宽容。不终止带状疱疹的“ Whitmore”和“ Whitemore”会产生
[WHIT,HITM,ITMO,TMOR,更多] 和 [WHIT,HITE,ITEM,TEMO,EMOR,更多] Jaccard相似度低至2/9的人;
而包括终止带状疱疹将产生
[#W,#WH,#WHI,WHIT,HITM,ITMO,TMOR,MORE,ORE#,RE#,E#] 和 [#W,#WH,#WHI,WHIT,HITE,ITEM,TEMO,EMOR,MORE,ORE#,RE#,E#] 具有较高的Jaccard相似度8/15;
Rob Neuhaus关于预规范化的建议非常明智。我会将长形式的单词归一化为缩写形式(例如,“圣詹姆斯街”会归一化为“ ST JAMES ST”)。使用有时不明确的缩写(“ St”->“ STREET”或“ SAINT”?)可能难以在另一个方向上进行归一化,而且缩写形式有助于减少带状疱疹,因此对整体相似性的影响较小,这就是很好,因为人们经常将“ Road”键入“ Street”等,并且并没有太大的含义。