Azure ML チュートリアル (Recommendation - Movie Rating Tweets)

# はじめに
前回に引き続き、AzureMLのチュートリアルをしていきます。
今回もデザイナーを使っていきます。

https://qiita.com/Kyoppy/items/5c80046900b53e79b572

# チュートリアル概要
今回のチュートリアルは、Recommendation - Movie Rating Tweetsというものになります。
このサンプルでは、レコメンデーションモジュールを使って、映画のレコメンデーションエンジンを学習させる方法を紹介します。
これにより、ユーザーの評価または、好みを使い、そのユーザーがどのような評価をこの映画にするのかというモデルになります。

# ブロックの説明
### 今回のデータ
今回のデータは映画のデータとユーザーの評価データを使います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629918/41b00c8f-6d81-f1a7-3285-7ec25a82e573.png)

#### Movie Ratings
ユーザーの評価データ
ユーザーがどの映画に対して、評価をしたかのデータが入ってます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629918/8941c038-b760-07b6-f6cb-e83fb5f6690c.png)

#### IMDB Movie Titles
映画のタイトルとID
IMDBの映画のデータが一覧で入ってます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629918/2bc7a7a9-0d16-5330-0018-45c11a48d671.png)

### Join Data
二つのデータセットをMovie IDで結合するブロックになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629918/c530662b-d340-bc04-52a2-74e4a16db0d9.png)
設定を上から解説します。
#### Join key columns for left dataset
左のデータセットの結合キーカラムを選択します。
今回は```MovieId```になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629918/d0534a20-a32c-cc16-e474-1ea4a77f118f.png)
#### Join key columns for right dataset
右のデータセットの結合キーカラムを選択します。
今回は```Movie ID```になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629918/955ffc40-2d69-90e4-f900-b700c488de7a.png)
#### Match case
キーカラムにおいて大文字小文字を区別した比較を行うかどうかを示す。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629918/da06ccc5-a668-ffaa-3e66-a7ebf7d54c62.png)
#### Join type
ジョインタイプの選択
* Inner Join：内部結合
* Left Outer Join：左外部結合
* Full Outer Join：完全外部結合
* Left Semi-Join：左セミ結合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629918/463e629f-0803-96fb-92ef-47f4706bbe46.png)
#### Keep right key columns in joined table
結合されたデータセットに、2つ目のデータセットのキーカラムを残すかどうかを指定する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629918/48360df3-e5db-eb36-82e5-762aba1f5846.png)

### Execute Python Script
今回のPythonの処理
レコメンダーモジュールが必要とする特定の順序でカラムを選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629918/6968ffc7-d6a9-d587-d712-ca19788569db.png)
コードはこんな感じ
```python

# The script MUST contain a function named azureml_main
# which is the entry point for this module.

# imports up here can be used to

# The entry point function can contain up to two input arguments:
#   Param<dataframe1>: a pandas.DataFrame
#   Param<dataframe2>: a pandas.DataFrame
def azureml_main(dataframe1 = None, dataframe2 = None): return dataframe1[['UserId','Movie Name','Rating']],

```
### Remove Duplicate Rows
同じ```Movide Name```と```UserId```を持つ重複した行を削除するブロック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629918/dbc524bc-c2f8-ad34-2163-b374cd71ef6d.png)
#### Key column selection filter expression
重複検索時に使用するキーカラムの選択
今回は```Movie Name```と```UserId```を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629918/f97ac3bf-5e6b-6098-1170-92f1cb116edc.png)
#### Retain first duplicate row
重複する行の集合の最初の行を残し，他の行を破棄するかどうかを示します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629918/a81a0081-8c58-4bfd-e6bb-01d388c20bff.png)

### Split Data
ここのブロックでは上記で作成した、トレーニングデータとテストデータを分けるブロックになります。
そのため、最後のoutputが二つになっており、それぞれに対して処理を行っていく形になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629918/ee7e145a-8bec-5113-cf2f-2238d8b8ea0a.png)
このブロックの機能を上から確認していきます。
#### Splitting mode
データセットの分割方法を選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629918/ab0a8a8a-abb5-08df-5d84-7e2f0787f78e.png)
* 行の分割
* 正規表現
* 相対表現
#### Fraction of rows in the first output dataset
入力データセットの行数に対する、最初の出力データセットの行数を表す比率を指定する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629918/97ae293c-22b3-3467-bf9b-8997500f00dc.png)
#### Randomized split
行をランダムに選択するかどうかを指定する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629918/3fd3f0ef-f033-4004-1df8-c2a6019c42b1.png)
#### Random seed
乱数生成器のシードを確認するための値を設定する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629918/1dbc1559-efba-8ee4-adf6-fcbb8a9e4030.png)
#### Stratified split
各分割の行を層別カラムでグループ化するかどうかを指定する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629918/b752b3e9-85dc-85b6-658e-a2bb283099da.png)

### Train SVD Recommender
SVD Recommenderの検証データを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629918/13e65fb8-7eee-6d8c-8fdd-cd40ee18cabc.png)

### Select Columns in Dataset
データセット内のカラムを選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629918/0fa35be7-2d70-7210-6be6-c5fe1af1436e.png)
今回は```Movide Name```と```UserId```を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629918/e9606565-4d36-f3a3-c58c-8cd319d8535a.png)

### Score SVD Recommender
テストデータを使って、SVD Recommenderで予測される評価を取得する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629918/3ad6428e-24ba-640c-9bf0-4c70943874e6.png)
#### Recommender prediction kind
レコメンデーションが出力すべき予測の種類を指定する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629918/51d91546-0863-205c-8abe-46ae9ba34aa4.png)
* Rating Prediction：評価の予測
* Item Recommendation：ユーザーへのおすすめ
今回は評価の予測をするので```Rating Prediction```で進めます。

### Evaluate Recommender
Recommenderをモデルとして評価する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629918/db4fd181-fd9b-9abd-ff0f-21f62d327cd3.png)

以上がブロックの説明になります。
前回に引き続き、こちらでリアルタイム推論パイプラインの作成をしていきます。

# リアルタイム推論パイプライン
大枠は前回と同じ感じになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629918/df475e06-cd4f-6cac-1471-fa88aa483d40.png)
今回は作成するとエラーになってます。
エラーの内容としては、推論パイプラインにしたときに、```Test dataset```がどこからも参照されていないのエラーになります。
しかし、トレーニングの方はもともとのデータを分けて```Test dataset```にしていたので、今回はリアルタイム推論であり、```Test dataset```はリアルタイムで作成することになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629918/93627853-4514-ed42-24d0-7e093232f6bc.png)
なので、```Evaluate Recommender```は削除して、推論パイプラインを作成していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629918/b0d7fc4f-9a9d-2143-d44a-bf63ce54a6c7.png)

前回に引き続き、モデルが出来たらデプロイをして、テスト実行をしてみます。

# テスト実行
そしたら、前回のようにテスト実行の画面まで行きます。
今回テストで使用するデータはこちらになります。
```json
{
  "Inputs": {
    "WebServiceInput0": [
      {
        "UserId": 1,
        "MovieId": 68646,
        "Rating": 10,
        "Timestamp": 1381620027
      },
      {
        "UserId": 1,
        "MovieId": 113277,
        "Rating": 10,
        "Timestamp": 1379466669
      },
      {
        "UserId": 2,
        "MovieId": 454876,
        "Rating": 8,
        "Timestamp": 1394818630
      },
      {
        "UserId": 2,
        "MovieId": 790636,
        "Rating": 7,
        "Timestamp": 1389963947
      },
      {
        "UserId": 2,
        "MovieId": 816711,
        "Rating": 8,
        "Timestamp": 1379963769
      }
    ],
    "WebServiceInput1": [
      {
        "Movie ID": 8,
        "Movie Name": "Edison Kinetoscopic Record of a Sneeze (1894)"
      },
      {
        "Movie ID": 91,
        "Movie Name": "Le manoir du diable (1896)"
      },
      {
        "Movie ID": 417,
        "Movie Name": "Le voyage dans la lune (1902)"
      },
      {
        "Movie ID": 628,
        "Movie Name": "The s of Dollie (1908)"
      },
      {
        "Movie ID": 833,
        "Movie Name": "The Country Doctor (1909)"
      }
    ]
  },
  "GlobalParameters": {}
}

```
このデータで一度テストボタンを押してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629918/646bd4ca-fdbf-050c-f44b-87ec01ea59f8.png)
すると、エラーが出ます。
理由としては、上記のデータの```WebServiceInput0```の```MovieID```と、```WebServiceInput1```の```Movie ID```が一致しないことによるエラーになります。
ブロックの時の処理で```Join Data```というのを行ってます。
そのため、```MovieID```と```Movie ID```を一致させる必要があります。

今回は自分で分かりやすいように書き換えるだけにします。
```json
{
  "Inputs": {
    "WebServiceInput0": [
      {
        "UserId": 1,
        "MovieId": 1,
        "Rating": 10,
        "Timestamp": 1381620027
      },
      {
        "UserId": 1,
        "MovieId": 2,
        "Rating": 10,
        "Timestamp": 1379466669
      },
      {
        "UserId": 2,
        "MovieId": 3,
        "Rating": 8,
        "Timestamp": 1394818630
      },
      {
        "UserId": 2,
        "MovieId": 4,
        "Rating": 7,
        "Timestamp": 1389963947
      },
      {
        "UserId": 2,
        "MovieId": 5,
        "Rating": 8,
        "Timestamp": 1379963769
      }
    ],
    "WebServiceInput1": [
      {
        "Movie ID": 1,
        "Movie Name": "Edison Kinetoscopic Record of a Sneeze (1894)"
      },
      {
        "Movie ID": 2,
        "Movie Name": "Le manoir du diable (1896)"
      },
      {
        "Movie ID": 3,
        "Movie Name": "Le voyage dans la lune (1902)"
      },
      {
        "Movie ID": 4,
        "Movie Name": "The s of Dollie (1908)"
      },
      {
        "Movie ID": 5,
        "Movie Name": "The Country Doctor (1909)"
      }
    ]
  },
  "GlobalParameters": {}
}
```
そしたら、こちらのデータで実行してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629918/698696b2-008b-bfc3-4201-b5fa4f9fc750.png)
しっかり予測できました。

# まとめ
今回は映画の評価の予測を行いました。
```Recommender prediction kind```を変更することで、おすすめの映画を出すことも可能なので、機会があればやりたいです。