我正在尝试为庞大的数据集(TB级数据)计算分位数(可以是近似的,具有一定的精度保证或误差界限)。我怎样才能有效地计算分位数。要求是
1) Can be computed efficiently (one-pass) or in a distributed way (merging)
2) High accuracy (or at least can be controlled)
3) Can be re-computed or reproduced in multiple language (java and python)
4) Incrementally updated (not a requirement but good to have)
我正在研究的几种方法是:
1)天真的解决方案:水库采样(不知道如何做到这一点 分布式地图减少方式特别是如何合并不同的水库 对于相同数据或两个不同分布的样本,是否有任何
良好的实施? )2)t-digest
3)Gurmeet Singh Manku,Sridhar Rajagopalan和Bruce G. Lindsay。 一次通过近似中位数和其他分位数以及与 记忆力有限。 (原因是我认为一些地图缩小框架就像 dataflow和BigQuery已经实现了这个AFAIK的变体)
具有使用这些算法和技术的经验的人能否为我提供一些关于每个问题的警告,利弊的指示。何时使用哪种方法,如果要求有效计算和准确性更好,则一种方法可以说比其他方法更好。
我没有特别使用基于摘要的方法,并且想要更好地理解为什么以及什么时候我更喜欢t-digest之类的东西,比如像水库采样这样简单的计算近似分位数。
答案 0 :(得分:1)
更新:似乎出现了一种新的非常好的算法,称为KLL。见paper。它有一个实施in Python和in Go。
t-digest具有多种语言的实现,可满足您的所有要求。请参阅the paper,与其他一些算法进行比较,例如:到Q-Digest。您可以在Q-Digest paper中查找更多比较。
通常,这两种算法都远远优于基于采样的估算分位数的算法,在给定相同存储量的情况下提供更好的准确性。你可以在优秀的书Data Streams: Algorithms and Applications中寻找对更多近似算法的讨论(它不讨论t-digest,因为它是在书出版后创建的。)
可能还有其他更好的算法,我不熟悉。
目前没有用于t-digest库的Beam包装器,但使用自定义CombineFn
开发它应该不难。例如,请参阅a current pending PR使用CombineFn
添加对不同近似算法的支持。