ナード戦隊データマン

データサイエンスを用いて悪と戦うぞ

spark-sklearnをjupyterで試しに使ってみる

巨大なデータに対してGridSearchCVを回し、たくさんのハイパーパラメータの組合せから最適なものを探すのには結構時間がかかります。ここでは、spark-sklearnを使うことにより、その問題の解決策を探ります。

事前準備

まず、ドライバとワーカーのマシンを用意します。ドライバは、jupyter notebookを使うマシンで、ワーカーは処理を分散実行するためのマシンです。

ワーカー(スレーブ)にsshでアクセスできるよう、以下を実行します。(lubuntuを使用)

apt-get install openssh-server 

dockerも入れます。

apt-get install docker

ドライバ(マスター)には、spark-sklearnを入れます。

pip install spark-sklearn

その他の設定は、以下の記事から行ってください。

https://qiita.com/chan-p/items/b4fd1e3c7bf95d6933f9

実行の確認

設定が完了しているのであれば、以下コマンドでjupyter notebookが起動するはずです。

/usr/local/spark/bin/pyspark --master spark://マスターのIP:7077 --packages org.apache.hadoop:hadoop-aws:2.7.0

jupyterが起動したら、ノートブックでsc変数にSparkContextオブジェクトが初期化されているか確認します。

In[1]:

sc

Out[1]:

SparkContext

Spark UI

Version
v2.2.0
Master
spark://192.168.2.104:7077
AppName
PySparkShell

今回は実行確認だけなので、以下を実行してみます。

In[2]:

from sklearn import svm, grid_search, datasets
from spark_sklearn import GridSearchCV
iris = datasets.load_iris()
parameters = {'kernel':('linear', 'rbf'), 'C':[1, 10]}
svr = svm.SVC()
clf = GridSearchCV(sc, svr, parameters)
clf.fit(iris.data, iris.target)

Out[2]:

GridSearchCV(cv=None, error_score='raise',
       estimator=SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
  decision_function_shape=None, degree=3, gamma='auto', kernel='rbf',
  max_iter=-1, probability=False, random_state=None, shrinking=True,
  tol=0.001, verbose=False),
       fit_params={}, iid=True, n_jobs=1,
       param_grid={'kernel': ('linear', 'rbf'), 'C': [1, 10]},
       pre_dispatch='2*n_jobs', refit=True, return_train_score=True,
       sc=<SparkContext master=spark://192.168.2.104:7077 appName=PySparkShell>,
       scoring=None, verbose=0)

In[3]:

clf.predict(iris.data)

Out[3]:

array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])

とりあえず、実行できたみたいです。

ちょっとした注意点

この単純なGridSearchCVを実行するのに、私のマシンでは5分かかりました。マシンの数が少ないのも原因ですが、sparkでは当然、分散させて実行するにネットワークを用いてデータのやり取りをします。

データの数が膨大で(いわゆるビッグデータ), ハイパーパラメータの組合せがとても多いような状況では、コア数の多い複数のマシンに分散させれば実行が早く完了する可能性があります。

でも、今回の例のような小さなデータで、少数のハイパーパラメータを設定するような状況では、sparkを使わないほうが速いようです。

リンク

https://github.com/databricks/spark-sklearn