R&D部のmatsushitasです。絶賛機械学習勉強中です。
機械学習プログラムの開発・実行環境として有名なJupyter Notebookと、Sparkの機械学習ライブラリであるMLlib。
この2つを組み合わせるケースはそれなりにあるんじゃないかと思いますが、その実行方法は何パターンかあるようです。
サンプルプログラムを使っていくつか紹介します。
サンプルプログラム
https://github.com/romiogaku/jupyter-notebook-spark-sample
Sparkに依存するpythonプログラムです。サンプルなので実際の学習は行いませんが、本来は大量の学習データをDataFrameで前処理したり、Spark MLlibで学習モデル作ったりする想定です。
外部jarに依存する例も示したかったので、今回は Elasticsearch-Hadoopコネクタを利用してみます。Spark用のjarファイルを読み込めば、SparkのDataFrameをElasticsearchに書き込んだりできるようになります。
前準備
事前にSparkとpipenvのインストールが必要です。(Sparkは2.2.0で動作を確認しました)
$ pipenv install
で依存ライブラリを仮想環境内にインストールできます。
また、Elasticsearchを使うのでdockerで起動しておきます。
$ docker-compose up -d
http://localhost:9200でElasticsearchが、http://localhost:5601 でKibanaが起動します。
実行方法1: pysparkコマンドでJupyterNotebookを起動させる
PySparkを使う際のインタプリタとしてJupyter Notebookを使うように環境変数を設定します。
PYSPARK_DRIVER_PYTHON="jupyter" PYSPARK_DRIVER_PYTHON_OPTS="notebook" pipenv run pyspark --jars /path/to/jupyter-notebook-spark-sample/elasticsearch-hadoop-6.3.2/dist/elasticsearch-spark-20_2.11-6.3.2.jar
外部jarファイルは相対パスだとうまくいかないことがあったので、絶対パスで指定しています。お使いの環境に合わせてください。
pipenv
を利用している場合は.env
ファイルを読み込んで環境変数をセットしてくれるので、以下のような.env
ファイルを用意してもOKです。
PYSPARK_DRIVER_PYTHON="jupyter"
PYSPARK_DRIVER_PYTHON_OPTS="notebook"
実行方法2: .pyファイルに変換してspark-submitコマンドで実行させる
spark-submit
コマンドはpythonプログラムも実行できます。
まずは.ipynb
ファイルを.py
ファイルに変換します。
$ pipenv run jupyter nbconvert --to script sample.ipynb
以下のコマンドで実行できます。
$ pipenv run spark-submit --jars /path/to/jupyter-notebook-spark-sample/elasticsearch-hadoop-6.3.2/dist/elasticsearch-spark-20_2.11-6.3.2.jar sample.py
実行方法3: Jupyter NotebookからSparkを起動させる
通常のJupyter Notebook起動コマンドです。
$ pipenv run jupyter notebook
立ち上がったらSparkをJupyter上で実行するための準備として、コード内の以下のCell全体をコメントインしてください。
import sys
spark_home = os.environ.get('SPARK_HOME', None)
sys.path.insert(0, spark_home + "/python")
# py4j-0.10.7-src.zipのバージョンは適宜変更してください
sys.path.insert(0, os.path.join(spark_home, "python/lib/py4j-0.10.4-src.zip"))
あとは通常通りJupyter Notebook上でステップごとに実行できます。
実行方法4: Jupyter Notebookをそのまま実行させる
これも方法3と同じく、SparkをJupyter上で実行するためコードがコメントインされている必要があります。
この方法ではブラウザでJupyter Notebookを起動させず、コマンドラインで.ipynb
ファイルを直接実行します。
$ pipenv run jupyter nbconvert --to notebook --execute sample.ipynb --output sample-output.ipynb --allow-errors --debug
nbconvertの代わりにpapermillを使うこともできます。
$ pipenv run papermill sample.ipynb sample-output.ipynb
出力結果はどちらも.ipynb
ファイルで出力されるので、HTMLに変換して見てみましょう。
$ pipenv run jupyter nbconvert --to html sample-output.ipynb
おわりに
複数の実行方法を紹介してきましたが、実行する環境によって使い分けるのが良さそうです。
例えば開発時はJupyter Notebookを使いたいので方法1、または方法3。
バッチプログラムとして定期実行させたい本番運用時は方法2、または方法4が良いかと思います。