前一段时间我被介绍给ElasticSearch significant terms aggregation,并对这个衡量标准的优秀和相关程度感到非常惊讶。对于那些不熟悉它的人来说,它是一个非常简单的概念 - 对于给定的查询(前景集),给定的属性根据背景集的统计显着性进行评分。
例如,如果我们要查询英国交通警察中最重要的犯罪类型:
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)是自行车盗窃。频率增加了7倍。
"自行车盗窃的重要性"将是[(I/S) - (T/C)] * [(I/S) / (T/C)] = 0.371...
其中:
由于实际原因(我拥有大量数据以及巨大的ElasticSearch内存要求),我希望在SQL中或直接在代码中实现重要的术语聚合。
我一直在寻找一些方法来潜在地优化这种查询,特别是降低内存需求和提高查询速度,但代价是一些错误余量 - 但到目前为止我还没有破解了它。在我看来:
我也在查看MinHash,但从描述中看来它似乎无法在这里应用。
有没有人知道一些有助于解决这个问题的聪明算法或数据结构?
答案 0 :(得分:10)
我怀疑SQL impl会更快。 Lucene提前保持C和T的值。 S是从查询结果派生的简单计数,我使用O(1)数据结构查找。主要成本是在所选字段中观察到的每个术语的许多T查找。使用min_doc_count通常有助于大幅减少这些查找的数量。
出于实际原因(我拥有大量数据和巨大的ElasticSearch内存要求
您是否考虑过使用doc值更好地管理elasticsearch内存?见https://www.elastic.co/blog/support-in-the-wild-my-biggest-elasticsearch-problem-at-scale
答案 1 :(得分:1)
当前景集足够小时,可以采用有效的解决方案。然后您可以负担处理前景集中的所有文档。
收集所选字段前景集中出现的所有字词集{ X k }及其频率{ f k }在前景集中。
对于每个 X k
选择具有最高显着性值的术语。
但是,由于这种方法的简单性,我想知道ElasticSearch是否已包含该优化。如果它没有 - 那么它很快就会出现!