10分で作る機械学習レコメンデーションAPI

こんにちは。この記事では、アクセスログから 
**｢このアイテムを閲覧した人はこちらのアイテムもよく閲覧しています｣** 
APIを作成する方法をご紹介します。
GitHubで公開されている [Product-Recommendations](https://github.com/Microsoft/Product-Recommendations) というオープンソースを使用します。 **コーディングは不要です。**

# できるもの
![000.PNG](https://qiita-image-store.s3.amazonaws.com/0/315364/8afd74fe-c7c9-2629-5e40-ade08cd956e2.png)

* ある `アイテムID` (｢商品ID｣や｢スポットID｣など)をパラメータに渡すと、関連度の高い `アイテムID` のリストを返却する
* 学習データはアクセスログを使用します
* これを Azure 上に作成し、APIとして利用できるようにします

# 用意するもの
* Azure アカウント( [無料作成方法はこちら](https://azure.microsoft.com/ja-jp/free/search) )

* アクセスログから `ユーザID`, `レコメンドしたいアイテムのID`, `タイムスタンプ` を抽出したCSVファイル (詳細は [Tips](https://qiita.com/drafts/a9b1a7f1ad263c08a946#%E3%83%AD%E3%82%B0%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E8%A9%B3%E3%81%97%E3%81%8F) 参照)
 
 ``` sample.csv
ユーザID,アイテムID,タイムスタンプ
USER0001,02301-1301284,2018-01-16 17:42:11
USER0002,02301-130087,2018-01-16 17:58:46
USER0001,07008-0000001047,2018-01-17 00:01:14
(以下略)
 ```
 
 今回は [ナビタイムのスポットページ](https://www.navitime.co.jp/poi?spt=02301.1301284) へのアクセスログから、ユーザID、スポットID、タイムスタンプを使用しました。
 
# 10分クッキング
## Azureサーバ構築&デプロイ(3分)

1. Product Recommendations の [デプロイページ](https://github.com/Microsoft/Product-Recommendations/tree/master/deploy) へアクセスし、上部の `Deploy to Azure` ボタンをクリック
![001.PNG](https://qiita-image-store.s3.amazonaws.com/0/315364/3d2d119f-2647-8fdc-1507-2c78a6f0eac8.png)

2. 必要事項を入力し、 `購入` ボタンをクリック (参考:[費用について](https://qiita.com/drafts/a9b1a7f1ad263c08a946#%E6%96%99%E9%87%91%E3%81%AF))
![002.PNG](https://qiita-image-store.s3.amazonaws.com/0/315364/ae00d097-b0d6-9764-581f-27cd12c76392.png)

3. 1分ほど待つと以下4つのリソースが生成されます。(末尾に任意の文字列が追加されます) **これで環境構築は完了です。**
![003.PNG](https://qiita-image-store.s3.amazonaws.com/0/315364/9cd9134e-f4f5-300a-63b1-1baee833a03f.png)


4. 確認
  * リソースグループ > [先ほど作成したリソースグループ名] > デプロイ > `Microsoft.Template` を選択
  * 出力 を選択。以下3つの値をコピーしておきます

![004.PNG](https://qiita-image-store.s3.amazonaws.com/0/315364/9ca1a4f7-b820-bd3a-624e-b34c60ae58c2.png)

![005.PNG](https://qiita-image-store.s3.amazonaws.com/0/315364/6bd543c1-166d-1be4-1273-985f83446b22.png)
)

| KEY | 内容 | 
|-----------|------------|
|RECOMMENDATIONSUI|モデル作成やテストに使えるWebツールのURL|
|RECOMMENDATIONSSWAGGER|Swagger のURL|
|ADMINPRIMARYKEY|上記2つのWebツールの使用時に要求されるキー|


## ログをアップロード(1分)
1.先程作成したストレージアカウントの Blob Storage に任意の名前(ここでは｢input-files｣)のコンテナを作成します
![006.PNG](https://qiita-image-store.s3.amazonaws.com/0/315364/7e29c572-216d-0c8f-e85f-d22588359fb7.png)


2.先ほど作成したコンテナの中にCSVをアップロードします
![007.PNG](https://qiita-image-store.s3.amazonaws.com/0/315364/2c62dd52-8441-a53e-d71f-84f7605cc87d.png)


## ログからモデルを作成(5分)
1. 先程コピーした `RECOMMENDATIONSUI` のURLをブラウザで開きます。**そう、先程デプロイしたサーバに、必要なWebツールやSwaggerがすでに用意され使える状態になっています。**キーが要求されるので、同じく先程コピーした `ADMINPRIMARYKEY` の値を入力し `LOGIN` ボタン押下
![008.PNG](https://qiita-image-store.s3.amazonaws.com/0/315364/64299602-9751-5b1e-15ff-f22240eb9158.png)

2. 緑の `TRAIN NEW MODE` ボタンを押下
![009.PNG](https://qiita-image-store.s3.amazonaws.com/0/315364/b0ce1736-2bee-770d-fe7d-ca47af6101eb.png)


3. 以下を指定。残りはデフォルトのまま `TRAIN` ボタンを押下
![010.PNG](https://qiita-image-store.s3.amazonaws.com/0/315364/62101437-5477-6a5c-1d1b-b067f056639e.png)

4. Statusが `Completed` になればモデル生成完了です
![011_Completed.PNG](https://qiita-image-store.s3.amazonaws.com/0/315364/c6310601-98de-81fe-1903-cb4116b3d9bb.png)


## 確認する(1分)
### UIツールで確認
1. `SCORE` ボタン > ｢清水寺｣のIDを入力 > `GET RECOMMENDATIONS` ボタン押下
![012.PNG](https://qiita-image-store.s3.amazonaws.com/0/315364/c90d5d5a-33f3-bc36-1b8c-12d435027da5.png)
![013.PNG](https://qiita-image-store.s3.amazonaws.com/0/315364/553af94b-6dd9-7120-39e8-4b4d6baf881f.png)

関連するアイテムIDと関連度(SCORE)が返却されました!
上から、
**伏見稲荷大社、金閣寺、嵐山、八坂神社、京都タワー**
のIDです。
｢清水寺｣を検索した人が検索していそうなスポットですね。


### Swaggerで確認
1. 先程コピーした `RECOMMENDATIONSSWAGGER` のURLをブラウザで開きます。右上のボックスに同じく先程コピーした `ADMINPRIMARYKEY` の値を入力します
2. `Operations` の文字をクリックするとAPI一覧が表示されるので、 `GET /api/models/default/recommend` を選択
![014.PNG](https://qiita-image-store.s3.amazonaws.com/0/315364/ec59165a-1001-e52c-b8ca-a4290f2808f1.png)

3. `itemId` に今度は｢札幌時計台｣のIDを入力し `Try it out!`
![015.PNG](https://qiita-image-store.s3.amazonaws.com/0/315364/af703848-ca8d-8e32-ce83-9683ebf2ca96.png)

4. 関連するアイテムIDと関連度(SCORE)の返却を確認できました!
上から、
**大通公園、さっぽろテレビ塔、サッポロビール博物館、小樽運河、白い恋人パーク**
のIDです。
こちらは｢札幌時計台｣を検索した人が検索していそうなスポットが返却されました。

**以上で ｢このアイテムを閲覧した人はこちらのアイテムもよく閲覧しています｣ APIが完成しました。**

# Tips集
## 料金は?
* GitHubで公開されている [Product-Recommendations](https://github.com/Microsoft/Product-Recommendations) は無料で使用できます。([LICENSEについて](https://github.com/Microsoft/Product-Recommendations/blob/master/LICENSE.md))
* 通常と同じくAzure上に新規作成したリソース(`AppService`など)の使用料金のみかかります。

## 精度は?
* 精度はデータ量やデータのばらつきに依存するので一概には言えません。ただ、既存のアクセスログを使用しただけのモデルでも実用に耐えうるというのが個人的な所感です。
* 精度や評価方法については [Product-Recommendationsの評価解説ページ](https://github.com/Microsoft/Product-Recommendations/blob/master/doc/model-evaluation.md)

## どういう仕組?
*  [Product-Recommendations](https://github.com/Microsoft/Product-Recommendations) の内部では、ユーザの行動ログを機械学習し関連度を算出しています。
* 今回は ｢ユーザの行動ログ｣ = ｢アクセスログ｣ = ｢学習データ｣ です。
* 詳しいアルゴリズムは [Product-Recommendationsの解説](https://github.com/Microsoft/Product-Recommendations/blob/master/doc/sar.md) 参照

## ログについて詳しく!
* こちらも [Product-RecommendationsのAPIリファレンス](https://github.com/Microsoft/Product-Recommendations/blob/master/doc/api-reference.md#usage-data) が詳しいです
* アクセスログ以外の、アプリログなどから抽出したデータでも全く構いません。アクセスログはどのサービスでも蓄積されている既存資産だと思うので、今回例として使用しました
* たとえば、NAVITIMEのスポットページのURL [https://www.navitime.co.jp/oi?spt=02301.1301284](https://www.navitime.co.jp/poi?spt=02301.1301284) にはスポットのIDが含まれます。(どのウェブサイトにもこういったアイテム表示ページがあると思います) 今回はアクセスログからこのスポットID、ユーザID、タイムスタンプを使用しました

## ｢あなたにオススメ｣(Personalize)はできないの?
* 今までインプットが｢アイテムID｣、アウトプットが｢インプットのアイテムIDに関連するアイテムID｣のパターンを説明してきました
* 実はインプットが｢ユーザの行動ログ｣、アウトプットが｢ユーザの行動ログに関連するアイテムID｣ 取得用のAPIも、これまでの過程ですでに作成されてます
* 詳しくは [Product-RecommendationsのAPIリファレンス](https://github.com/Microsoft/Product-Recommendations/blob/master/doc/api-reference.md#get-personalized-recommendations) 参照

## URLがダサいんだけど…
* リソース名の末尾に無作為の文字列がつくのは仕様です。
* 本番リリース時には [API Management](https://docs.microsoft.com/en-us/azure/api-management/import-and-publish) を使ってURLをリダイレクトしましょう。すでにSwaggerJsonファイルが生成されているので、Importも楽ちん! (上記ドキュメントの `OpenAPI Specification` に Swagger の上部に表示されているjsonURLを指定します。一瞬で全APIがImportできます)

# まとめ
以上、10分でAzure上にレコメンデーションAPIを作成する方法でした。
機械学習と聞くとデータの収集で頓挫しがちですが、会社に眠る既存資産(アクセスログ)でお手軽に作成できる点が魅力ですね。