【问题标题】:Spark Mlib FPGrowth job fails with Memory ErrorSpark Mllib FP 增长作业因内存错误而失败
【发布时间】:2016-01-14 06:05:05
【问题描述】:

我有一个相当简单的用例,但结果集可能非常大。我的代码执行以下操作(在 pyspark shell 上):

from pyspark.mllib.fpm import FPGrowth
data = sc.textFile("/Users/me/associationtestproject/data/sourcedata.txt")
transactions = data.map(lambda line: line.strip().split(' '))
model = FPGrowth.train(transactions, minSupport=0.000001, numPartitions=1000)
# Perform any RDD operation
for item in model.freqItemsets().toLocalIterator():
    # do something with item

我发现每当我通过调用 count() 或 toLocalIterator 开始实际处理时,我的操作最终都会以内存不足错误结束。 FPGrowth 没有对我的数据进行分区吗?我的结果数据是否如此之大,以至于即使是一个分区也会阻塞我的记忆?如果是,有没有办法我可以以“流式”方式将 RDD 持久保存到磁盘,而无需尝试将其保存在内存中?

感谢您提供任何见解。

编辑: FPGrowth 的一个基本限制是整个 FP Tree 必须适合内存。因此,关于提高最低支持门槛的建议是有效的。

-拉吉

【问题讨论】:

  • 你有多少内存,你有多少产品?
  • 嗨 Alberto:在本地运行时,我给驱动程序 12G 内存。我的输入文件相当大:177468 行,每行包含相当多的项目。

标签: apache-spark rdd apache-spark-mllib


【解决方案1】:

嗯,问题很可能是支持阈值。当你像这里这样设置一个非常低的值时(我不会频繁调用百万分之一),你基本上会放弃向下封闭属性的所有好处。

这意味着所考虑的项目集的数量呈指数增长,在最坏的情况下,它将等于 2N - 1m,其中 N 是项目的数量。除非您有一个包含很少项目的玩具数据,否则这根本不可行。

编辑

请注意,对于大约 200K 事务(从 cmets 获取的信息)和支持阈值 1e-6,数据中的每个项集都必须是频繁的。所以基本上你在这里要做的是枚举所有观察到的项目集。

【讨论】:

  • 我同意你的评价。但是,我希望 mlib 能够扩展到大型数据集。查看 FPGrowth.scala 的底层,我看到 genFreqItems() 方法执行了一个 collect()。我想知道是否有一种方法可以重写以避免完整的 collect() 或替换为本地迭代器。想法?
  • 没关系。你根本无法以指数级的复杂性取胜。即使您忽略数学,也请考虑一下。在大约 200K 事务和阈值 1e-6 的情况下,每个大小为 1 的项集都很频繁。可以在您的数据中找到的每个大小为 2 的项集也将是频繁的。依此类推……即使您可以处理复杂性,它也无法提供任何有用的信息
  • 嗨@zero323,我同意它不会有用。但在某些方面,这不是重点。真正的问题是 FPGrowth 的这个实现没有扩展到那个大小。
  • 你是对的。该算法要求整个 FP 树驻留在内存中。我必须提高门槛。
猜你喜欢
  • 2017-03-16
  • 1970-01-01
  • 2022-08-13
  • 1970-01-01
  • 1970-01-01
  • 2018-08-24
  • 2015-11-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多