Dash（+Docker）で機械学習アプリを作ってみたpart1 ~環境構築と動作確認~

## はじめに
### 動機
　機械学習を勉強する中で何か成果物を作ってみたいと思い、また可視化ツールであるPlotlyも触ってみたいと思っていたため、Plotlyが使われているDashでのアプリ開発に取り組みました。実際に作成した成果物が[こちら](https://dash-classification-app.herokuapp.com/)になります。学習記録を残す目的でこの記事を書きました。アプリ開発は初心者ですが、よろしくお願いいたします。
### 対象読者
　Dashでのアプリ開発に興味のある方や、機械学習やデータサイエンス関連の成果物を作りたいが何を作れば良いか悩んでいる方の参考になれば幸いです。Dockerの知識があることを前提としています。Dockerについては、[かめさんのブログ](https://datawokagaku.com/category/%e8%ac%9b%e5%ba%a7%e4%b8%80%e8%a6%a7/docker%e8%b6%85%e5%85%a5%e9%96%80/)（深く学ぶならUdemy講座）が分かりやすくておすすめです。

## Dashとは？
　DashはPythonのWebアプリケーションフレームワークの一つです。Plotly社が開発したオープンソースのフレームワークで、他にもR言語などで利用することができます。PythonのWebアプリフレームワークではDjangoやflaskなどが有名ですが、Dashは**可視化に特化している**点が特徴的です。Dashのバックエンドではflask, Plotly.js, React.jsが動いており、核となるPlotly.jsはJavaScriptベースの可視化ツールで、対話的な操作が可能な図を描画することが可能です。
　まとめると、Dashを使うことで、**JavaScriptの知識なしに動的なダッシュボードアプリを簡単に作成することができます**。言葉で説明してもイメージが沸きにくいと思うので、ぜひ[公式サイト](https://dash-gallery.plotly.host/Portal/)で公開されているアプリのサンプルを見てみて下さい。機械学習系のアプリも多くあり、また全てではありませんがGitHubにソースコードも公開されているため、機械学習のアウトプット法の一つとして参考になると思います。

## 環境構築
　環境構築は、[こちらの方の記事](https://qiita.com/hikarut/items/bbf099da841bff5e769c)を参考にDockerで行いました。Dashアプリ用のディレクトリ（今回は'Dash_App'）内に以下のファイルを用意します。

```
＜ディレクトリ構成＞
Dash_App/
　　├ app.py
　　├ Dockerfile
　　└ docker-compose.yml
```

```docker:Dockerfile
FROM python:3.7.3
USER root

RUN apt-get update
RUN apt-get install -y vim less
RUN apt-get install -y zsh less
RUN pip install --upgrade pip
RUN pip install --upgrade setuptools

RUN pip install \
    dash==1.16.3 \
    pandas \
    category_encoders \
    scikit-learn

ENV LANG ja_JP.UTF-8
ENV LANGUAGE ja_JP:ja
ENV LC_ALL ja_JP.UTF-8

EXPOSE 5050
CMD ["bash"]
```

```yml:docker-compose.yml
version: '3'
services:
  dash-app:
    restart: always
    build: .
    container_name: 'dash-app'
    ports:
      - "5050:5050"
    working_dir: '/root/'
    tty: true
    volumes:
      - .:/root/src/
      - ~/.zshrc:/root/.zshrc
```
　app.pyにはアプリの内容を書いていきます。まずは動作確認のため、公式チュートリアルにあるコードをコピペしておきます。

```python:app.py
import dash
import dash_core_components as dcc 
import dash_html_components as html

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

app.layout = html.Div(children=[

    html.H1(children='Hello Dash'),
    html.Div(children='Dash: A web application framework for Python.'),
    dcc.Graph(
        id='example-graph',
        figure={
            'data':[{'x': [1, 2, 3], 'y': [4, 1, 2], 'type': 'bar', 'name': 'SF'},
                    {'x': [1, 2, 3], 'y': [2, 4, 5], 'type': 'bar', 'name': u'Montréal'}],
            'layout':{'title': 'Dash Data Visualization'}
        }
    )
])

if __name__ == '__main__':
    app.run_server(host='0.0.0.0', port=5050, debug=True)
```
　サーバを立ち上げるコードの部分（最下行）で`host='0.0.0.0', port=5050`を追記して指定していることに注意してください。ファイルの作成が終わったら以下のコマンドでコンテナを立ち上げます。

```
$ docker-compose up -d --build
```
　コンテナが立ち上がったら、以下のコマンドのようにコンテナに入って`app.py`を実行します。※`dash-app`は、`docker-compose.yml`で指定したコンテナ名になります。

```
$ docker-compose exec dash-app zsh -c "python src/app.py"
```
　問題がなければアプリが起動します。ブラウザから`localhost:5050`にアクセスし、下のようなアプリ画面が表示されれば成功です。※「control + C」でアプリを終了します。
![スクリーンショット 2020-11-12 0.27.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/740683/0f25bfa1-2c68-d470-5b3f-21d5fe65e1b5.png)

## おわりに
　DockerコンテナでのDashの環境構築方法を紹介しました（とは言っても別の記事を見ながらDockerfileを少し修正しただけですが...）。一番面倒な環境構築がさくっとできるので、やはりDockerは便利ですね。[次の記事（part2）](https://qiita.com/NobuYoshi/items/9078d0689fef748486ac)では、app.pyの書き方について、公式チュートリアルから抜粋しながら基本となる部分に絞って紹介したいと思います。ありがとうございました。