de:code 2018 [AI14] Azure Machine Learning services で実現する Deep Learning によるテキスト分類

[de:code 2018](https://www.microsoft.com/ja-jp/events/decode/2018/)に参加してきましたのでその結果をまとめています。

内容の間違い、誤字脱字等はご了承ください。正確なところは、本家のサイトを参照いただければと思います。

# タイトル等
## タイトル
de:code 2018 [AI14] Azure Machine Learning services で実現する Deep Learning によるテキスト分類
## 演者
得上 竜一さん　株式会社PLAN-B
## 日時
2018/05/23 11:00-11:50

# 概要、感じたこと

機械学習と言えば、画像判定ということがどうしても多くなっていますが、実際の業務でまずは導入しやすいのは、文字に対する機械学習ではないか、と思っていましたが、その考えを後押ししてくれるセッションでした。

また、実際に精度を高めるプロセスを行うためには、**精度を測るということより、精度を測れる状態にするということが大事である**、という考え方は胸落ちするものがありました。

実際にデータの精度を高めて行くプロセスも含めて、今日からでも実践できるので、どんどん試してみようと思います。

また、Azure Machine Learning StudioをMirosoft Azureを使用しないで、Tensorflowを使用する目的でも使えること。最終的に動作させるときに、Dockerコンテナではなく、Javaを使用して動かす、という考え方も参考になりました。

# はじめに

![はじめに](https://koavyq.bl.files.1drv.com/y4mKu4_1Fvzu2D2KxkNQ_iDGhnPSOzC181OrwwTE7KZkiifhYn9WPATjtialXWIYIIXpNEVSYU6gxenYpodD7xxnwQzbveORZMFDN2U_C9DlBJUicK_dfZqvRXVCshoXVjKGvoVntEVAddaQGOY-ENGiFp6x_OYDP6CqQFzUfALvnFC3meOw74v9MH8MN8LLPXAYyNspoGgtGfg4ju0k5P0GA?width=2493&height=1402&cropmode=none)

このセッションを受けた人は、次の言葉を覚えて帰ってほしい！

## Deep Learningって、画像だけじゃないんですよ。テキストデータならうちにもあるし、なんなら、私やり方も知ってますよ。



# 今回の例

![例](https://l4cwpq.bl.files.1drv.com/y4mEBT-gQqMvRvf1w5f6h9AEWFO6RIil1WIg0Ve0OH52GDn734q3FpW5V7Uou4z5QOe0g6K30CdL2DhGia277x7McBYr7VqzbLHrxTKsaO73TAP3N1Jbr36427wEvWDEvEat55QzakSnRAgc0WmxdXBATHVXd4ocFah0TrLXJeYi8C6-NhAFydTLw4nLYNiwf0rjAhV-Z3C3g-PTNgxswXJjA?width=3224&height=1814&cropmode=none)

DMP＝広告配信ビジネスについて、自動的に収集できるWeb行動情報だけではなく、アンケートも利用して広告配信ビジネスを行いたい。

もともと別件で機械学習を行っていたが、こういう案件が上がってきた。

## 推定されたデータと確実なデータ

98%のWeb行動情報など大抵はインターネット上から得られたデータとなるがこれは推定されたデータとなる（クッキー、ブラウザの個別情報）。

2%については、アンケートから得られたデータと繋がったデータとなっているので、これを確実なデータとしている。

Webの行動データとアンケートがつながった確実なデータが全体の2％しかない。そのため残り98%について、年齢と性別をどの様に推定するか、ということを行いたい。

## 今回の作成方法

Azure Machine Learning WorkBenchを利用し、IDをベースにして、どの年齢なら、どのアクセスをしているかというデータを作成していく。

# Azure Machine Learning WorkBench


![TDSP](https://kib6va.bl.files.1drv.com/y4mfqXKy-T47Tg9K5liqlq2Wm2a934y_qvxYNZIqaVN4Ko9gbVs9Zqvf4xG9mj_ppMZ39vSs2PkgWZg3B8o9x20QuB9bQE7INPdmUMBPRp0tAlskEQxB49KKhVFZ_4233s5JCFJ2hDg2iVIdMI-KVd45aMe_E0g1HPp133n7USyk045QdFho2EuKGrS3WHsb0MBaGoypJVnaw3gF2MLBZ0_jw?width=2896&height=1629&cropmode=none)

チームでデータサイエンスをどのように進めていけばよいかということを示したTDSP(Team Data Science Process)プロジェクトがWorkBench上で作成できるので、これを参考にすれば良い。

![違う](https://iybeaw.bl.files.1drv.com/y4mAlGuIo2qO_B-rTDa4jWOSTjp_KmzrEJcj_6LdN5OTZWO7fluEIfpkh4xXY5jP8va13omVJgfJ2J70ycuoMCDbprdy--Qqz168QS4kvHyniLFL06obVLfFJjCobBnoo2b3XTFQ9aeChzv-T8zcJy1XXxDhlzFMm2Iw3zBt6kOi0grJOhh4fdi29u6MUtuQMV4rAOGi_uJVr63vMmzgZs7cQ?width=3278&height=1844&cropmode=none)

Azume Machine Learning StudioとAzure Machine Learning Servicesはイコールではない。

Azume Machine Learning WorkBenchは、ローカルで実行することもできるし、クラウド上でも動かすこともできる。Tensorflowの実行を行うこともできる。クラウド上の操作ツールとして使いやすいツール

データを見ながら、データの取り込み、加工処理（抽出も）を行うことができる。途中でヒストグラム、データソースのジョインを表示することもできる。

# Modelingで行うこと

Modelingには、TensorFlowを利用する（Azure MLではない）。普通にサポートされている。

![Modeling](https://kiavyq.bl.files.1drv.com/y4mY6qYiMFyTgWgGHTSzv35R8APzl6l4sYjpQKBm_ueMmGHc3Hne1JdFORi4HvI7zzkP-BdBgqSR00XpuTJN32XME3CCEvhJ4_jLVqdFCSbsy5BNwNUkkGmEZM6rqMxxglr77IRyIBx63ASZsF1F_A8e20yN6oFn3w1hAtd03txq6xL5F7YDGrCOL-AvVoeto4bAsdKlvPSDQ9X87grcs25Ug?width=3657&height=2057&cropmode=none)

Modelingでは以下の手順を行なっていく。

1. データをNewral Networkに入れやすい形に変換
2. まずはSimpleなNewral Netowrkを作ってみる
3. 精度を測る
4. 層の追加やパラメータの調整
5. （必要があれば）データの追加
6. 3.4.5の繰り返し

まずは、精度を測るということより、**精度を測れる状態にするということが大事である**。つまり、実際にモデリングの精度を高めていくには、前述の3.4.5の繰り返しを行うための環境づくりが大事である。


# Demo

* ノートブックを使っていく
* インストールには30分かかるが、30分後にはクラウド関係なく使用できる状態になる。Pythonのノートブックなどが使える
* CNTK、CNDKをバックエンドにすることもできる
* データを読み込む際には、Generate Data Access Codeで作成したコードを張り付けると、コードの作成を簡略化して、読み込むことができる
* 実際の判定方法としては、1文字ずつのコードにして数値化している。今回は100文字だけ読み込んでいる後はぶった切っている。


# Deep LearningとはInputとOutputの間に層を挟んで楽しむ雅な遊び

Depp Learningは、InputとOutputとの間に層を挟んで変化を楽しむ雅な遊びであり、すごく楽しい作業である。

シンプルな、ネットワークから、複雑なネットワークにしていくのが、非常に楽しい。


# 実際の解析の手順

## 概要

今回使う方法としては、Character Level CNN（畳み込みが特徴的なニューラルネットワーク）。

ここで問題となるのが、テキストは1次元なのに2次元にできるのか？というところ。そこで、N-gramという方法を利用し、テキストを３文字ずつに分けて、3文字の数値にすることで画像と同じ扱いをできるようにする。

## シンプルなNewral Network

![シンプル](https://lob6va.bl.files.1drv.com/y4ml-UrB-uOMULXVzdeh0wwIgBG68LzvuxjTB8e8qTKqWvevfM8kFQoozqORCPzzu-T79NK5PicsgaYvcAfvwgrHG2PBMrTqhZgaQ7W-rt02iGIL6OzSd9JKCZDT5fjVA60tFEymw9hVls32Pf-vtzpbVHgkzBx-r7kG7nKVrgKkFVhH_moifHU_wm0BxmU0gFK9YZ56Z2pksRV2XOE0EyZgQ?width=3568&height=2007&cropmode=none)

まずは、間の層がないシンプルなネットワーク。この時点では当然判定の精度もコイントスと変わらない！

## 3Gramで文字を分割

![3gram](https://lib6va.bl.files.1drv.com/y4mnCMAWabGwsGCZcUuoRmDsnILXpuX42WrXOQ0MNUeyy1OG8fjD8RROMq_Y5Zx-RvtsroGFm_lOc4HJrxGJVLj6L9W71pkvPRNgl-IrSr7CbPHDpXIgL0HpDuvL7CHXhzznQ-4nbhi-jGSi8OAytRCEq6kP0deYILZqz8ZU8Mct8imPPJSEudh6Rrbi0sOEIIrxxuiDJguLMj1anGCHZDzgw?width=3188&height=1793&cropmode=none)

ピンクの文字の部分が、3Gramで分割するために追加したところ。この部分で、文字を3文字ずつに分割している。

### ネットワーク図

![図](https://lyavyq.bl.files.1drv.com/y4mvuFqrq2xuF3BZ-U0_u7eKs4XJteHH14Qy6H9G9k6kcB7WkKyX2ehKiwd0gR3qDpoz50pT9p28XTYvZ5YgqZi_7-rqk3_nVrFQC8rs0bofCCteGNuUzq6v65M9LEg9QvyS0SOttDJyxcW__fmeLIqdRKtdsuga32k-2cP34_1mvswuN6jwMWcQbMWtB3uMrYtwrs72dpgwYpTViNUdLpgMg?width=3287&height=1849&cropmode=none)

InputとOutputの間に、文字の2次元化などの層を挟んでいる

### 結果

![結果](https://kyb6va.bl.files.1drv.com/y4mr10UIfe7VKRUHxra8u-LOT4nOk1cPNvwnB1Yc0Zvcy8V-U4_DOySh02i36twlLNAnpJ8pQo4Hq8NPRmFIOrd-YTrnLxsr4-LOVLfQOIHZZ0IH0ka-y-C_islz3skkhsA_33q4KQ7WyVDnOb0NnpoXoIRy9U7e9rn6_aLEIj_07IiloKAK-z6adYgp4uUdnrUAlFVGb8hKLSpvfkd7ImDHQ?width=3219&height=1811&cropmode=none)

コイントスよりは良いが、まだよくはない。

* accurcy（判定の精度）

	精度は上がってきているが、まだ不十分。

* loss（損失）

	検証データでは問題なく損失が下がってきているが、テストデータでは、途中でグラフが上昇に転じている。これは過学習が発生している。つまり学習したデータについてのみOKな学習モデルとなっている

では、過学習となっているものについてどうすればいいか？の対策として、まずはDropoutを入れる。

## Dropout

![コード](https://kob6va.bl.files.1drv.com/y4mQ37omCdd_WoyBxGl0NoIb6mKqsN5uVOdZYr1OGZ0mkVNrVP0-7Bb4SCTzjLiqrGY927CM8Dx0FVbgWQpEdJ4E0GAztVCGhKzXARdU82aTYmXQhHAjbLncKXiRdGkHOXAD5z8_8nlvJAVN8ny5JnjpYNiLbwneYBiGGIKr-Uh42-omVnr9ABarlbjp3cPnqzTe-FLCX6LAkLkx2RSAICCTg?width=3246&height=1826&cropmode=none)

ピンクの部分で追加されたデータを入れると、一部のデータを捨てる（次の処理に渡さない）ということを行う。

せっかく入れたデータを捨てることになるが、ランダムに捨てることで過学習となったモデルが汎用化される層となる。

### ネットワーク図

![ネットワーク図](https://lyb6va.bl.files.1drv.com/y4mZ6aLgRSwlgySkfveOf-270KoAqrqiQ4jT1QgBTQd4738DKwwXRg4mEySqlPwVIJzxy62JfcRgkAn-dWreFnqxBBiXS2vSTNuMlpX7uMYysSMuVLbKqi4fNnuMc0nlhE-Q2PE4QEGdkHD4F5pvRcT_JOyEhpAGnaO2g3vHT7_Jw4-hyr-mmkK5yTGD4tLUk3qDwpQydUYjXGsT7WRYSVElg?width=3191&height=1795&cropmode=none)


Dropoutを入れることで若干良くなったが、これでも足りないので、Batch Normalizationを行う。



## Batch Normalization

![コード](https://liblsg.bl.files.1drv.com/y4m858c_XmqQCmaM8Wggt_eI5nb5QyyAv6aUHZK1GUVu6-71sZZC_fhrUVDgkEv-nXArwq2vMa10t4O8IHpHAmcTEygo1NKSfIlB6kSrXsF4BnRWj-5QMAPQFgyPNgevQeNSVS3dqpEvoBldZR_QKFIcMqMsrvF5qGQaZzdZFOHwOo9TrLAXb1zYhBbTDeBu8WAqKdnleiW5CJaFS6tD88SLg?width=3538&height=1990&cropmode=none)

Batch Normalizationは画期的な層であり、学習進行や過学習対策として効果的である。

（筆者補足）Batch Normalizatinは、2015年に提案された画期的な手法で、次の特徴があります。これらの効果により、ディープラーニングの学習にかかる時間や、パラメータ調整の難しさを軽減することができます。
* 学習を早く進行させることができる（学習係数をおきくすることができる）
* 初期値にそれほど依存しない（初期値に対して神経質でなくても良くなる）
* 過学習を抑制する(Dropoutなどの必要性を減らす)

### ネットワーク図

![ネットワーク図](https://iycwpq.bl.files.1drv.com/y4mHfNYNko9fAjA5hLqHyuaPlGGbmgf75i0wFwsaauVik-pVsylXeVQ8BAL8ExImjeIVr8p-Prn3ConCNJvA_jyYr4qi3VLLt7L-O3AW_85UBUraM73TVD7NI8s0wJn57zU-IO6vnxBKefdYS1QEGq4aBsmG5WsDUaVPGm_PWj9svPTFnWsLXrZPfOCXPijsONdHOWdR4THNJ_qoULSHDSypQ?width=3377&height=1899&cropmode=none)

### 結果

lossのテスト結果が右肩上がりはダメだが、右肩下がり、または並行になればいったんOKである。


## Inputの近くにDropoutを追加

### ネットワーク図

![図](https://iyavyq.bl.files.1drv.com/y4mTo7gnGuBaW6jXy2dqkuX_4h9JJhxW5Uta4VZNVGtZOsmCT3whhT3HQmdaKaRhoL7kmSocVwrJPSyhoQD9-XfX4O3SBk8rR2B0bEbHkKzcsubAT01EZomMBW3hOfA5UQyJkUViC4opzS7aTYVG3GOiZtN-fKw2j7t0jMfnKvBDC8wh42aE_Izwd-DfpaeOXbMIXh0tKJckunxB11wjgc_Xw?width=3774&height=2122&cropmode=none)

Input近くに1個、Outputの前に1個、真ん中に1個という形が大体の場合において理想的である。

### 結果

![結果](https://l4b6va.bl.files.1drv.com/y4m8ZF5--9Cp4wLgGpTN_YptjDczTsa8UQ7Azqu4iLgkRdJI7y-WEfMnzy_Y1OEeWnNaH5MLRJgWVWKCcLqKqLp-ObKUOnTshtIdZOUanOQaNK02LCptVI52Vuflf4onjBaBJAb0RNSQdaFNBg57cZCl6_V8abeRKroNhhaLhXLwQj09RV8eNwpr4odZVPagcsK0Zz4EjLuMjVALZ_Hmc6JXA?width=3180&height=1789&cropmode=none)

lossのほうが下がっていく傾向になると、使えるモデルとなる。データ量を増やすのはそれから行った方が良い。

つまり、ある程度妥当なモデルになるまでは、むやみに回数を増やさずに、少ない回数で試行し、いいモデルになってから回数(epoch_count)を増やすということをやったほうが効率的である。

#### 補足

* epoch_count

	最初にやるときは、10,20,50を試すと良い。

* early_stoppingを使えば、学習精度が悪い時には止まってくれる

* Workbenchを使えば、ローカルでNotebookが使える


## 3Gram + 2Gram

使用するデータとして、3文字ずつ切り出したデータに加えて、2文字ずつ切り出したデータも元データとして利用し、結果を確認してみる。

### ネットワーク図

![図](https://kibeaw.bl.files.1drv.com/y4mOyEGpJWXiW_ttv7IP2BW6y8ZYzEtURbKlZge8duh4UNQ9I9FgcF9XEMshPeYb5HJSQV26aaKL-YJAheYNtgGFa39VGaUEASjoaaxVdBXd0rYmtCrUcclL9pWl4mDGmykjzUPsriB3te9Ggw7Ds5wNuVDdPcWUCI3LhQGPUaJ2cKAcWHhHxbo0NdG6-wp9VVG9SF8ocqNGrbe934cNiq5qg?width=3158&height=1776&cropmode=none)

### 結果

![グラフ](https://iibeaw.bl.files.1drv.com/y4mHDLswMNArWvtR6RpEhsx9kYMMbTuMDUjyYjfmPD6Sg2AOFF9ajf2LYGWMG-N2jZfC2ikg-jDYrRUlfgBoSq3ER4o5bUKo69jSdvNMsgeRw93mlVeuBN8ptZfe0by0-tQARLLYL2X4Pg26cz5Ift6DU4-BNXhfD3X-GwFId1N8yU62c7dkNGEXuas7C01RK1MOslJ9Y6hB-QZiiFSGdbghg?width=3213&height=1807&cropmode=none)

結果が上下動する結果なので、あまり良い状態ではない結果となった。

# これが最適とは全く言えない

前項までの結果では、**これが最適とは全く言えない**、というようなことを繰り返していくのがチューニングである。

様々なパラメータを繰り返し、一番Accuracyがたかい設定を探っていく。

方法としては、回数、人数をかけるということになる。いろいろな手法（後述）が出ているが、これ、というような方法はまだ出ていない。

機械学習においては、AIだけではなく、周辺の技術や、数学的な考え方についても学んだ方が、考え方が広がる。

## 手法の紹介

### GridSearch

とにかく全部のパラメータについて総当たりを行い、良いパラメータを探る方法

### 複数の組み合わせ

1個だけの精度ではなくて、別の精度算出方法を使用して、良い方法を比較する。いわゆるマギシステム。

### マルコフチェーン

調和平均。2択の問題であれば揺らぎながらも妥当な結果となる。


# Deployment（実際の実行）

## Docker コンテナによるポータビリティ

![Docker](https://kybeaw.bl.files.1drv.com/y4m5ta1Tx3kBmF-c6tGpIihCVP0CvGjwPRifam_N_OqKzw1sSrXA12lIaEKfMrRxs5o4LFnTZE4sYsUUraFAs6ZIaTVvEVv-mWrd79jSzNByjSRVmzd25g9XUBcDowyuITCPj81JirA2oxKBoNCstISz2F7LAbe8FerNcmUiUHqI1pCYSE1e121w-Pkg12BpxnDVr5Or9paRMzp-fY8smrQeA?width=3391&height=1907&cropmode=none)

学習モデルについて、Dockerコンテナによるポータビリティが行える。

しかし、演者としては推奨していない、とのことだった。理由としては、簡単なモデルでも2GBになってしまうので、別の方法があるならば、少々重すぎる方法ではないか、とのこと。

## Java Run Anywhere

![Paas](https://kyavyq.bl.files.1drv.com/y4m4zTI3H69dRh6q3OZa9eNxP5lpA3cJhH-GcF9GjEU1DZTILWpfQMuXKjhFC3wu4sYNXIg-l8sSw6aPss1OweXrTObQZHGZAkrUFab5w-pa2sc1Z0czeW0ljgR7f8cw_0ZS8U6vPO5iuJYwC-3Ys_VtUZLQ2uK4K20Nzx0GOKcRhWaKGHpEWSao9KkflehefYe3oyQ41yY9EFOSaJa_ZJmAA?width=2939&height=1653&cropmode=none)

TensorflowはJavaでも使えるので、Paasに乗せてしまえばよい。

実際にやっている環境の話だが、4GB 2VCPUでOK。テキストであれば、GPUまで載せなくても、CPUでも十分である。Javaは最適化されるので1時間で200はさばけている。

考え方として、とにかくDockerコンテナという方法に走らず、TensorflowのBindingできるやり方（Java、JavaScript）を検討した方が良い。

#最後に

## 協力

一人でやることもできるが、検証はアウトソースにでもやるでもよいが、モデリングはいろんな人で協力しよう。

## 宿題

帰ってから、早速やってみること。

Azure Machine Learning WorkBenchをインストールし、日報でもなんでもいいので、まずはテキストを探してやってみる。もし何もなければ、青空文庫、Wikipediaなどはいいデータである。

たとえば、日報からネガティブな報告なのか、ポジティブな報告などを２択で判定してみるのも良いし、問い合わせについて、これはクレームなのか、そうではないのかを判定してみるのも良い。

判定に使用する機器としては、タブレットでできるレベルである。文字は画像に比べて軽いので、まずはやってみること！

### 参考情報

![図](https://iyblsg.bl.files.1drv.com/y4mnSwsf3g7suqXtXHBNm3Z_4bbwkf1G_pjQInn8a2H7fZwDUqA57gCUYHqoG2JRPPVya8P3y00LDipDJHWcML5_VFEocigGjGIDk4bszVWz0A7PHHIs1qx0r7zuGFp9tLvrSauEJ4T_vW7YgtO0AhRwjMRjsMCxRuzSzHBIhRsdiuQPa8TvlwGROC_UiCcmic3e1WnjsY2HwtfqULDu7r5eA?width=3577&height=2012&cropmode=none)

* [Team Data Science Processとは](https://docs.microsoft.com/ja-jp/azure/machine-learning/team-data-science-process/overview)

* [クイックスタート：Azure Machine Learningサービスのインストールと基本操作](https://docs.microsoft.com/ja-jp/azure/machine-learning/service/quickstart-installation)

* [Azure Machine Learningサービス（プレビュー）のドキュメント](https://azure.microsoft.com/ja-jp/services/machine-learning-services/)

* [Character-level Convolutional Networks for Text Classfication](https://papers.nips.cc/paper/5782-character-level-convolutional-networks-for-text-classification.pdf)

* [Installing TensorFlow for Java](https://www.tensorflow.org/install/install_java)

# お願い

帰ったら、次の言葉を組織の人に言いましょう。

## Deep Learningって、画像だけじゃないんですよ。テキストデータならうちにもあるし、なんなら、私やり方も知ってますよ。

![画像](https://lycwpq.bl.files.1drv.com/y4mvvDkXmSnlKJphYhmKm9epSc7IsdLUI6wAhl3D6hSBWnEPWOwHLBwVUykKwIPrYmFE4d86R0Zuv3SqTC2PsmL-oOoX2GQsp--tDf_3h_Q20Pe7k5L4rf39xLmPW4NsSVCBuHpOdwIzg4SOY0v-I_LOMQ5x4rOtup-dinVf4xqR_pJzfYKIgzbh70B9gqrpYTDrgPoaKXkmX3_NoFQIWZgCQ?width=2614&height=1573&cropmode=none)