【问题标题】:Why spark.ml don't implement any of spark.mllib algorithms?为什么 spark.ml 不实现任何 spark.mllib 算法?
【发布时间】:2016-01-19 03:19:57
【问题描述】:

Spark MLlib Guide 之后,我们可以看到 Spark 有两个机器学习库:

  • spark.mllib,建立在 RDD 之上。
  • spark.ml,建立在 Dataframes 之上。

根据 StackOverflow 上的 thisthis 问题,数据帧比 RDD 更好(并且更新),应尽可能使用。

问题是我想使用常见的机器学习算法(例如:Frequent Pattern Mining,Naive Bayes等)和spark.ml(用于数据帧)不提供这种方法,只有spark.mllib(用于RDDs) 提供了这种算法。

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

这里缺少什么?

【问题讨论】:

  • 也与 StackOverflow 中的 Saving models 相关
  • 这个问题其实很有意思,其实和Alberto提到的那个问题有关。您可以在 @zero323 的答案中找到您的答案。
  • 迟到了,只是想补充一点,虽然主要的 Spark ML 在线文档没有提到它,但您可以在 API 文档中找到 NaiveBayes,您当然可以使用它。我是。

标签: machine-learning apache-spark pyspark apache-spark-mllib apache-spark-ml


【解决方案1】:

Spark 2.0.0

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

另请参阅:Switch RDD-based MLlib APIs to maintenance mode in Spark 2.0

火花

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

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

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

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

关于更好、更新和更快的我会看看Deep Dive into Spark SQL’s Catalyst Optimizer,尤其是与准引号相关的部分:

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


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

【讨论】:

  • 如果我错了请纠正我,但我认为即使ml 仅用作mllib 的包装器,它也为python 用户提供了很大的好处,因为ml 将使用mllib 的 Scala 版本,而不是通过 pyspark.mllib API 提供的 python 版本。这消除了在 JVM 和 Python 解释器之间移动数据的大量开销。
  • @Max 如果您统计加载到 Java 对象中的数据并且从不将其移回,那么可以。否则就不一样了。虚拟机之间也有不同类型的“移动数据”。所以我不确定我是否理解这个问题。
  • 是的,我的意思是如果您的输入/输出将在磁盘上,并且您使用 DataFrame API 进行磁盘 I/O。至于虚拟机之间的移动,我刚刚意识到在pyspark.mllib 场景中不需要序列化/反序列化数据(因为大部分数据将永远保留在 python 虚拟机中作为 numpy 数组等,并且不需要对其进行操作在 JVM 中)。所以我猜想使用 python RDD 与 Scala RDD 的开销仅限于您描述的问题here - 我认为这仍然不是完全微不足道的吗?
  • @max 好吧... 将东西保存在一个地方当然有好处。但这一切都取决于上下文。通常,分布式模型训练比任何 serde 活动都要昂贵得多。但是您不会通过加快一小部分代码来进行优化。所以我猜这里是合理的。
猜你喜欢
  • 1970-01-01
  • 2021-12-15
  • 2018-05-27
  • 2011-12-23
  • 2017-06-29
  • 2011-03-10
  • 1970-01-01
  • 1970-01-01
  • 2013-01-14
相关资源
最近更新 更多