【发布时间】:2012-04-27 05:18:29
【问题描述】:
我一直在处理一些非常大的数据集,通常是数十亿个元素,它们都保存在 memcached 云中并定期转储到文件中,对于我正在尝试的一项任务计算这个集合的基数。
在某些情况下,每个项目都包含一个 IP 和一些其他属性来标识一个人,并以 base64 编码,项目大小为 20 字节。不可能通过删除某些字段来减小项目的大小。
这是将我的数据集模拟为内存版本的东西(感谢this post 生成字符串):
import base64, os
dataset_size = 10000000000 # that's 10 billion, be careful if you run it !
big_dataset = [base64.b64encode(os.urandom(10)) for i in range(dataset_size)]
我的第一个方法是使用这样的哈希集:
uniques = set(big_dataset)
print "Cardinality: %d" % len(uniques)
虽然这在理论上适用于小型数据集,但您可以猜到有一个小问题:
- 我无法对我的数据的唯一性做出任何假设。我可以拥有 50% 的数据集是唯一的,或者我也可以拥有 100%。这是以固定的时间间隔动态生成的,并根据许多因素(例如一天中的时间)而变化
- 数据集大小为 100 亿。以 base 64 编码的每个项目是 20 个字节,乘以 100 亿是平均几百个千兆字节。不幸的是,我无法使用具有那么多 RAM 的机器!
我已经完成了我的作业,最多只能找到一些研究论文或一些不起眼的图书馆,但这样做的部分目标是了解什么方法有效以及为什么有效。
所以我打电话给你们 Python 用户,你们知道有什么算法可以帮助我有效地估计基数吗?复杂性是指我不太关心运行时间复杂性,但我更关注空间复杂性。如果它极大地提高了性能,我不介意牺牲一点准确性(所以我不一定需要知道唯一性的确切数量,即使这是理想的,但可能不是一种可行的方法)。我会说最多 5% 是可以接受的。我正在为这个项目寻找专门的 Python 内容。
感谢您提供的任何帮助!
正如一些人所说,我可以使用 Hadoop/MR,但对于这个特定的项目,我们不想走 MR 方式,而是想探索算法以在单台机器上有效地做到这一点,因为这可能是应用于其他几个不同的项目。
【问题讨论】:
-
只是一个建议,但这听起来可能对 Map-Reduce 框架有好处——将数据中的元素映射到字典或其他东西中的计数。为此,您可以使用由 Yelp 创建的 Python Map-Reduce 框架 MRJob。使用 MRJob 在 Amazon EC2 上运行它对您来说也是一个好主意。我以前用它来计算大型 corpra 中的词频。我想这完全取决于您如何解析单个数据元素。
-
感谢您的建议,是的,我考虑过 MR(实际上我在其他项目中经常使用它),但是对于这个特定问题,MR/Hadoop 不是一个选项,我们'作为概念验证的一部分,我希望研究在单台机器上执行此操作的算法。
-
如果 100% 的准确率不重要,也许一个会给你 5% 错误的布隆过滤器会适合内存?如果没有,并且需要一台机器,您可以简单地使用一些具有唯一键的简单 nosql 数据库,该数据库存储在磁盘上并删除重复项。它会很慢,但它适用于你拥有的任何数量的内存。您仍然可以并行化实际的插入工作。
-
最近有一篇关于 HN 的精彩帖子,讲述了一家公司 (Clearspring) 在现实世界中这样做...Big Data Counting: How To Count A Billion Distinct Objects Using Only 1.5KB Of Memory
-
哇,很棒的链接,这似乎正是我需要的!希望我以前见过。
标签: python optimization memcached set cardinality