多对多并编写半智能匹配算法

时间:2009-10-15 18:07:12

标签: mysql ruby-on-rails ruby algorithm search

我正在学习使用Ruby on Rails进行编程,但我已经完成了最艰巨的任务。我有两张桌子,每张桌子都有一份商业类别清单(I.E. Thai Food Restaurant,Plumber,Office Supply Store)。这两个表来自两个不同的API,我基本上充当它们之间的中间人。他们列出或多或少相同类别的类别,但通常他们会用不同的方式表达它们(I.E.汽车车身修理和绘画VS汽车车身修理和绘画)。

我的第一个目标是为此任务设计模型。我决定“多对多”并通过手动映射两行来测试它。 完成。测试。真棒。

我的第二个目标是编写一个算法来匹配两个表中的行,并根据相似性给出优先级。我猜测很多工作都可以在MySQL中完成。到目前为止,这是我的伪代码:

for each row in table 1
    split phrase up into words by spaces

    SELECT name, id FROM joined_table
        SELECT name, id FROM table2 AS word1 WHERE name LIKE '% word1 %'
        SELECT name, id FROM table2 AS word2 WHERE name LIKE '% word2 %'
        SELECT name, id FROM table2 AS word3 WHERE name LIKE '% word3 %'
        JOIN word1, word2, word3 WHERE word1.id == word2.id 
                                    OR word2.id == word3.id
        order by count of matches of each word

    insert relationships into map table
end

我以前从未设计过搜索算法,因此您可以提供的任何帮助都非常感谢。我很高兴搞清楚这一点,但我想我会伸手向专业人士那里寻求建议。

干杯!

更新:一位同事建议我查看一个名为mechanical turk的网站,该网站是最具成本效益的地图分类方式。我所要做的就是建立一个简单的表格,每千场比赛的成本约为3.00美元。

2 个答案:

答案 0 :(得分:0)

你不应该这样做。

更好的方法是规范化您的数据,然后简单地匹配

如果“auto”==“auto”,则将所有“汽车”改为“汽车”。就像你将所有东西从混合大小写转换为大写或小写一样。

存储实际值,“规范化”数据并存储,然后您可以匹配标准化数据。

这也允许您拥有比SQL中可用的“任意”复杂的规范化规则,并且您只运行一次,而不是每次查询。

编辑 - 发表评论。

那么这个怎么样。

我仍然认为你可以通过大量的工作来规范它。有些工作,是的,但不是很大。

运行所有数据,并进行一些基本的自由格式文本处理。规范化案例,阻止,抛出“无趣”的话语,或者在他们被召唤时“停止”单词。您可以在网上找到此类处理的基础知识。这并不困难。

最后,您将获得文字的唯一字词列表。你应该扫描这个列表,毫无疑问你会发现你可能想要删除的其他单词作为“停止”单词。如果您找到一些“明显的”同义词,您可以将同义词映射作为规范化过程的一部分。由你决定。最终可能不会有疯狂的“有趣”字样。

此时要做的一件好事是创建一个倒排索引表。例如,如果您有3个带有“auto”一词的条目,则在倒排索引表中有3行:

"auto", 123
"auto", 456
"auto", 789

如果您想查找哪些行具有“自动”,请加入该索引表。

现在,您正在遍历数据集。

使用上述技术转换文本,即标准化文本,现在有一个“有趣”单词列表。

使用反向索引查找甚至是匹配的潜在候选者的所有符合条件的行,即所有在“有趣”列表中至少包含一个词的行。

最后,你然后规范化这些行的文本,做一组有趣的单词与他们有趣的单词的交集。这为您提供了匹配单词的数量。然后,您可以像“匹配单词数/候选单词数”一样简单地执行基本百分比评估。

你可以看到,你可以动态地做一些这样的处理,你可以存储很多中间结果(比如规范化的文本),或者只是采取高于阈值的行(比如说,75%得分) ,并将它们粘在你的加入表中。

此外,这项工作可以迭代完成。您不必再次重新处理整个数据集。

当你得到一个新行时,找到那些有共享单词的行,然后重新调整它们以及新的行。删除行时,只需删除反向索引条目以及您的连接条目。更新行时,只需先“删除”它,然后再“添加”它。 (即删除所有旧关系,然后重新更新已更新的行和具有共享单词的行。)

最后应该很快。

答案 1 :(得分:0)

没有完整的答案,有建议。

如果我理解你要做什么,我认为完全自动化可能很难。

如果数据集各有“1%的奇怪”,那么您可能需要几百个手动映射。

从一开始,假设一些匹配很容易,一些很难,并且需要一些规则。

您的第一条规则可能是“确切的词组匹配匹配”,也许您描述的“最大匹配字数”规则可能是第二条规则。但是你可能会有一些错误的比赛。在你引用的例子中,不匹配的词 - 汽车与汽车 - 是实现匹配的关键。

你需要有一些方法来处理另一方没有等价物的类别,这肯定会在一套15K中。

当您获得数据更新时,请比较新旧,并仅处理更改 - 最小化工作。