14

不久前我被介绍到 ElasticSearch重要术语聚合,并且对这个指标的好和相关性感到非常惊讶。对于那些不熟悉它的人来说,这是一个非常简单的概念——对于给定的查询(前景集),给定的属性会根据背景集的统计显着性进行评分。

例如,如果我们要查询英国交通警察中最重要的犯罪类型:

C = 5,064,554 -- total number of crimes
T =    66,799 -- total number of bicycle thefts
S =    47,347 -- total number of crimes in British Transport Police
I =     3,640 -- total number of bicycle thefts in British Transport Police

通常,自行车盗窃仅占犯罪的 1% (66,799/5,064,554),但对于处理铁路和车站犯罪的英国交通警察来说,7% 的犯罪 (3,640/47,347) 是自行车盗窃。这是频率显着增加的七倍。

“自行车盗窃”的意义将是[(I/S) - (T/C)] * [(I/S) / (T/C)] = 0.371...

在哪里:

  • C是集合中所有文档的数量
  • S是匹配查询的文档数
  • T是具有特定术语的文档数
  • I是同时与ST相交的文档数

出于实际原因(我拥有的大量数据和巨大的 ElasticSearch 内存需求),我希望在 SQL 中或直接在代码中实现重要的术语聚合。

我一直在寻找一些可能优化这种查询的方法,特别是降低内存需求并提高查询速度,但代价是一些误差范围 - 但到目前为止我还没有破解它。在我看来,这:

  • 变量CS很容易缓存或查询。
  • 变量T可以从Count-Min Sketch导出,而不是查询数据库。
  • 然而,变量I似乎不可能从T的 Count-Min Sketch 推导出来。

我也在看MinHash,但从描述来看,它似乎不能在这里应用。

有谁知道一些有助于解决这个问题的聪明算法或数据结构?

4

2 回答 2

10

我怀疑 SQL impl 会更快。C 和 T 的值由 Lucene 提前维护。S 是从查询结果派生的简单计数,使用 O(1) 数据结构查找 I。主要成本是在所选字段中观察到的每个术语的许多 T 查找。使用 min_doc_count 通常有助于大大减少这些查找的数量。

出于实际原因(我拥有的大量数据和巨大的 ElasticSearch 内存需求

您是否考虑过使用 doc 值来更好地管理 elasticsearch 内存?请参阅https://www.elastic.co/blog/support-in-the-wild-my-biggest-elasticsearch-problem-at-scale

于 2016-06-05T16:40:20.717 回答
1

当前景集足够小时,一个有效的解决方案是可能的。然后,您可以负担处理前台集中的所有文档。

  1. 收集所选字段的前景集中出现的所有术语的集合 { X k },以及它们在前景集中的频率 { f k }。

  2. 对于每个X k

    • 计算X k的显着性为 ( f k - F k ) * ( f k / F k ),其中F k = T k / CX k在背景集中的频率。
  3. 选择具有最高显着性值的项。

但是,由于这种方法的简单性,我想知道 ElasticSearch 是否已经包含该优化。如果它没有 - 那么它很快就会!

于 2016-06-11T16:46:57.407 回答