Docker + Jupyter notebook + mecab でローカルやAzure Data Science VMで自然言語処理

# 目的
- Docker上のLinuxで、mecabを用いて自然言語処理を行う
- ポータブル・スケーラブル・マネージャブルな環境にする  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/195903/6d14cdc3-84ea-908a-f3f4-64e443c3a629.png)



# 環境
- ホスト：Windows10(Docker For Windows)  
- Docker：Ubuntu（jupyter/datascience-notebook）  

# データ
- Livedoorニュースコーパス  
https://www.rondhuit.com/download.html#ldcc

# 前処理の前処理
- 改行とURLとタイムスタンプの削除
  - 各ファイルのヘッダーに入っている、引用元のURLとタイムスタンプ、それから改行を削除する。 
![image.png](https://qiita-image-store.s3.amazonaws.com/0/195903/312ddd0b-2b2a-ed5c-b81a-9bc607ca2420.png)
  - grep置換  
```
\n|http?://[\w/:%#\$&\?\(\)~\.=\+\-]+|\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d\+\d\d\d\d
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/195903/2fd6c13d-4edd-2566-4b45-32cf113d0f72.png)
 
- ファイル統合
    - textbinderとか使う  
        - http://pckowazafreesoft.ojaru.jp/html/freesoft_textbinder.html

# Dockerインストール
- https://docs.docker.com/docker-for-windows/install/  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/195903/2e049d4d-4e01-efbc-3bcd-a8112f47a904.png)  
<br>
- ※制限があるので注意※
  - 64bit版のWindows 10（バージョン1511、ビルド10586以降）、ProもしくはEnterprise・Educationエディション
  - Hyper-Vが利用できること
  - コンテナ実行用の仮想マシンには、メモリ2GB、ディスク60GB（容量可変タイプの仮想ディスクで、初期サイズは4GB程度）のリソースが必要

# データの準備
- ポータブルな環境にするために、データは外部永続ストレージにいれておくことが望ましい。  
<br>
- BloBStorageにコンテナを作る。(参考：https://docs.microsoft.com/ja-jp/azure/storage/common/storage-create-storage-account)  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/195903/2fd6b870-6649-a23f-f332-a3b8d76bcb61.png)  
<br>
- ファイルアップロード  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/195903/c7091524-d5e9-5e47-f2ec-403ff755dcc5.png)  
<br>

# Docker Imageの作成
- DockerHubからImageを取得。  
DockerHub  
https://hub.docker.com/  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/195903/d912a7da-c1df-2414-64e6-bdee7055f0dc.png)
<br>  
- 今回は、UbuntuにAnacondaが搭載されたこちらのImageをベースとする。  
https://hub.docker.com/r/jupyter/datascience-notebook/  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/195903/96c01da5-aa18-718b-3464-dbc2ff23e43c.png)  
<br>

- ダウンロードと起動

```
# ダウンロード
$ docker pull datascience-notebook

# イメージの確認
$ docker images
REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE
jupyter/datascience-notebook   latest              1c322d19442d        2 days ago          5.95GB
ubuntu                         latest              c9d990395902        13 days ago         113MB
hello-world                    latest              e38bc07ac18e        2 weeks ago         1.85kB

# 実行
$ docker run -p 8888:8888 --name jpt -e GRANT_SUDO=yes --user root jupyter/datascience-notebook
/usr/local/bin/start-notebook.sh: ignoring /usr/local/bin/start-notebook.d/*

Set username to: jovyan
usermod: no changes
Granting jovyan sudo access and appending /opt/conda/bin to sudo PATH
Executing the command: jupyter notebook
[I 06:50:03.820 NotebookApp] Writing notebook server cookie secret to /home/jovyan/.local/share/jupyter/runtime/notebook_cookie_secret
[W 06:50:04.206 NotebookApp] WARNING: The notebook server is listening on all IP addresses and not using encryption. This is not recommended.
[I 06:50:04.287 NotebookApp] JupyterLab beta preview extension loaded from /opt/conda/lib/python3.6/site-packages/jupyterlab
[I 06:50:04.287 NotebookApp] JupyterLab application directory is /opt/conda/share/jupyter/lab
[I 06:50:04.305 NotebookApp] Serving notebooks from local directory: /home/jovyan
[I 06:50:04.305 NotebookApp] 0 active kernels
[I 06:50:04.305 NotebookApp] The Jupyter Notebook is running at:
[I 06:50:04.306 NotebookApp] http://[all ip addresses on your system]:8888/?token=167a0943c31e9415e9136719d81a71888eb2cc3ea53d7931
[I 06:50:04.306 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
[C 06:50:04.308 NotebookApp]

    Copy/paste this URL into your browser when you connect for the first time,
    to login with a token:
        http://localhost:8888/?token=167a0943c31e9415e9136719d81a71888eb2cc3ea53d7931
[I 06:50:28.247 NotebookApp] 302 GET /?token=167a0943c31e9415e9136719d81a71888eb2cc3ea53d7931 (172.17.0.1) 1.20ms
```

- 表示された http://localhost:8888…… をブラウザに貼り付けてアクセスすると、JupyterNotebookが表示される。  
<br>
- その前に必要なものをDocker内にインストールする。

```
# Dockerにログイン
$ winpty docker exec -it jpt bash

# update
sudo apt-get update 
sudo apt-get -y upgrade 
sudo apt-get -y dist-upgrade

# mecabインストール
sudo apt-get install mecab libmecab-dev mecab-ipadic mecab-ipadic-utf8 file
git clone --depth 1 https://github.com/neologd/mecab-ipadic-neologd.git
cd mecab-ipadic-neologd
./bin/install-mecab-ipadic-neologd -n -a

# edit
vi /etc/mecabrc

# 下記行を編集
 dicdir = /usr/lib/mecab/dic/mecab-ipadic-neologd

# pip
pip install mecab-python3
pip install wordcloud

# 新語辞書を確認する。
python
Python 3.6.5 | packaged by conda-forge | (default, Apr  6 2018, 13:39:56)
[GCC 4.8.2 20140120 (Red Hat 4.8.2-15)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import MeCab
>>> m = MeCab.Tagger("-Ochasen")
>>> print(m.parse("きゃりーぱみゅぱみゅと、橋本環奈が、ディズニーランドに遊びに行ったらしい。"))
きゃりーぱみゅぱみゅ    キャリーパミュパミュ    きゃりーぱみゅぱみゅ    名詞-固有名詞-人名-一般
と      ト      と      助詞-並立助詞
、      、      、      記号-読点
橋本環奈        ハシモトカンナ  橋本環奈        名詞-固有名詞-一般
が      ガ      が      助詞-格助詞-一般
、      、      、      記号-読点
ディズニーランド        ディズニーランド        ディズニーランド        名詞-固有名詞-一般
に      ニ      に      助詞-格助詞-一般
遊び    アソビ  遊び    名詞-一般
に      ニ      に      助詞-格助詞-一般
行っ    イッ    行く    動詞-自立       五段・カ行促音便        連用タ接続
た      タ      た      助動詞  特殊・タ        基本形
らしい  ラシイ  らしい  助動詞  形容詞・イ段    基本形
。      。      。      記号-句点
EOS

# dockerをイメージとして保存する。
$ docker commit jpt jupyter-mecab

# イメージを確認する。
$ docker images
REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE
jupyter-mecab                  latest              f3add9c48f38        2 minutes ago       9.41GB
jupyter/datascience-notebook   latest              1c322d19442d        2 days ago          5.95GB

# ログイン
$ docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: tatsuyatakahashi
Password:

# タグをつける
$ docker tag jupyter-mecab tatsuyatakahashi/nlp:empty

# DockerHubにプッシュする
$ docker push tatsuyatakahashi/nlp

# イメージの確認（プッシュしたものが、自動的にプルされる）
$ docker images
REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE
jupyter-mecab                  latest              f3add9c48f38        16 minutes ago      9.41GB
tatsuyatakahashi/nlp           empty               f3add9c48f38        16 minutes ago      9.41GB
jupyter/datascience-notebook   latest              1c322d19442d        2 days ago          5.95GB
```

- DockerHubに登録された。  
https://hub.docker.com/r/tatsuyatakahashi/nlp/  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/195903/2ce62827-954e-1ae7-a0d0-564f39998b9c.png)  
<br>

# Jupyter Notebook と Mecab
- 上記で表示された http://localhost:8888…… にブラウザでアクセスします。  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/195903/1074155e-2b42-73fb-29c0-92617bb82e17.png)  
<br>

- コードの全量はこちらです。データファイルのStorageのURLは適宜変更してください（ファイルは削除済みです）。ブロックごとに解説していきます。
https://github.com/tatsuya-takahashi/textmining-livedoornews/blob/master/nlp.ipynb  
<br>

- データダウンロード  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/195903/e41e2562-58a4-4cb4-7a3f-e5ef5c15cd6d.png)  
<br>

- ライブラリのImportと、データの確認  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/195903/d9f5a539-0c18-ba3a-f5fa-acf9cd38391e.png)  
<br>

- mecabの形態素解析を実行  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/195903/5a9a3cba-6a7c-c5c2-cecd-0d03baca870c.png)  
<br>

- wordcloudで、ワードクラウドを表示  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/195903/6effddae-8c92-e4d0-8380-cd881c3599c0.png)  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/195903/0815232f-7781-b89a-b92d-b8001704c0c6.png)  
<br>

- Docker上で、Jupyter Notebookとmecabが実行できた。

# リモートのDSVM（Data Science Virtual Machine）で再現
- Azureポータルで、すべてのサービス -> virtual machineと入力してクリック -> 好きなマシンを選ぶ  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/195903/20f3319b-9235-cdc4-d441-082c474729fe.png)  
<br>

- 必要な情報を入力していく
![image.png](https://qiita-image-store.s3.amazonaws.com/0/195903/f0d618a8-bb3c-b571-958c-e62295911113.png)  
<br>

- 今回はDS1_V2にした  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/195903/e7074465-9014-9f49-74d7-2282f2188287.png)  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/195903/817880a7-948e-64a7-3c46-6b66ca537bf7.png)  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/195903/deb5de9e-e676-3154-72b9-5051e4b71426.png)  
<br>  

- X2GOでアクセスする。今回は公開鍵認証方式にした。X2GOの詳しい説明は、こちらを参照。
https://docs.microsoft.com/ja-jp/azure/machine-learning/data-science-virtual-machine/linux-dsvm-intro  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/195903/c41e2bc9-be88-8653-eef2-927f91642938.png)  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/195903/8236daad-024f-33c4-8deb-98fce9060c90.png)  
<br>  

- ログインできた。DSVMは、はじめからDockerや、Pythonや科学計算ライブラリがインストールされている。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/195903/a8e797bf-76ef-aad0-3ddb-1f074c8f6e3d.png)  
<br>

- 環境を構築する

```
# 上で作ったDockerHubのイメージをダウンロード
$ sudo docker pull tatsuyatakahashi/nlp:empty

# 確認
$ sudo docker images
REPOSITORY             TAG                 IMAGE ID            CREATED             SIZE
tatsuyatakahashi/nlp   empty               f3add9c48f38        18 hours ago        9.41GB

# 起動
$ sudo docker run -d -p 8888:8888 --name jpt -e GRANT_SUDO=yew --user root tatsuyatakahashi/nlp:empty
/usr/local/bin/start-notebook.sh: ignoring /usr/local/bin/start-notebook.d/*

Set username to: jovyan
usermod: no changes
Executing the command: jupyter notebook
[W 02:25:16.462 NotebookApp] WARNING: The notebook server is listening on all IP addresses and not using encryption. This is not recommended.
[I 02:25:16.601 NotebookApp] JupyterLab beta preview extension loaded from /opt/conda/lib/python3.6/site-packages/jupyterlab
[I 02:25:16.602 NotebookApp] JupyterLab application directory is /opt/conda/share/jupyter/lab
[I 02:25:16.646 NotebookApp] Serving notebooks from local directory: /home/jovyan
[I 02:25:16.646 NotebookApp] 0 active kernels
[I 02:25:16.646 NotebookApp] The Jupyter Notebook is running at:
[I 02:25:16.646 NotebookApp] http://[all ip addresses on your system]:8888/?token=66e86470a096479d414087e79c0e62cab88f143ead03a2c0
[I 02:25:16.646 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
[C 02:25:16.647 NotebookApp] 
    
    Copy/paste this URL into your browser when you connect for the first time,
    to login with a token:
        http://localhost:8888/?token=66e86470a096479d414087e79c0e62cab88f143ead03a2c0

# ログイン
$ sudo docker exec -it jpt bash

# ソースコードはgithubに格納したものを使用する。このように、環境、データ、ソースを疎結合にしておくことで、ポータビリティを担保する。
$ sudo git clone https://github.com/tatsuya-takahashi/textmining-livedoornews.git
```

<br>
- Docker上でJupyter Notebook起動確認
![image.png](https://qiita-image-store.s3.amazonaws.com/0/195903/700b86d0-0066-8e5e-4e8b-9c5ff169c417.png)  
<br>
- ローカルDockerと同様に実行可能  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/195903/75d93fa0-65a8-45d0-c192-62948b146b17.png)  
<br>

# 総論
- 実行環境をDocker、ソースをGithub、データをAzure BlobStorageに入れておくことにより、いかなる環境でも即時デプロイ・実行が可能になった。
- OSに依存せず、Dockerが動く環境さえあれば同様の結果が担保される。

# 次回
- Azure Batch AI（ https://azure.microsoft.com/ja-jp/services/batch-ai/）を利用した、低優先度マシン（low priority vm）での分散学習について寄稿予定です。