23

我正在对一些数据应用一些机器学习算法,如线性回归、逻辑回归和朴素贝叶斯,但我试图避免使用 RDD 并开始使用 DataFrame,因为RDD比 pyspark 下的 Dataframe慢(见图 1)。

我使用 DataFrames 的另一个原因是因为 ml 库有一个对调整模型非常有用的类是CrossValidator这个类在拟合它之后返回一个模型,显然这个方法必须测试几个场景,然后返回一个拟合模型(具有最佳参数组合)。

我使用的集群不是很大,数据也很大,有些拟合需要几个小时,所以我想保存这些模型以便以后重用它们,但我还没有意识到如何,有什么我忽略的吗?

笔记:

  • mllib 的模型类有一个 save 方法(即NaiveBayes),但 mllib 没有 CrossValidator 并使用 RDD,所以我有预谋地避免它。
  • 当前版本是火花 1.5.1。
4

2 回答 2

25

火花 2.0.0+

乍一看Transformers,使用以下接口实现EstimatorsMLWritable

def write: MLWriter
def save(path: String): Unit 

MLReadable具有以下界面

def read: MLReader[T]
def load(path: String): T

这意味着您可以使用save方法将模型写入磁盘,例如

import org.apache.spark.ml.PipelineModel

val model: PipelineModel
model.save("/path/to/model")

稍后阅读:

val reloadedModel: PipelineModel = PipelineModel.load("/path/to/model")

PySpark 中也分别用MLWritable/JavaMLWritableMLReadable/实现了等效方法JavaMLReadable

from pyspark.ml import Pipeline, PipelineModel

model = Pipeline(...).fit(df)
model.save("/path/to/model")

reloaded_model = PipelineModel.load("/path/to/model")

SparkR 提供write.ml/read.ml功能,但截至今天,这些与其他支持的语言不兼容 - SPARK-15572

请注意,加载器类必须与存储的类匹配PipelineStage。例如,如果您保存了LogisticRegressionModel,则应使用LogisticRegressionModel.loadnot LogisticRegression.load

如果您使用 Spark <= 1.6.0 并在保存模型时遇到一些问题,我建议您切换版本。

除了 Spark 特定方法之外,还有越来越多的库旨在使用 Spark 独立方法保存和加载 Spark ML 模型。例如,请参阅如何提供 Spark MLlib 模型?.

火花 >= 1.6

从 Spark 1.6 开始,可以使用该save方法保存模型。因为几乎每个都model实现了MLWritable接口。例如,LinearRegressionModel有它,因此可以使用它将模型保存到所需的路径。

火花 < 1.6

我相信你在这里做出了不正确的假设。

可以优化a 上的某些操作,DataFrames并且与 plain 相比,它可以提高性能RDDsDataFrames提供高效的缓存,SQLish API 可以说比 RDD API 更容易理解。

ML Pipelines 非常有用,并且像交叉验证器或不同的评估器这样的工具在任何机器管道中都是必不可少的,即使上述任何一个都不是特别难在低级 MLlib API 之上实现,最好准备好使用,通用和相对良好的测试解决方案。

到目前为止一切顺利,但有几个问题:

  • 据我所知,对DataFrameslike的简单操作selectwithColumn显示与其 RDD 等价物相似的性能,例如map
  • 在某些情况下,与经过良好调整的低级转换相比,增加典型管道中的列数实际上会降低性能。您当然可以在纠正该问题的过程中添加 drop-column-transformers,
  • 许多 ML 算法,包括ml.classification.NaiveBayes 只是对其mllibAPI 的封装,
  • PySpark ML/MLlib 算法将实际处理委托给它的 Scala 算法,
  • 最后但并非最不重要的一点是,RDD 仍然存在,即使隐藏在 DataFrame API 后面

我相信最终通过使用 ML 而不是 MLLib 得到的是非常优雅的高级 API。您可以做的一件事是将两者结合起来创建一个自定义的多步骤管道:

  • 使用 ML 加载、清理和转换数据,
  • 提取所需数据(例如参见extractLabeledPoints方法)并传递给MLLib算法,
  • 添加自定义交叉验证/评估
  • MLLib使用您选择的方法(Spark 模型或PMML)保存模型

这不是最佳解决方案,但在给定当前 API 的情况下,它是我能想到的最佳解决方案。

于 2015-10-09T12:51:58.193 回答
5

似乎截至今天尚未实现用于保存模型的 API 功能(请参阅Spark 问题跟踪器 SPARK-6725)。

发布了另一种方法(如何将模型从 ML 管道保存到 S3 或 HDFS?),它涉及简单地序列化模型,但它是一种 Java 方法。我希望在 PySpark 中您可以做类似的事情,即腌制模型以写入磁盘。

于 2015-10-09T03:08:10.743 回答