web-dev-qa-db-ja.com

Spark \ PySparkでモデルを保存/ロードする正しい方法は何ですか

私はPySparkとMLlibを使用してSpark 1.3.0で作業しており、モデルを保存してロードする必要があります。次のようなコードを使用します(公式 ドキュメント から取得) )

from pyspark.mllib.recommendation import ALS, MatrixFactorizationModel, Rating

data = sc.textFile("data/mllib/als/test.data")
ratings = data.map(lambda l: l.split(',')).map(lambda l: Rating(int(l[0]), int(l[1]), float(l[2])))
rank = 10
numIterations = 20
model = ALS.train(ratings, rank, numIterations)
testdata = ratings.map(lambda p: (p[0], p[1]))
predictions = model.predictAll(testdata).map(lambda r: ((r[0], r[1]), r[2]))
predictions.collect() # shows me some predictions
model.save(sc, "model0")

# Trying to load saved model and work with it
model0 = MatrixFactorizationModel.load(sc, "model0")
predictions0 = model0.predictAll(testdata).map(lambda r: ((r[0], r[1]), r[2]))

Model0を使おうとすると、長いトレースバックが得られます。これは次のように終わります。

Py4JError: An error occurred while calling o70.predict. Trace:
py4j.Py4JException: Method predict([class org.Apache.spark.api.Java.JavaRDD]) does not exist
    at py4j.reflection.ReflectionEngine.getMethod(ReflectionEngine.Java:333)
    at py4j.reflection.ReflectionEngine.getMethod(ReflectionEngine.Java:342)
    at py4j.Gateway.invoke(Gateway.Java:252)
    at py4j.commands.AbstractCommand.invokeMethod(AbstractCommand.Java:133)
    at py4j.commands.CallCommand.execute(CallCommand.Java:79)
    at py4j.GatewayConnection.run(GatewayConnection.Java:207)
    at Java.lang.Thread.run(Thread.Java:745)

だから私の質問は-私は何か間違ったことをしているのですか?私がデバッグした限り、モデルは(ローカルおよびHDFSに)保存されており、いくつかのデータを含む多くのファイルが含まれています。モデルは正しく保存されているように感じますが、おそらく正しくロードされていません。私もグーグルで検索しましたが、関連するものは何も見つかりませんでした。

このsave\load機能は最近Spark 1.3.0に追加されたようです。このため、別の質問があります。リリース1.3.0より前にモデルをsave\loadするための推奨される方法は何でしたか。 ?少なくともPythonの場合、これを行うための優れた方法は見つかりませんでした。Pickleも試しましたが、ここで説明したのと同じ問題に直面しました Save Apache Spark mllib model Pythonで

13
artemdevel

モデルを保存する1つの方法(Scalaで;しかしおそらくPythonでも同様):

// persist model to HDFS
sc.parallelize(Seq(model), 1).saveAsObjectFile("linReg.model")

保存されたモデルは、次のようにロードできます。

val linRegModel = sc.objectFile[LinearRegressionModel]("linReg.model").first()

関連する 質問 も参照してください

詳細については、( ref )を参照してください。

7
Neil

このプルリクエスト 2015年3月28日(質問が最後に編集された翌日)にマージされた時点で、この問題は解決されています。

GitHub(git clone git://github.com/Apache/spark.git -b branch-1.3)から最新バージョンのクローンを作成/フェッチしてから、spark/README.mdを使用してビルド($ mvn -DskipTests clean packageの手順に従って)する必要があります。

注:Mavenが不安定だったため、Sparkの構築で問題が発生しました。$ update-alternatives --config mvnを使用し、優先度が150の「パス」を選択することで問題を解決しました。 ここでの説明

5
emmagras

私もこれに遭遇します-それはバグのように見えます。 spark jira に報告しました。

2
Charles Hayden

MLでパイプラインを使用してモデルをトレーニングしてから、MLWriterとMLReaderを使用してモデルを保存して読み戻します。

from pyspark.ml import Pipeline
from pyspark.ml import PipelineModel

pipeTrain.write().overwrite().save(outpath)
model_in = PipelineModel.load(outpath)
1
Rong Du