16

根据Spark MLlib 指南 ,我们可以看到 Spark 有两个机器学习库:

  • spark.mllib,建立在 RDD 之上。
  • spark.ml,建立在数据框之上。

根据这个和StackOverflow 上的这个问题,Dataframes 比 RDD 更好(而且更新),应该尽可能使用。

问题是我想使用常见的机器学习算法(例如:频繁模式挖掘朴素贝叶斯等)并且spark.ml(对于数据帧)不提供这种方法,只有spark.mllib(对于 RDD)提供这种算法。

如果 Dataframes 比 RDDs 更好,并且参考指南建议使用spark.ml,为什么不在该库中实现常见的机器学习方法?

这里缺少什么?

4

1 回答 1

15

火花 2.0.0

DataFrame目前,随着 RDD API 的不断弃用,Spark 向 API 迈进了一大步。虽然原生“ML”算法的数量正在增长,但下面强调的要点仍然有效,并且在内部许多阶段是直接使用 RDD 实现的。

另请参阅:在 Spark 2.0 中将基于 RDD 的 MLlib API 切换到维护模式

火花 < 2.0.0

我想主要的缺失点是spark.ml算法通常不在 DataFrames 上运行。所以在实践中,拥有一个ml包装器比其他任何事情都重要。甚至本机 ML 实现(如内部ml.recommendation.ALS使用RDDs)。

为什么不在 DataFrames 之上从头开始实现一切?很可能是因为只有很小一部分机器学习算法实际上可以从目前在 Catalyst 中实现的优化中受益,更不用说使用 DataFrame API / SQL 高效自然地实现了。

  • 大多数 ML 算法需要高效的线性代数库而不是表格处理。对线性代数使用基于成本的优化器可能是一个有趣的补充(我认为已经有一个),但现在看起来这里没有什么可收获的。
  • DataFrames API 使您几乎无法控制数据。你不能使用 partitioner *,你不能同时访问多条记录(我的意思是整个分区),你被限制在一组相对较小的类型和操作中,你不能使用可变数据结构等等。
  • Catalyst 应用局部优化。如果您传递 SQL 查询/DSL 表达式,它可以对其进行分析、重新排序、应用早期预测。所有这一切都是伟大但典型的可扩展算法需要迭代处理。所以你真正想要优化的是整个工作流程,单独的 DataFrame 并不比普通的 RDD 快,并且取决于操作实际上可能更慢。
  • Spark 中的迭代处理,尤其是连接,需要对分区数量进行精细分级控制,否则会发生奇怪的事情。DataFrames 让您无法控制分区。此外,DataFrame/Dataset 不提供本机检查点功能(在 Spark 2.1 中修复),这使得迭代处理几乎不可能没有丑陋的 hack
  • 忽略低级实现细节,某些算法组(如 FPM)不太适合 ML 管道定义的模型。
  • 许多优化仅限于本机类型,而不是像VectorUDT.

DataFrames 还有一个问题,它与机器学习没有真正的关系。当您决定在代码中使用 DataFrame 时,您几乎放弃了静态类型和类型推断的所有好处。如果您认为这是一个问题,这是非常主观的,但可以肯定的是,在 Scala 世界中感觉并不自然。

关于更好、更新和更快的我会看看Deep Dive into Spark SQL's Catalyst Optimizer,特别是与 quasiquotes 相关的部分:

下图显示了准引号让我们生成性能类似于手动调优程序的代码。


* 这在 Spark 1.6 中已更改,但仍仅限于默认值HashPartitioning

于 2015-10-20T13:59:47.393 回答