algorithm - 使用 ElasticSearch 进行模糊重复搜索
问题描述
我有一个相当大的N
文档数据集,其中只有不到 1% 是我想要识别的近乎重复的。我有很多数字字段和一些文本字段。如果...,我认为数据集中的两个文档关闭
- 除了一个、两个或三个数据字段外,所有数据字段都完全相同。
- 两个文档的相应文本字段只需进行几次编辑(即 ElasticSearch 使用的Levensthein 距离)。
您将如何应对使用 ElasticSearch 识别模糊重复项的挑战?
我已经很难为第 (1) 部分编写一个(通用)ElasticSearch 查询,它没有明确使用字段名称。我真的必须构建以下模式的巨大查询,还是有更聪明的方法?
( SELECT * FROM MessyData AS T1
JOIN MessyData AS T2
WHERE T1.F1 != T1.F1 AND T1.F2 = T2.F2 AND T1.F3 = T2.F3 AND ... )
UNION ALL
( SELECT * FROM MessyData AS T1
JOIN MessyData AS T2
WHERE T1.F1 = T1.F1 AND T1.F2 != T2.F2 AND T1.F3 = T2.F3 AND ... )
UNION ALL
( SELECT * FROM MessyData AS T1
JOIN MessyData AS T2
WHERE T1.F1 = T1.F1 AND T1.F2 = T2.F2 AND T1.F3 != T2.F3 AND ... )
UNION ALL
( ... )
注意:我使用 SQL 伪代码来说明我对除一个字段之外的所有字段都相同的情况的含义。F
代表字段,T
代表表,但它将是 ElasticSearch 中的索引。
计算树状图或使用另一种相似性度量来比较每个文档,每个文档都给了我计算工作量,N·(N-1)
因此是不可行的。
对于问题的第二部分,我正在考虑的方法是用m
测试文档(m
比 小得多N
)探测我的数据集,将 ElasticSearch 的所有m
查询得分相加。这会给我 O(m·N) 作为计算工作量,但我仍然必须对所有N
分数总和进行排序,至少部分排序,或者在运行中排序。
除了这个问题,More Like This
还有其他算法吗?Fuzzy Query
也感谢科学论文的链接!
参考
- https://en.wikipedia.org/wiki/Data_deduplication只是作为介绍
- https://discuss.elastic.co/t/finding-documents--almost--the-same/66089/2
- https://discuss.elastic.co/t/using-fuzzy-query-to-find-near-duplicates/39075 - 论坛上的一个问题没有任何答案
- https://www.compose.com/articles/how-scoring-works-in-elasticsearch/
- https://betterexplained.com/articles/sorting-algorithms/了解不同标准搜索算法的顺序
解决方案
我建议将您的字段分为 4 组的快速而肮脏的方法。计算每组字段的哈希值。除非您在这四个度量之一上具有相同的哈希值,否则您不能接近重复。
运气好的话,这个技巧意味着您只需要计算任何给定文档,其中包含相对较少的其他文档,这些文档在四分之一的字段上完全匹配。
如果“在同一哈希上匹配”的簇太大,您可以对不属于该簇的字段重复该技巧,以期减少需要完成的工作量。
推荐阅读
- java - 如何比较\断言双值放心
- c# - 如何使用 IEnumerable.GroupBy 比较元素之间的多个属性?
- php - 将产品元移动到附加信息选项卡
- internet-explorer - 在 Micronaut 中合并 IE 的 CORS 响应标头
- excel - 根据该列中第一个单元格的值查找一列,然后将该列定义为可在宏函数中使用的范围
- azure-aks - 主节点与工作节点通信的端口是什么
- php - php 7.3 下“continue”定位开关相当于“break”错误
- swift - 如何更改 Xcode 上的构建系统信息路径?
- javascript - 如何在 vue.js 应用程序中注册角度元素?
- laravel - 如何在 laravel 控制器中设置会话并在视图刀片中显示会话?