Spark 2.0.0+
乍一看,所有的Transformers
和Estimators
都实现了MLWritable
接口,其接口如下:
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
/
JavaMLWritable
和
MLReadable
/
JavaMLReadable
。请注意保留 HTML 标签。
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.load
而不是
LogisticRegression.load
。
如果您使用的是Spark <= 1.6.0并且遇到了一些模型保存问题,建议您切换版本。
此外,除了Spark特定的方法之外,还有越来越多的库专门设计用于使用Spark独立方法保存和加载Spark ML模型。例如,请参阅
如何提供Spark MLlib模型服务?。
Spark >= 1.6
自Spark 1.6以来,可以使用
save
方法保存您的模型。因为几乎每个
model
都实现了
MLWritable接口。例如,
LinearRegressionModel就有,因此可以使用它将模型保存到所需路径。
Spark < 1.6
我认为你在这里做出了错误的假设。
一些对
DataFrames
的操作可以进行优化,并且相比于普通的
RDDs
,可以获得更好的性能。
DataFrames
提供高效的缓存,并且SQLish API比RDD API更易于理解。
ML管道非常有用,像交叉验证器或不同的评估器等工具在任何机器学习管道中都是必备的。即使以上内容并不特别难以在低级MLlib API之上实现,但拥有已准备好的、通用的、相对经过良好测试的解决方案要好得多。
到目前为止一切都很好,但存在一些问题:
- 据我所知,对于像
DataFrames
这样的简单操作,如select
或withColumn
,其性能与其RDD等效项(如map
)相似。
- 在某些情况下,在典型管道中增加列数实际上可能会降低性能,与精心调整的低级转换相比。当然,您可以在途中添加删除列转换器来纠正这种情况。
- 许多ML算法,包括
ml.classification.NaiveBayes
仅仅是其mllib
API的包装器。
- PySpark ML/MLlib算法将实际处理委托给其Scala同行。
- 最后但并非最不重要的,RDD仍然存在,即使它被DataFrame API很好地隐藏起来了。
我相信,使用ML而不是MLLib,你得到的东西非常优雅,高级API。您可以做的一件事是将两者结合起来创建自定义的多步骤管道:
虽然不是最佳解决方案,但在当前API下是我能想到的最好的方案。
RDDs
转变为DataFrames
。 我用的是1.6.1
,但是我也遇到了相同的问题,因为OneVsRest
似乎还没有实现保存功能。https://dev59.com/vJXfa4cB1Zd3GeqPfXZY - Brian