在非 Spark 环境中加载 pyspark ML 模型

Posted

技术标签:

【中文标题】在非 Spark 环境中加载 pyspark ML 模型【英文标题】:Loading a pyspark ML model in a non-Spark environment 【发布时间】:2016-11-21 08:11:49 【问题描述】:

我有兴趣在 python 中部署机器学习模型,因此可以通过对服务器的请求进行预测。

我将创建一个 Cloudera 集群,并通过使用库 pyspark 来利用 Spark 开发模型。我想知道如何保存模型以便在服务器上使用它。

我已经看到不同的算法具有 .save 功能(就像在这篇文章 How to save and load MLLib model in Apache Spark 中回答的那样),但是由于服务器将在没有 Spark 而不是在 Cloudera 集群中的另一台机器上,所以我没有不知道是否可以使用他们的 .load 和 .predict 函数。

是否可以使用 pyspark 库函数在没有 Spark 的情况下进行预测?或者我是否必须进行任何转换才能保存模型并在其他地方使用它?

【问题讨论】:

我相信你需要有火花。我要说的一件事是,您可以在 python 中创建一个简单的 rest api 并加载模型文件并发送响应。 我添加了一个有效的答案 【参考方案1】:

花了一个小时后我得到了这个工作代码,这可能没有优化,

Mymodel.py:

import os
import sys

# Path for spark source folder
os.environ['SPARK_HOME']="E:\\Work\\spark\\installtion\\spark"

# Append pyspark  to Python Path
sys.path.append("E:\\Work\\spark\\installtion\\spark\\python")

try:
    from pyspark.ml.feature import StringIndexer
    # $example on$
    from numpy import array
    from math import sqrt
    from pyspark import SparkConf
    # $example off$

    from pyspark import SparkContext
    # $example on$
    from pyspark.mllib.clustering import KMeans, KMeansModel

    print ("Successfully imported Spark Modules")

except ImportError as e:
    sys.exit(1)


if __name__ == "__main__":
    sconf = SparkConf().setAppName("KMeansExample").set('spark.sql.warehouse.dir', 'file:///E:/Work/spark/installtion/spark/spark-warehouse/')
    sc = SparkContext(conf=sconf)  # SparkContext
    parsedData =  array([0.0,0.0, 1.0,1.0, 9.0,8.0, 8.0,9.0]).reshape(4,2)
    clusters = KMeans.train(sc.parallelize(parsedData), 2, maxIterations=10,
                            runs=10, initializationMode="random")
    clusters.save(sc, "mymodel")  // this will save model to file system
    sc.stop()

此代码将创建一个 kmean 集群模型并将其保存在文件系统中。

API.py

from flask import jsonify, request, Flask
from sklearn.externals import joblib
import os
import sys

# Path for spark source folder
os.environ['SPARK_HOME']="E:\\Work\\spark\\installtion\\spark"

# Append pyspark  to Python Path
sys.path.append("E:\\Work\\spark\\installtion\\spark\\python")

try:
    from pyspark.ml.feature import StringIndexer
    # $example on$
    from numpy import array
    from math import sqrt
    from pyspark import SparkConf
    # $example off$

    from pyspark import SparkContext
    # $example on$
    from pyspark.mllib.clustering import KMeans, KMeansModel

    print ("Successfully imported Spark Modules")

except ImportError as e:
    sys.exit(1)


app = Flask(__name__)

@app.route('/', methods=['GET'])
def predict():

    sconf = SparkConf().setAppName("KMeansExample").set('spark.sql.warehouse.dir', 'file:///E:/Work/spark/installtion/spark/spark-warehouse/')
    sc = SparkContext(conf=sconf)  # SparkContext
    sameModel = KMeansModel.load(sc, "clus")  // load from file system 

    response = sameModel.predict(array([0.0, 0.0]))  // pass your data

    return jsonify(response)

if __name__ == '__main__':
    app.run()

上面是我用烧瓶写的 REST api。

拨打http://127.0.0.1:5000/。您可以在浏览器中看到响应。

【讨论】:

我想知道调用 clusters.save 时模型以哪种格式保存。提前致谢。 您好,谢谢您的回答。但有一件事我不确定。我可以在只安装了 python 的机器上运行 API.py 脚本吗?还是我还需要安装 Spark?那样的话,安装单机版就够了吗? @MarcialGonzalez,是的,我们必须在服务器上安装 Spark,或者你可以做另一件事,在你的 rest 和 spark ml 服务器之间建立一个基于端口的通信。 @MarcialGonzalez,在我的生产中,我们有一个 REST api 暴露给客户端,我们的 ML 服务器正在运行,REST api 将使用基于端口与 ML 服务器通信并返回响应 是否可以通过使用 pickle 或 joblib 来持久化 pyspark 生成的 spark ml 模型?想法是将其导出并加载到仅安装 Python 的机器中。【参考方案2】:

看看MLeap(我参与的一个项目)——它提供了整个 ML 管道(不仅仅是估计器)的序列化/反序列化和一个不依赖于 spark 上下文的分布式执行引擎数据帧和执行计划。

截至今天,MLeap 用于执行模型的运行时没有 python 绑定,只有 scala/java,但添加它们应该不会很复杂。如果您需要帮助从 Spark 训练的管道和模型创建评分引擎,请随时在 github 上与我自己和其他 MLeap 开发人员联系。

【讨论】:

我刚刚创建了***.com/questions/tagged/mleap 标签,您可能想关注它。是否有计划将 mleap 集成到主 Spark 项目/分支中?对 Java 8 的支持如何?【参考方案3】:

这可能不是完整的解决方案

模型.py

from sklearn.externals import joblib
from sklearn.pipeline import make_pipeline
from sklearn.feature_extraction.text import HashingVectorizer
from sklearn.svm import LinearSVC

# code to load training data into X_train, y_train, split train/test set

vec = HashingVectorizer()
svc = LinearSVC()
clf = make_pipeline(vec, svc)
svc.fit(X_train, y_train)

joblib.dump('class1': clf, 'models', compress=9)

myRest.py

from flask import jsonify, request, Flask
from sklearn.externals import joblib

models = joblib.load('models')
app = Flask(__name__)

@app.route('/', methods=['POST'])
def predict():
    text = request.form.get('text')
    results = 
    for name, clf in models.iteritems():
        results[name] = clf.predict([text])[0]
    return jsonify(results)

if __name__ == '__main__':
    app.run()

你可以做这样的事情。参考:https://loads.pickle.me.uk/2016/04/04/deploying-a-scikit-learn-classifier-to-production/

对于火花:http://spark.apache.org/docs/latest/mllib-collaborative-filtering.html

【讨论】:

恐怕根本不是解决办法。 PySpark ml 不是 scikit-learn @LostInOverflow,我也知道我为 scikit-learn 添加了示例。确实我接受你的评论。但是我们甚至可以像这样加载 spark ml 模型。 sameModel = MatrixFactorizationModel.load(sc, "target/tmp/myCollaborativeFilter") 。检查此链接:spark.apache.org/docs/latest/mllib-collaborative-filtering.html 可以,但至少需要本地模式“集群”。所以它不是非 Spark 环境。 @LostInOverflow 是的,并使用工作样本检查我的另一个答案

以上是关于在非 Spark 环境中加载 pyspark ML 模型的主要内容,如果未能解决你的问题,请参考以下文章

在 Azure ML 上的 jupyter notebook 中加载 csv 并设置参数

如何从 PySpark 中的 spark.ml 中提取模型超参数?

在非 Codeigniter 类中加载和使用 Codeigniter 模型

NoSuchMethodException:Pyspark 模型加载中的 org.apache.spark.ml.classification.GBTClassificationModel

PySpark 中的 org.apache.spark.ml.feature.Tokenizer NPE

使用 PySpark 将多个数字列拟合到 spark-ml 模型中