从不同(大)数据源查找类似记录的最快方法是什么

时间:2012-03-06 14:16:08

标签: architecture algorithm

我为一家拥有大量不同人口统计数据集的公共卫生机构工作 - 存储在SQL服务器,Access和Excel中。我编写了一个应用程序,允许人们根据不同的标准在这些数据集中找到“匹配”,并使用GUI进行设置。例如,一个'匹配'可能是两个数据集中的First,Last和DOB匹配 - 但SSN是'off by 1'(由Levenshtein算法确定)。

这些是大数据集。匹配标准可能变得非常复杂。现在,我通过将两个数据集拉入内存中的数据表然后逐行遍历第一个表并查看第二个表中是否存在匹配的任何行(使用LINQ)来查找匹配项。所以我的代码看起来像:

For each table1Row in TableOne/DatasourceOne
    table2Options=from l in table2rows where Levenshtein(table1Row.first, l.first)<2 //first name off by one            
    table2Options=from l in table2rows where Levenshtein(table1Row.last, l.last)<2 //last name off by one 
    if table2Options.count>1 then the row in table1 'matches' table 2      
Next 

代码生成正确的输出(找到匹配项),但它是SLOOOW。我知道一行一行应该更慢 - 但是使用LINQ来查找所有记录的速度甚至更慢。

From l in table1, k in table2 where Levenshtein(l.first, k.first)<2 and Levenshtein(l.last, k.last)<2 select l //this takes forever because it calculates the function for l rows * k rows 

有关如何更快地完成此核心匹配的任何想法?

4 个答案:

答案 0 :(得分:3)

如果FirstName不匹配,则添加和如果语句不检查LastName

99%的LastName都不匹配..所以你很少会对名字进行检查。 这将使您的处理时间缩短近一半。


你可以做的另一件事是添加更多规则,(当然你必须这样做,同时保持灌木意图完好无损)..例如:如果你添加规则来说“{{1的第一个字母必须匹配“,然后你可以先过滤,从而大大提高你的效率。

答案 1 :(得分:2)

Levenshtein的wikipedia article引用了一些可能有所帮助的改进。在您的情况下,由于您只对低于阈值的距离感兴趣,您应该注意,如果字符串大小相等(例如社会安全号码),则可以使用汉明距离代替。对于大小不等的字符串,您只需要在矩阵中计算2k + 1的对角条纹,其中k是您的阈值。

相互运行两个字符串列表应该能够在Levenshtein算法中提供一些优化。例如,比较以“a”开头的单词的替换将适用于以“a”开头的所有单词。我会看看我是否能够提出一种已经以这种方式优化的参考算法。

答案 2 :(得分:1)

您能将分析所需的所有数据带入内存,然后进行分析吗?我已经替换了这样的代码:

for each day in months:
     for each customer in customers:
          computed = computeSalesInDatabase(customer,day)
          saveComputed(computed)

使用这样的代码:

for each day in months:
     dailyData = getFullDay(day)
     for each customer in customers:
          computed = computeSalesInMemory(customer,day,dailyData)
          saveComputed(computed)

并且发现它更具高效性。

答案 3 :(得分:1)

我希望将其转向某种No-SQL类型的实现。您可能需要查看NoSQL and Linq上的这篇StackOverflow文章以获取更多信息。

如果您无法使用完整的NoSQL实现,那么您可能需要从中获取一些想法,例如使用键值对来形成数据之间的连接。