Amazon Personalizeのメモ


公開されているハンズオン ( https://pages.awscloud.com/event_JAPAN_Hands-on-Amazon-Personalize-Forecast-2019.html ) の [資料](https://pages.awscloud.com/rs/112-TZM-766/images/201912-AmazonPersonalizeHandson.pdf) を頼りに、Amazon Personalizeを体験した時に、ハンズオンと[公式の開発者ドキュメント](https://docs.aws.amazon.com/ja_jp/personalize/latest/dg/what-is-personalize.html) の補足をまとめていきます。

## 使われる単語

単語の関係性を クラス図で表現してみました。
![AmazonPersonalize.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145742/2c571643-2d85-c7eb-dd59-446456df6917.png)

* Datasets
    * レコメンデーションの元になるデータ
    * User
        * 会員などのいわゆるユーザマスタ
    * Item
        * 商品やコンテンツなどの推奨するアイテムのマスタ
    * Iteration
        * UserとItem を関係づけるトランザクション
        * 例えば、購入や閲覧など
* Solution
    * レコメンデーションのモデル
* レシピ
    * User、Item、Iterationから レシピを構築に利用する機械学習のアルゴリズムとパラメータ
    * バージョンを持っている
* キャンペーン
    * レコメンドを得るためには キャンペーン に対して行う。 

レコメンデーションは *Campaign* から取得します。 学習モデルに相当する *Solution* にはバージョンがあるので、Datasetsと Recipeのパラメータを調整して、PDCAを回しながら施策の効果を上げていく運用になると思われます。

## レシピの使い分け

レシピはパラメータで調整可能なものが「事前定義済みレシピ」として提供されているので、用意できるデータと期待するレコメンド結果に応じて使い分けます。


## レシピタイプ

「事前定義済みレシピ」を分類するものです。

| レシピタイプ            | 用途 | 要件(userId) | 要件(itemId)| 要件(inputList) | 
| -------------------- | --- | ----------- | ---------- | -------------- |
| USER_PERSONALIZATION | あなたにおすすめの商品はこちらです。 | 必須         | オプション    | 該当なし         |
| PERSONALIZED_RANKING | (多分)あなたのお気にり商品はこちらです。 | 必須         | 該当なし     | itemId のリスト  |
| RELATED_ITEMS        | この商品を購入した人はこちらの商品も購入しています。 | 使用されない   | 必須        | 該当なし        |

(inputListは　Interactions の事かな？)

## 事前定義済みレシピ

#### USER_PERSONALIZATION

* HRNN
    * HRNN は、階層的再帰型ニューラルネットワークであり、特定期間のユーザーアイテムインタラクションをモデル化できます。ユーザーの行動が時間の経過とともに変化する場合は (進化していくインテントの問題と呼ばれる)、HRNN レシピを使用します。
    * モデルをトレーニングするために、HRNN は、データセットグループのインタラクションデータセットを使用します。データセットグループは、ユーザー、アイテム、インタラクションのデータセットを含むことができる一連の関連データセットです。
* HRNN-Metadata
    * HRNN-Metadata は、インタラクション、ユーザー、アイテムのデータセットにあるメタデータから派生した追加の特徴を含む HRNN レシピです。たとえば、評価、映画のジャンル、リリース年などです。少なくとも 1 つのデータセットのトレーニングデータにメタデータが含まれている必要があります。高品質なメタデータを使用できる場合、HRNN-Metadata は非メタデータモデルよりもパフォーマンスが高くなります。このレシピを使用したトレーニングでは、トレーニング時間が長くなることがあります。
    * モデルをトレーニングするために、HRNN-Metadata は、データセットグループのユーザー、アイテム、インタラクションのデータセットを使用します。データセットグループは、ユーザー、アイテム、インタラクションのデータセットを含むことができる一連の関連データセットです。
* HRNN-Coldstart
    * HRNN-Coldstart は、HRNN-Metadata レシピに似ていますが、新しいアイテムのパーソナライズされた探索も含まれています。新しいアイテムを頻繁にカタログに追加し、それらのアイテムをすぐにレコメンデーションに含める必要がある場合は、HRNN-Coldstart レシピを使用します。
    * モデルをトレーニングするために、HRNN-Coldstart は、データセットグループのユーザー、アイテム、インタラクションのデータセットを使用します。データセットグループは、ユーザー、アイテム、インタラクションのデータセットを含むことができる一連の関連データセットです。トレーニングデータを提供するデータセットグループには、アイテムデータセットが含まれている必要があります。
* Popularity-Count
    * Popularity-Count レシピは、インタラクションデータセット内のアイテムに対するイベントのカウントに基づいて、そのアイテムの人気度を計算します。Popularity-Count レシピを使用してベースラインを作成して、他の USER-PERSONALIZATION レシピと結果を比較します。
    * モデルをトレーニングするために、Popular-Count レシピは、データセットグループのインタラクションデータセットを使用します。データセットグループは、ユーザー、アイテム、インタラクションのデータセットを含むことができる一連の関連データセットです。

### PERSONALIZED_RANKING
* Personalized-Ranking
    * Personalized-Ranking レシピは、結果をフィルタリングおよび再ランク付けすることもできる階層的再帰型ニューラルネットワーク (HRNN) レシピです。Personalized-Ranking は、最良のレコメンデーションのリストを提供します。ユーザーの結果をパーソナライズする場合は (検索結果または選別リストのパーソナライズされた再ランキングを生成するときなど)、Personalized-Ranking レシピを使用します。
    * モデルをトレーニングするために、Personalized-Ranking レシピは、データセットグループのインタラクションデータセットを使用します。データセットグループは、ユーザー、アイテム、インタラクションのデータセットを含むことができる一連の関連データセットです。

### RELATED_ITEMS
* SIMS
    * アイテム間の類似度 (SIMS) レシピは、ユーザーアイテムインタラクションデータセット内のユーザー履歴内のアイテムの共起に基づいて、特定のアイテムに類似したアイテムを生成します。アイテムに十分なユーザー行動データがない場合、または指定されたアイテム ID が見つからない場合、レシピは人気アイテムをレコメンデーションとして返します。SIMS レシピを使用して、アイテムの発見性と詳細ページを改善します。SIMS レシピのトレーニングは、他のレシピに比べて高速です。
    * モデルをトレーニングするために、SIMS レシピは、データセットグループのインタラクションデータセットを使用します。データセットグループは、ユーザー、アイテム、インタラクションのデータセットを含むことができる一連の関連データセットです。

### 自動
* AutoML
    * 実行時に上のレシピを考慮します。

## レシピの調整

レシピはパラメータを持ち、変更可能になっています。パラメータは [開発者ガイドの事前定義済みレシピの使用](https://docs.aws.amazon.com/ja_jp/personalize/latest/dg/working-with-predefined-recipes.html)からリンクされている個々の事前定義レシピの説明に記載されています。

## AWS CLIで レコメンデーションを取得する

AWS CLIでレコメンデーションを取得するコマンド `personalize-runtime` です。 これとは別に`personalize` というコマンドがあり、これは RecipeやCampaign の管理で使います。

今回はユーザID 1の人に推奨するアイテムを取得します。

```bash
$ export campaign_arn="arn:aws:personalize:us-west-2:123456789012:campaign/my-campaign"
$ aws personalize-runtime get-recommendations --campaign-arn ${campaign_arn} --user-id 1 --num-results 10 --region us-west-2
```

実行するとITEM_IDの一覧を得られます。

```json
{
    "itemList": [
        {
            "itemId": "356"
        },
        {
            "itemId": "318"
        },
        {
            "itemId": "296"
        },
        {
            "itemId": "3578"
        },
        {
            "itemId": "1198"
        },
        {
            "itemId": "58559"
        },
        {
            "itemId": "608"
        },
        {
            "itemId": "593"
        },
        {
            "itemId": "5618"
        },
        {
            "itemId": "50"
        }
    ]
}

```

## 実際に使うときに気になる事

1. ソリューション の作成/更新 の処理時間
    * チュートリアルを実施する範囲では計算に使われるインスタンスタイプを変更できる仕組みがありませんでした。利用する事前定義済みレシピやDatasetsに登録したデータ量に応じて計算時間が変わるのであれば、終わるのジッと待つしかできないと思いました。インスタンスタイプや台数を指定する事で計算時間を短縮できると嬉しいです。
    * これは [performHPO](https://docs.aws.amazon.com/ja_jp/personalize/latest/dg/customizing-solution-config-hpo.html)で調整が行えそう
2. レシピのパラメータ調整
    * レコメンドを取得した時に、推奨したアイテムを評価したスコアが表示を得られません。パラメータの妥当性を判断するために、ソリューションの更新を繰り返す必要がありそうなので、時間がかかりそうです。
3. バッチレコメンデーションのキャパシティ
   * APIでリアルタイムにレコメンドを取得するとスパイクが発生した時に遅延すると思われるので、 事前にバッチで取得してキャッシュするのが良さそうです。キャンペーンには、1秒間あたりのレコメンド回数`minProvisionedTPS` を指定するので、バッチレコメンデーションでもこれの影響を受けるのかを知りたいです。

## とはいえ

レコメンデーションをお手軽に実現できるのは助かります。

## 参考
- [AWSが提供するフルマネージドレコメンドエンジン『Amazon Personalize』について](https://qiita.com/overflowfl/items/e92947acab9d1993cbad)