事前に出していた内容と違くてすみません!
とりあえず環境用意しようとしてたら時間かかってしまって。。
申し訳程度にmllibのコード書いてるのでご容赦ください。
自己紹介
-
名前:柴田 (@uryyyyyyy)
-
所属:株式会社オプト 開発1部
-
仕事内容:
- React/Play2でのWebアプリ開発
- Sparkでの分散処理開発
- mllibでのリコメンドエンジン開発←New
-
理系出身ですが、統計や情報系のことほとんどわからない。。
-
型&IDEがないとコード書けない。(TypeScript/Scala. JetBrains大好き)
-
Pokemon Go飽きた。。
前置き
筆者は主にアプリケーションエンジニアで、データ分析&pythonは目下独学で学び中です。
そのへんは温かい目で見ていただけると嬉しいです。
逆にscala/spark/AWSはある程度やってるので、何かあれば聞いてください!
(モデルをS3にバイナリで保存しておく方法とか云々)
概要
-
機械学習・データサイエンスといえばpython(numpy/iPython/scikit-learn)なのでpythonで書いていきたい。
-
しかし、仕事柄大規模なデータを扱うことになるので、分散できるsparkのAPIで取り扱いたい。
-
ということで(EMR)クラスタ上でpysparkを動かしてみます。
-
今からpython学ぶなら3系だろうということで3系(Anaconda)で動かす。
手順
基本的にこちらの記事を参考にしました。丁寧に書かれていて素晴らしいです。
Spark + IPython環境をAmazon EMR上で構築し、簡単なData解析を動かして見る (第1回:環境構築編)
- スクリプト準備
- EMRクラスタ立ち上げ
- iPython Notebook起動
- 動作確認
(スライドだと見づらいのでQiitaの記事として見て頂ければ。)
スクリプト準備
以下の2つのshellを用意します。
- EMRのbootstrap時に全ノードにanaconda3を入れるためのスクリプト
#Environments
ANACONDA_VERSION=3-4.0.0
PYENV=~/.pyenv
PYENV_BIN=$PYENV/bin
##Install git and Anaconda
sudo yum -y install git
git clone https://github.com/yyuu/pyenv.git $PYENV
echo -e "\nexport PYENV_ROOT=$PYENV" | tee -a ~/.bash_profile >> /dev/null
echo -e "\nexport PATH=$PYENV_BIN:$PATH" | tee -a ~/.bash_profile >> /dev/null
echo -e "\neval '$($PYENV_BIN/pyenv init -)'" | tee -a ~/.bash_profile >> /dev/null
source ~/.bash_profile
pyenv install anaconda$ANACONDA_VERSION
pyenv rehash
pyenv global anaconda$ANACONDA_VERSION
echo -e "\nexport PATH='$PYENV/versions/anaconda$ANACONDA_VERSION/bin/:$PATH'" | tee -a ~/.bash_profile >> /dev/null
source ~/.bash_profile
conda update --yes conda
##Install addtional python libraries
conda install --yes seaborn
- MasterNodeでiPyhtonの設定を行うスクリプト
#Environments
SPARK_PACKAGES=com.databricks:spark-avro_2.10:2.0.1,com.databricks:spark-csv_2.10:1.4.0
ANACONDA_VERSION=3-4.0.0
JUPYTER_LOG=/home/hadoop/.jupyter/jupyter.log
PYENV=~/.pyenv
PYENV_BIN=$PYENV/bin
##Configure Jupyter
jupyter notebook --generate-config
JUPYTER_NOTEBOOK_CONFIG=/home/hadoop/.jupyter/jupyter_notebook_config.py
sed -i -e "3a c.NotebookApp.ip = '*'" $JUPYTER_NOTEBOOK_CONFIG
sed -i -e "3a c.NotebookApp.open_browser =False" $JUPYTER_NOTEBOOK_CONFIG
sed -i -e "3a c.NotebookApp.port = 8080" $JUPYTER_NOTEBOOK_CONFIG
sed -i -e "3a c = get_config()" $JUPYTER_NOTEBOOK_CONFIG
IPYTHON_KERNEL_CONFIG=/home/hadoop/.ipython/profile_default/ipython_kernel_config.py
ipython profile create
sed -i -e "3a c.InteractiveShellApp.matplotlib = 'inline'" $IPYTHON_KERNEL_CONFIG
##Launch Jupyter by executing "pyspark"
JUPYTER_PYSPARK_BIN=/home/hadoop/.jupyter/start-jupyter-pyspark.sh
cat << EOF > $JUPYTER_PYSPARK_BIN
export SPARK_HOME=/usr/lib/spark/
export PYSPARK_PYTHON=$PYENV/versions/anaconda$ANACONDA_VERSION/bin/python
export PYSPARK_DRIVER_PYTHON=ipython
export PYSPARK_DRIVER_PYTHON_OPTS='notebook'
export SPARK_PACKAGES=$SPARK_PACKAGES
nohup pyspark --packages $SPARK_PACKAGES > $JUPYTER_LOG 2>&1 &
EOF
chmod +x $JUPYTER_PYSPARK_BIN
EMRクラスタ立ち上げ
基本は上記参考記事のままなのですが、
- BootStrapActionで上記のanaconda3-bootstrap.shを読ませる。
- とりあえず使うときはSpot Instanceを使うと安いよ。
- Security-Groupは、とりあえず自分のマシンからMasterNodeにsshログインさえできればOK。
- 実運用ではEMRを外に晒したくないので踏み台とか経由すると思います
- が、ちょいと面倒なので、とりあえずKeyがないとsshできなくて、他のportが空いてなければいいかなと。
- CoreNodeはとりあえずEmrManagedSlaveSecurityGroupを使っとけば大丈夫。
設定例の全体はこんな感じ。
aws emr create-cluster --applications Name=Hadoop Name=Spark Name=Ganglia --bootstrap-actions '[{"Path":"s3://<bucket>/anaconda3-bootstrap.sh","Name":"Custom action"}]' --ec2-attributes '{"KeyName":"","AdditionalSlaveSecurityGroups":[],"InstanceProfile":"EMR_EC2_DefaultRole","SubnetId":"","EmrManagedSlaveSecurityGroup":"","EmrManagedMasterSecurityGroup":""}' --service-role EMR_DefaultRole --enable-debugging --release-label emr-4.7.2 --log-uri '' --name 'jupyter pyspark' --instance-groups '[{"InstanceCount":1,"BidPrice":"0.1","EbsConfiguration":{"EbsBlockDeviceConfigs":[{"VolumeSpecification":{"SizeInGB":32,"VolumeType":"gp2"},"VolumesPerInstance":1}]},"InstanceGroupType":"MASTER","InstanceType":"m4.large","Name":"Master instance group - 1"},{"InstanceCount":2,"BidPrice":"0.1","EbsConfiguration":{"EbsBlockDeviceConfigs":[{"VolumeSpecification":{"SizeInGB":32,"VolumeType":"gp2"},"VolumesPerInstance":1}]},"InstanceGroupType":"CORE","InstanceType":"m4.large","Name":"Core instance group - 2"}]' --configurations '[{"Classification":"spark","Properties":{"maximizeResourceAllocation":"true"},"Configurations":[]}]' --region ap-northeast-1
iPython Notebook起動
立ち上げた後、MasterNodeにSSHして、上記のsetup-iPython.shを流し、
$JUPYTER_PYSPARK_BIN
を実行すればiPython notebookが立ち上がります。
後は自分のマシンから
ssh -i ~/.ssh/my.pem -ND 8157 hadoop@ec2-XXXX.com
のようにsshトンネリングを行い、ブラウザにproxyを立てればOK(やり方はEMRに書いてある)
ブラウザからhttp://ec2-XXXX.com:8080
に繋げたら設定完了。
動作確認
こんな感じになりました。試しにscikit-learnと比較してみました。
まとめ
- EMR使うとクラスタ上でのpyspark環境が楽に用意できますよ。
- ただ、sparkContext張りっぱなしなので一度に複数のNOTEBOOKは操作できないかも。
- iPyhtonで試して、上手く行ったらそれをそのままScalaに直して実運用!とかできそう。
- EC2はデフォでpython2系なので注意。
- MasterNodeにもWorkerNodeにもPython3系が必要です
(逆)質問
- みなさん、機械学習・データ解析するならどの言語を使っていますか?
- Python
- 王道感。可視化ツールやライブラリが充実してる感。速度も速いっぽい
- R
- 分析・統計系では一番情報が揃ってる?ちょっとした検証用?プログラム書ける?
- Java/Scala
- そろそろイケるのでは?ND4JとかDeepLearning4Jとかあるし。型欲しいですよね?
- Julia
- 使ってみたいけど未知。Rの強化版なイメージ
- Python
- どういうところでsparkを使いたいですか?
- リコメンドエンジン?
- ユーザー数とプロダクト数が増えると欲しくなる。ウチでも使ってる。
- その他
- 普通はモデルの生成にはそこまでデータ要らないのでは?
- 作ったモデルを大量のデータに適用したい時には使えそう。
- リコメンドエンジン?
- オススメのSaaS/PaaSとか
- Azure ML
- 一番王道?GUI系充実してるし、デプロイ楽そうだし
- Amazon ML
- 用途が限られるけど、分類には使えそう?
- Clouderaさんよく知らないです。。すみません。。。
- Azure ML
ありがとうございました
ちなみに、オプトではエンジニアを積極採用中なので、ご興味があればお声がけください。(雑)