匹配大型文本数据集 - 如何更快地完成?

时间:2015-03-30 21:54:21

标签: c# sql algorithm full-text-search sphinx

我正在努力工作几周,在逻辑和技术方面采取最佳方法,同时尝试以连续,旋转的方式匹配2大套文本。

一方面,我们有歌曲和歌词(大约30M行文本,每行约1000个字符),另一方面我们有歌词类别(大约20K,每个约50个字符)。歌词类别指的是歌曲的内容。

每首歌应该被分配到一个或多个类别,以及我看到它的方式,这只能通过比较每个类别中的单词的相关性与歌曲的歌词来完成,其次是选择具有最大全文搜索分数的分数(或者对于那些具有相同最大分数的分类,选择超过1个分类),考虑同义词,词干,停用词以及适当的全文搜索引擎的所有铃声和口哨声。如果你有更好的方法来解决这个问题,请不要犹豫,给我一个提示。

作为一个假设的例子,根据它的歌词,歌曲" Unchained Melody"应该去类别:

  • 情歌
    • 亲爱的,亲爱的
      • 感到孤独

它的歌词确实包含了类别(其整个路径)中包含的所有这些词,包括它们的变形和同义词,多次,因此该类别的文本应该与歌曲的文本相当。 / p>

所以问题是使用哪种方法将所有这些类别文本与所有这些歌曲文本进行匹配?

请记住,当然,如今每天都会发布数千首歌曲,即使有机会,这些类别也会不断变化/改善。

到目前为止,我已尝试过以下方法:

  1. 包含类别的SQL Server 2014,链接到Sphinx搜索引擎,该搜索引擎在其全文索引中保存歌词文本。构建在这些上面的应用程序对单个歌曲文本执行20K查询(即,获得每个类别与歌曲文本的相关性),选择排名最佳的结果。这意味着20K * 30M查询所有要匹配的歌曲。当然,这需要40个核心机器+ 256 GB RAM的年龄,到那时,有新的歌曲和可能的类别更改/更新结构。

  2. 这个很有趣:SQL Server 2014包含歌词,链接到保存类别文本的Sphinx。通过将歌曲文本分成单词来创建匹配每首歌曲的类别的查询,其中" OR"如果在一行中找到更多的单词(包含类别文本和来自其完整路径的文本),则结果排名更高。结果是:速度更快,因为每首歌只有一个大查询才能获得排名靠前的类别,但仍然不够快,而且准确度稍差。

  3. SQL Server 2014同时包含歌词和类别,启用了全文搜索,同时在一组有限的类别中使用第一种方法(没有Sphinx,只有SQL&#FT;)最初来自第二种方法(再次,没有Sphinx,只有SQL的FT),所有内容都分成数百个异步批处理工作。所以,它是上述两者的组合。结果:更准确,并且给它充分的力量,更快一点,但仍然不够,因为我觉得它可能。匹配所有歌曲和歌词大约需要3天。

  4. 如果您有任何其他想法我可以尝试,我会非常感激。我对准确性(40%)和速度(60%)感兴趣,我真的觉得有更简单的方法来完成这项工作。

1 个答案:

答案 0 :(得分:2)

就我个人而言,我可能会坚持你的1.但有两个改进

批量更新,而只是为每个类别/文档组合运行一个查询。每个类别运行一个查询 - 并获取所有文档的结果。更少的查询。您可以通过优化来使这些“大”查询更有效率。

Delta Updates ,而不是每个时段,只运行“完整”流程,定期使用单独的小型和特定系统。知道如何运行更集中的更新以避免重复工作的人。例如:

  1. 在添加新类别时,可以运行其大查询来查找该类别的文档。删除的类别只是删除记录。对类别的“编辑”可以是删除后跟插入。

  2. 新文档也可能是一个特殊的sphinx索引,它只包含新文档(主要的+ delta索引系统可能已经提供了这个!)。然后针对这个小得多的delta索引运行每个类别的主查询。

  3. 甚至可能使用“推测”系统来减少您需要运行的类别数量。例如,将类别中的所有单词塞入批量BuildKeyword调用。这可以让你恢复每个单词的命中率,这样就可以排除没有匹配的类别(所以不需要为许多类别运行主查询)
  4. ......更聪明,更努力地工作