Azure Machine Learning でいきなり機械学習

GYAO の kenharad です。

今回機械学習について全く知識のない自分が
いきなりAzure Machine Learning（以下AzureML）で機械学習を実践してみました。
経験なしでもさくっと機械学習を行うことが出来たので、その内容をハンズオン形式で紹介したいと思います。




# 目的
* Azure Machine Learning の使い方を身につける。
* 結果の良い/悪いが判断できるようにする。

# 概要
機械学習ではまず最初に予測があり、それを実証するために実験を行います。
今回はAzure MLを用いて、「あるWebサイトのPV数に天気が影響しているのではないか」という推測を元に
それぞれのデータの相関関係に有意性が存在するかを調べてみます。
これが実証されると、天気予報からWebサイトのPV数が推測できるようになりそうです。

# 前提条件
Azure のアカウントを所持しており、ログインできるものとします。
:information_source: Azure 自体の説明については他のサイトを御覧ください - [ヤフーでAzureを検索](https://search.yahoo.co.jp/search?p=Microsoft+Azure)

# Azure Machine Learning の起動 
Azure Portal にアクセスします - https://portal.azure.com/#

AzureML 用のワークスペースを作成します。
「新規」->「Intelligence+analytics」->「Machine Learning ワークスペース」をクリック
![スクリーンショット 2017-01-10 12.36.44.png](https://qiita-image-store.s3.amazonaws.com/0/156783/860e24c3-bb6c-d648-da68-f5a0377cb39e.png)

以下のように適当に項目を埋めて「作成」をクリック
![スクリーンショット 2017-01-10 12.39.46.png](https://qiita-image-store.s3.amazonaws.com/0/156783/41a1c872-3d59-9fce-5aeb-83e4e6d2d763.png)

「Webサービス プラン価格レベル」については、今回はテストのため一番安いものでOKです。
作成すると毎日課金されるので、ハンズオン終了後不要であれば削除しましょう。
　
作成には数十秒〜数分程度かかります、完了まで待ちます。

作成完了後、「すべてのリソース」から作成したワークスペースにアクセスできます。
作成したワークスペースをクリックしてください。
![スクリーンショット 2017-01-10 12.44.29.png](https://qiita-image-store.s3.amazonaws.com/0/156783/37e74aa5-7963-77b2-d041-6d07e5a1f4d5.png)

続けて 「概要」->「Machine Learning Studio」をクリック
![スクリーンショット 2017-01-10 12.47.30.png](https://qiita-image-store.s3.amazonaws.com/0/156783/fd0280e2-4a79-427e-7f75-a0c98c74923a.png)

「Microsoft Azure Machine Learning Studio」がブラウザで開かれます。

ページ右上の「Sign in」をクリックし、Azure ログイン時のアカウントでサインインします。

 
# 実験の準備
## 実験の作成
AzureML にはいくつかの実験サンプルが用意されています。
最初のうちはサンプルの動作を確認しつつ身に付けていくのが手っ取り早いのですが、今回は1から作ってみたいと思います。

画面左下の「＋New」をクリックします。
メニューが現れるので、左側から「EXPERIMENT」を選択し、「Blank Experiment」を選択します。
![スクリーンショット 2016-12-20 16.26.01.jpeg](https://qiita-image-store.s3.amazonaws.com/0/156783/3772f3ba-f3f7-7352-6268-7f3cdc468598.jpeg)

| :information_source: |
|:--|
| 既存のサンプルをロードして必要な箇所のみ修正するほうが手間がなくスピーディーですが、 今回は1ステップずつ確認しながら構築するために、あえてブランクから作成しています。  |

以下のような画面になります。
この画面に必要なデータ、フィルタ、計算モデル等のロジックをドラッグ＆ドロップで配置することにより、
実験を作成することができます。
![スクリーンショット 2016-12-20 16.27.47 (1).png](https://qiita-image-store.s3.amazonaws.com/0/156783/7e21af64-2430-c661-414f-8ebda96e8246.png)

タイトル（「Experiment Created on XXXXXXX」と書かれているところ）はわかり易い名前に変更しましょう。

## データの配置
今回は概要に記したように、WebサイトのPV数と天気（雨量値）の相関関係に有意性が存在するかを調べてみることにします。
まず某サイトのPVデータを用意してみました、以下のようなCSVデータです。
<img width="226" alt="3d2035cf-93ca-8871-462e-54dd01c29abf (1).png" src="https://qiita-image-store.s3.amazonaws.com/0/156783/063182d0-dc18-bbb1-9d92-17e9d7d57b71.png">

| :information_source: |
|:--|
|  ※ この時、1行目はカラム名を、2行目以降をデータとしてください。 カラム名には日本語も使用できますが、文字コードはUTF-8を使用してください。 データフォーマットにはCSV,TSV 等が使用できます。 |

次に天気データを用意します。
今回は天気データとしてアメダス雨量データを用いることとしました。
アメダス雨量データは以下からダウンロードすることができます。
http://www.data.jma.go.jp/gmd/risk/obsdl/index.php

ダウンロード直後のデータではそのまま使えない内容となっているので、不要な項目を削除したり、
フォーマットをあわせたりして以下のような形式にデータを整形します。

<img width="218" alt="スクリーンショット 2017-01-10 14.27.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/156783/3349765f-f4f6-f189-c266-bfbd6c2e3235.png">

次に用意したデータのアップロードを行います。
AzureMLメニューの「DATASETS」 -> ページ下部「+NEW」 -> 「FROM LOCAL FILE」を選択し、ローカルから用意したデータをアップロードしてください。
アップロード時にはデータのフォーマットやヘッダの有り無しをオプションで指定できます。
![スクリーンショット 2017-01-11 16.38.26.png](https://qiita-image-store.s3.amazonaws.com/0/156783/20804b7b-30ea-02cf-094a-f3e6822a36b2.png)

データをアップロードできたら準備完了です。
いよいよ実験を作成していきます。
画面左側「Saved Datasets」→ 「My Datasets」を選択し、その中からPVデータ、雨量データをD&Dします。
![スクリーンショット 2017-01-10 14.44.12.png](https://qiita-image-store.s3.amazonaws.com/0/156783/00349b16-fc53-0e89-93c1-87e3dc6213f1.png)
 
データの中身は配置後に右クリック → 「Visualize」で確認することができます。
この時点でデータの最小値、最大値、平均値、分布等を確認することができます。
![b80346fb-b89a-5e57-2956-b8bdc2c6ea60.png](https://qiita-image-store.s3.amazonaws.com/0/156783/f7181085-c010-b101-a02e-10e9adcb824b.png)
![90a13390-6999-43e9-9602-548501850d8e.png](https://qiita-image-store.s3.amazonaws.com/0/156783/01117f1d-4c3c-834b-4ccb-c342af4b0e2e.png)



## データの前処理
それぞれのデータをマージするためのロジックを記述します。
画面左「Python Language Modules」→ 「Execute Python Script」を選択しD&D。
それぞれのデータから線を引っ張りスクリプトへのインプットとします。
![スクリーンショット 2017-01-11 16.55.46.png](https://qiita-image-store.s3.amazonaws.com/0/156783/1dff6ad0-6267-2878-eb46-9ef49b286683.png)



スクリプトモジュールをクリックし、既設関数内に以下のコードを追加します。

```py:sample
    # date をキーとしてデータをマージ
    dataframe1 = dataframe1.merge(dataframe2,on='date')
```

ここでは例えばPVが10以上のものだけを使う

```py:sample
    # PV が１０以上のものだけを取得
    dataframe1 = dataframe1[dataframe1.PV >= 10]
```
などのコードを記述することができます。

## データ分割
マージしたデータを学習データとテストデータに分けるモジュールを配置します。

| :information_source:  |
|:--|
| 学習データはデータから有意性を見出すもので、テストデータは見出された有意性に合致しているかどうかを判断するためのものです。 このように一定量のデータからパターンを導き出し、それ以外のデータがパターンに沿っているかを確認する手法を「教師あり学習」といいます。　 |

画面左「Data Transformation」→ 「Sample and Split」→ 「Split Data」をD&D。
スクリプトモジュールから線を引っ張りインプットとします。
![スクリーンショット 2017-01-11 16.54.06.png](https://qiita-image-store.s3.amazonaws.com/0/156783/095da0be-47f5-06a5-e454-605212da8956.png)


画面右の「Fraction of rows in the first output dataset」にて学習データとテストデータの割合を変更することができます。

ここまでの流れを一度実行してみましょう。
実行前に画面下部「Save」をクリックし実験内容を保存します（エラーがあると保存できないこともあります）
「Run」をクリックすると実験が実施されます、エラーがあると途中で停止するので適宜修正してください。

| :information_source:  |
|:--|
| マウスで一つ以上のモジュールを選択し、「Run selected」を選択することで、指定したモジュールのみ再実行できます。  |


最後まで動作したら「Split Data」を右クリック → Visualize で確認してください。
二つのデータがdateをキーとしてマージされたことが確認できると思います。
![938e0b71-d5a5-b91c-7fdf-2408e9bb3115.png](https://qiita-image-store.s3.amazonaws.com/0/156783/cba120c5-b8ac-c0d1-e900-499135668a27.png)

※ この時 rows が元データより少ないのは、データが二つに分割されているためです。 

## トレーニング
学習データが用意できたので、学習モジュールに突っ込みます。
今回モデルは線形回帰を使います（機械学習はとりあえず線形回帰で有意性が出るかどうかを確かめるのがいいそうです）
機械学習の種類については他のサイトを参照してみてください。

「Machine Learning」→「Initialize Model」→「Regression」→「Linear Regression（線形回帰）」をD&D
![スクリーンショット 2017-01-11 16.52.30.png](https://qiita-image-store.s3.amazonaws.com/0/156783/c28f5b9f-9c00-5fb5-47c1-06e05540973a.png)


「Machine Learning」→「Train」→「Train Model」をD&D 
※ 線形回帰はこれを用いますが、クラスタリングや異常検知の場合は他のトレーニングモデルになります。 
![スクリーンショット 2017-01-11 16.50.37.png](https://qiita-image-store.s3.amazonaws.com/0/156783/b3e85d5c-fb23-9691-1997-ab2e9d93a701.png)


 「Linear Regression」と「Split Data」をそれぞれ「Train Model」に接続し、画面右の「Launch Column Selector」から
任意の「抽出したい値」を指定します（今回はPVにしておきます）
![スクリーンショット 2017-01-10 15.28.18.png](https://qiita-image-store.s3.amazonaws.com/0/156783/2c1483f6-0816-4f29-f476-6c9279394e5a.png)

## 評価
トレーニング →スコアリング→評価　の流れは基本的なものでどの実験でもこの流れとなります。
よって以降は特に意識せずそのままモジュールを配置してください。

「Machine Learning」→「Score」→「Score Model」をD&D
「Machine Learning」→「Evaluate」→「Evaluate Model」をD&D
それぞれのモジュールを線でつなぐ
以下のようになると思います。
![スクリーンショット 2017-01-11 16.47.42.png](https://qiita-image-store.s3.amazonaws.com/0/156783/bcdc32c5-f057-4aae-5e2c-70f116024630.png)


## モジュールの追加
データ内の date カラムが集計結果に影響を与えていたため、計算内容から除外するモジュールを追加しました。
「Data Transformation」→「Manipulation」→「Select Columns in Dataset」モジュールです。
date以外の集計に必要なデータ（PV, rain）だけに絞ります。
![スクリーンショット 2017-01-11 16.45.32.png](https://qiita-image-store.s3.amazonaws.com/0/156783/d11e1b91-fa3f-251b-501d-0781d9460490.png)


# 実験

実行してみます。
エラーが発生した場合は適宜修正してください。
最後まで実行が終わったら、「Score Model」のアウトプットをVisualizeで確認します。

入力データとそれに対するスコア（予想値）です。
このケースでは雨量値（2列目）に対し予想されるPV数（３列目）がスコア値として表示されています。
この結果から、学習結果としては雨量が高いほどPVが高くなるという結果になっているようですが、
実際のPV値（１列目）と予測値（３列目）を見ると乖離があるようです。
![21f752b2-8f45-0b3e-9d43-ac953903b62c.png](https://qiita-image-store.s3.amazonaws.com/0/156783/ed0e6a33-4a37-5955-dc20-02ea72067560.png)


上記画面で適当な列をクリックすると画面右にプロットグラフが表示されます。
以下ではPV列を選択した後、プロットグラフ上で「compare to Scored Labels」を選択しています。
PV と予測値（Scored Labels）は予測が当たっていれば近似値をとなるはずなのですが、ばらばらに見えます。
![ac249af0-6f39-c4e7-0616-14abc45d6569.png](https://qiita-image-store.s3.amazonaws.com/0/156783/08759159-1896-f882-a0d7-dba0e0399b20.png)


実験の精度は「Evaluate Model」モジュールをクリックし、「Visualize」で確認することができます。
一番下の項目が1に近いほど精度が高いといえるそうです。
![スクリーンショット 2017-01-10 16.06.32.png](https://qiita-image-store.s3.amazonaws.com/0/156783/8e560bb2-7968-37fe-8611-a4d7051cfac6.png)

この結果から察するに、天気がPVに及ぼす影響は低く、
それ以外の外部要因の方が影響度が高いと予想されます。
また、今回はデータからノイズを除去する作業を行っていないため、実験内容を精査することで、
違った結果が出てくる可能性もありそうです。

:information_source:  出力結果の意味と値

| 名前 | 概要 |
|:--|:--|
| Mean Absolute Error | 平均絶対誤差、0に近いほど良い |
| Root Mean Squared Error | 予測値が正解値からどれだけ離れているかを示す。0に近いほど良い |
| Relative Absolute Error | 相対誤差 |
| Relative Squared Error | ルート相対二乗誤差 |
| Coefficient of Determination | 決定係数、特徴ベクトルが正解値をどれだけ説明できているか。高いほど良い |



# 考察

今回は予測と異なる結果となりましたが、予測と異なる = 失敗ではありません。
「予測していた結果と違った」ということが分かっただけでも収穫ですし、この結果を参考に実験の内容を磨き込みしていくことで
より実験の精度を高めていくことが出来ると思います。

今回の例では、サイトのPV数と天気という単純なものでしたが、
以下のようにノイズとなりそうな要因を見つけ出し、１つずつ排除していくことでより指向性の高い数値が出てくると思います。

* 特定の地域のPVと天気に絞る。
* 日中の活動時間帯だけに絞る。
* 曜日を考慮し平日は除外する。
* 気温も考慮に入れてみる。
* 季節要因を加味する。
* 外部イベント的な要因を排除する（重大事件が起こった日、外部サイトからの流入が極端に多い日等）

また、天気以外のデータ（曜日等）とPV数の相関関係を見るのもおもしろそうですね。

今回はここまで。
AzureMLが用意しているサンプルにはもっと複雑な多くの実験がありますので、興味を持った方はサンプルを動かしてみると良いと思います。


# リンク

[Microsoft Azure](https://portal.azure.com/#)
[Microsoft Azure Machine Learning Studio](https://studio.azureml.net/)