Azure Machine LearningによるY!映画のレコメンデーション

## はじめに
Azure Machine Learningにはマイクロソフト社独自のレコメンドの機能（Matchbox recommender）を使ってY!映画のレコメンデーションモデルを作成してみたいと思います。


## Y!映画のレコメンデーション
以下はY!映画のレビューの評価点数を使い、協調フィルタリングを行う手順です。


### データ
協調フィルタリングで必要なデータは「ユーザ、映画タイトル、評価点数」の３つです。

例）

| user       | title | score |
|:-----------|:------------|:------------|
| user001    | 君の名は。     | 5     |
| user001    | シン・ゴジラ    |  1    |
| user002    | 君の名は。     | 3     |
| user003    | オデッセイ     | 4  |
| user003    | アバター      |  5    |

※scoreの形式はintegerです。範囲は1から5で大きな数字ほど評価が高くなります。

今回は以下２つのcsvファイルを用意しました。
モデル作成の過程で２つのファイルを結合し、上記の形に整形します。

*cinemaid.csv*

| id       | title       |
|:-----------|:------------|
| 355058       | 君の名は       |
| 354182       | シン・ゴジラ       |
| 351301       | スター・ウォーズ／フォースの覚醒       |

※レビュー投稿数が多い映画タイトル3,000作品をサンプルとして抽出してます。

*movie_review.csv*

| user       | id | score |
|:-----------|:------------|:------------|
| user001    | 355058     | 5     |
| user001    | 354182   |  1    |
| user002    | 351301     | 3     |

※上記の映画に書かれたお役立ち度の高いレビューが約28万件でユーザ数は約8万件です。


次のステップへ行く前にローカルにあるcsvファイルをアップロードしておきます。

```Azure Machine Learning Studio > DATASET > ページ下の+NEW``` の順にクリックしファイルをアップロードします。
<img width="717" alt="スクリーンショット 2017-01-13 13.44.53.png" src="https://qiita-image-store.s3.amazonaws.com/0/113045/bc2503a0-e4f6-e602-b81e-bf1b4644e96a.png">

### モデル
```Azure Machine Learning Studio > EXPERIMENTS > ページ下の+NEW > Blank Experiment```の順にクリックし新規に実験を作成します。

実験名は「Test Movie Recommend」とします。
左の実験のメニューから必要なアイテムをドラッグドロップして以下のように配置します。

<img width="610" alt="model.png" src="https://qiita-image-store.s3.amazonaws.com/0/113045/1f427568-9f1b-0de6-6fdb-75a2ca836719.png">

各モジュールの説明をします。
基本的な配置は分類や回帰など他の機械学習モデルでも同じになります。

#### データの配置と前処理
先ほどアップロードしたファイルを以下から探し、ドラッグ＆ドロップで配置します。

```Azure Machine Learning Studio > Saved Datasets > My Datasets```

>ローカルのファイルではなくAzure StorageやAzure DocumentDBからインポートする手順は場合はこちらを参照してください。
[Azure Machine LearningとAzure Storage／DocumentDBを連携させる](http://qiita.com/snomoto/items/395c6fd6914fcad631a8)

<img width="312" alt="スクリーンショット 2017-01-13 13.51.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/113045/b0841341-1954-3a51-d5f6-3b417966ab31.png">

下図の部分をクリックしてVisualizeから詳細を確認できます。
<img width="357" alt="スクリーンショット 2017-01-13 14.07.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/113045/c48e346c-87f3-e5da-3df7-44a2f4fd908e.png">
*movie_review.csv*
<img width="468" alt="スクリーンショット 2017-01-13 14.10.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/113045/9770380d-db3c-4890-870d-02a817f7b15d.png">
*cinemaid.csv*
<img width="421" alt="スクリーンショット 2017-01-13 14.10.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/113045/774edd4f-c3bf-0725-f84f-408c88ea6f90.png">


次に2つのファイルを結合し、```user、title、score```の３つのデータを抜き出します。
また```user、title```がユニークになるようにします。
<img width="644" alt="スクリーンショット 2017-01-13 13.39.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/113045/8a92cc9e-ed05-cfd8-73a0-feae746dc060.png">

・Join Data
```Data Transformation > Manipulation > Join Data```
<img width="262" alt="joindata.png" src="https://qiita-image-store.s3.amazonaws.com/0/113045/513f2026-7fe0-4128-8a35-5c888d4e7201.png">

結果は以下のようになります。
<img width="755" alt="スクリーンショット 2017-01-16 17.25.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/113045/3237e8af-06c2-3df0-b22a-32faf8774e5f.png">

・Select Columns in Dataset
```Data Transformation > Manipulation > Select Columns in Dataset```から選択し配置し```user、title、score``` を選択します。
<img width="650" alt="select_clm.png" src="https://qiita-image-store.s3.amazonaws.com/0/113045/b3f97c08-6c8d-d4c0-a0a8-011d433e1d71.png">

結果は以下のようになりました。
<img width="573" alt="スクリーンショット 2017-01-18 15.57.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/113045/4ff3839b-8ac6-d9c1-c762-4a061698d344.png">
※USER001は確認用のダミーデータですが、それ以外は本物のデータなのでUSER名は伏せてあります。

・Remove Duplicate Rows
userとtitleがユニークになるようにします。
```Data Transformation > Manipulation > Remove Duplicate Rows```

<img width="263" alt="スクリーンショット 2017-01-13 14.24.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/113045/83c65ce2-2992-3222-1aeb-cc0d26ee3a9a.png">

#### 学習用データとテストデータのセットに分割
<img width="322" alt="スクリーンショット 2017-01-13 14.29.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/113045/8faa5e64-2955-1468-8ffb-90dd23b47a08.png">

```Data Transformation > Sample and Split > Split Data```

「Splitting mode」を「Recommender Split」へ変更し、学習用データの割合を0.75（デフォルトは0.5）、テスト用は0.25に設定します。
<img width="267" alt="スクリーンショット 2017-01-17 10.22.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/113045/66a7b6e4-be0d-d7f2-afbe-00fe12d2e4ff.png">


#### モデルのトレーニング
<img width="431" alt="スクリーンショット 2017-01-13 15.27.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/113045/84ff34fc-029a-7280-0d10-4a9805769d38.png">

先ほど分割した学習用データを使って学習させます。

```Machine Learning > Train > Train Matchbox Recommender```

パラメータは特にいじらずデフォルトのままにします。
<img width="232" alt="スクリーンショット 2017-01-13 15.16.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/113045/00817075-d9ed-df5b-5b32-d11601a6b711.png">

#### モデルの評価
Split Dataで分割した25%のテスト用データにスコアをつけて効果を確認します。
<img width="547" alt="スクリーンショット 2017-01-13 15.24.01.png" src="https://qiita-image-store.s3.amazonaws.com/0/113045/d7efc408-615a-9011-ea16-287fdf1a3d87.png">

```Machine Learning > Score > Score Machbox Recommender```
Train Machboxモジュールとテスト用データをつなぎます。
パラメータは特にいじらずデフォルトのままにします。
<img width="238" alt="スクリーンショット 2017-01-13 15.04.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/113045/f5fd79ac-576d-7169-4f62-3808b68bf436.png">

>レコメンデーションモデルの精度を評価する場合はRecommended item selectionの選択を「From Rated Items」にします。この場合は自分が評価した作品の中からオススメする作品が選ばれます。全てのアイテムからオススメされるようにするには「From All Items」に変更します。まずはモデルの評価を行いたいので「From Rated Items」のままで進めていきます。

```Machine Learning > Evaluate > Evaluate Recommender```
レコメンドデータとテスト用データと照らし合わせて誤差を求めるためEvaluate Recommenderを配置し、テストデータとScore Matchboxモジュールをつなぎます。

#### RUNを実行
すべて配置が完了したのでRUNを実行します。

#### 結果を確認
<img width="248" alt="スクリーンショット 2017-01-13 15.40.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/113045/d34435fc-92f1-075a-77c2-d6c43c47660a.png">
この部分をクリックし、Visualizeをクリックして結果を確認します。

<img width="469" alt="スクリーンショット 2017-01-17 10.28.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/113045/250f3d91-4905-2605-f4bf-55243fde0866.png">

NDCGはユーザへオススメされた映画がどれくらい適切かを表すもので1に近いほど精度が高いといえます。
今回はNDCGが0.947という結果でしたのでなかなか良い結果が出たと思います。

#### すべてのアイテムからレコメンドされるように変更
Evaluate Recommenderを削除して結果をCSVファイルに落として確認するためにConvert to CSVを配置します。
<img width="478" alt="スクリーンショット 2017-01-16 17.48.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/113045/5ab79c92-613a-c0d0-1229-7bd9eaf357a2.png">
配置が完了したら、Score Machbox Recommenderを以下のように修正します。

<img width="241" alt="スクリーンショット 2017-01-16 17.50.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/113045/f6733960-0b3d-01c8-780d-26ee273d996b.png">

RUNを実行し結果を確認します。

・USER001が点数をつけた映画
<img width="457" alt="スクリーンショット 2017-01-16 18.00.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/113045/022a7ad8-2886-0155-b834-5211963ca3f4.png">

・オススメされた５つの映画
「劇場版マクロスF　～サヨナラノツバサ～」,「マイケル・ジャクソン THIS IS IT」,「任侠ヘルパー」,「フラガール」,「ウルトラマンメビウス＆ウルトラ兄弟」
※優先度の高い順に並んでいます。

一部ですが、その他のユーザの結果は以下になります。
<img width="710" alt="スクリーンショット 2017-01-18 15.44.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/113045/947ffde1-3590-e268-9ff6-5333eb049659.png">


## おわりに
Azure Machine Learningでプログラムを一切することなく簡単にレコメンデーションモデルの作成ができました。
USER001の結果を見てみますと、評価した映画とは違うものがオススメされているのを確認できました。
しかし、ほとんどのユーザに対して上記と同じような映画がオススメされているのでもう少し精度を向上させたいと思います。
今回はTrain Matchbox Recommenderへインプットしたデータはレビューの評価点数だけでしたが、他にもユーザ属性（年齢、性別、好きなジャンルなど）と作品属性（監督、メインキャストなど）をインプットすることができます。
これらを使うことでより精度の高い結果が得られるはずなので今後試してみたいと思います。