计算 TB 数据集中分位数的高效算法
Posted
技术标签:
【中文标题】计算 TB 数据集中分位数的高效算法【英文标题】:efficient algorithm for computing quantiles in terabytes dataset 【发布时间】:2017-10-19 10:09:13 【问题描述】:我正在尝试为庞大的数据集(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。 一次通过并使用近似中位数和其他分位数 有限的记忆。 (原因是我认为一些地图减少框架,如 数据流和 BigQuery 已经实现了这个 AFAIK 的变体)
之前有使用这些算法和技术经验的人能否为我提供一些关于每种算法和技术的注意事项、优点和缺点的指示。何时使用哪种方法,如果要求高效计算和更好的准确性,则一种方法可以说比其他方法更好。
我没有特别使用基于摘要的方法,并且想更好地理解为什么以及何时我更喜欢像 t-digest 这样的东西而不是像水库采样这样简单的东西来计算近似分位数。
【问题讨论】:
你的数据集是如何格式化的? @AndrewMo:你能澄清一下你的意思和它的重要性吗?您可以假设的架构是几百列(对于每个我需要计算分位数)和分布式文件系统上的 avro 文件。每一列都是不同的,有自己的分布 为什么不把它塞进 BigQuery 并用 SQL 来处理呢? BigQuery 早餐会吃 TB:cloud.google.com/bigquery/docs/reference/standard-sql/… 【参考方案1】:更新:似乎出现了一种新的非常好的算法,称为 KLL。见paper。它有一个实现in Python 和in Go。
t-digest 有多种语言的实现并满足您的所有要求。请参阅the paper,它与其他一些算法进行比较,例如到 Q 文摘。您可以在Q-Digest paper 中查找更多比较。
一般来说,这两种算法在估计分位数方面都远远优于基于采样的算法,因为在相同存储量的情况下,它们可以提供更好的准确性。您可以在优秀的书籍Data Streams: Algorithms and Applications 中寻找更多近似算法的讨论(它没有讨论 t-digest,因为它是在本书出版后创建的)。
可能还有我不熟悉的其他更好的算法。
目前没有用于 t-digest 库的 Beam 包装器,但使用自定义 CombineFn
开发一个应该不难。例如,请参阅 a current pending PR 添加对使用 CombineFn
的不同近似算法的支持。
【讨论】:
以上是关于计算 TB 数据集中分位数的高效算法的主要内容,如果未能解决你的问题,请参考以下文章