AWSが提供するフルマネージドレコメンドエンジン『Amazon Personalize』について

# 1.はじめに
AWSにはフルマネージドなレコメンデーションサービスであるAmazon Personalizeが用意されています。開発しているシステムにレコメンドエンジンを導入検討にあたって、どういったものなのか調査を行いましたので、その調査内容を取りまとめてみました。

# 2.Amazon Personalizeの各種用語について

Amazon Personalizeを利用するにあたって、いくつかの準備が必要となります。その中で出てくる用語が、正直な話わかりづらいです。利用にあたってこれらの言葉を理解しておかないと挫折すると思いますので、私なりにまとめてみました。

## 2-1.データセットグループ・データセット・スキーマ
どのようなレコメンドエンジンにおいても、レコメンドを行うためには、その素情報を投入する必要があります。Amazon Personalizeでは、素情報の総称をデータデータセットグループといいます。データセットグループは、Interactions、Users、Itemsの３種のデータセットで構成され、それぞれ一つずつスキーマ定義することが可能です。
あえてRDBと対応してみます。

| Amazon Personalize | RDB | 備考 |
| --- | --- | --- |
| データセットグループ | データベース | いくつも作成可能 |
| データセット | テーブル | RDBと異なり３つしか作れない |
| スキーマ | テーブル定義 | RDBと異なり自由度はとても低い<BR>ERも変更不可 |


レコメンドで利用するアルゴリズム（後述のレシピ）によって、利用するデータセットが異なり、３種類すべてを必ず用意する必要があるわけではありません。ただし、Interactionsはすべてのアルゴリズムで利用するため、用意が必須となります。

それぞれのデータセットのスキーマ定義は以下の通りとなります。

### 2-1-1.Interactions
ユーザとアイテムを紐づけるデータを格納します。紐づける情報とは、例えば評価情報、参照情報、購入量情報、購入金額情報などが該当します。これらは、すべて利用者の操作にまつわるデータであり、Amazon Personalizeではイベントといいます。また、評価、参照、購入などをイベントタイプといいます。Interactionsではこれらイベント情報をすべて格納できるように設計されています。

スキーマ定義は以下の通りです。

| 項目名 | 型 | 説明 | 必須 |
| --- | --- | --- | --- |
| USER_ID | string | ユーザを識別するID | 〇 |
| ITEM_ID | string | アイテムを識別するID | 〇 |
| EVENT_TYPE | string | イベントを識別するID |  |
| EVENT_VALUE | string | イベントの値 |  |
| TIMESTAMP | long | イベント発生時間（Unix時間=エポック秒） | 〇 |


### 2-1-2.Users
ユーザの情報を格納します。ユーザの情報とは、性別、年齢、所在都道府県、職業といった情報を指します。レコメンド精度を上げるための情報として利用されます。

スキーマ定義は以下の通りです。

| 項目名 | 型 | 説明 | 必須 |
| --- | --- | --- | --- |
| USER_ID | string | ユーザを識別するID | 〇 |
| (自由に定義可能) | (自由に定義可能) | ユーザ属性情報（メタデータ）１ | 〇 |
| (自由に定義可能) | (自由に定義可能) | ユーザ属性情報２ |  |
| (自由に定義可能) | (自由に定義可能) | ユーザ属性情報３ |  |
| (自由に定義可能) | (自由に定義可能) | ユーザ属性情報４ |  |
| (自由に定義可能) | (自由に定義可能) | ユーザ属性情報５ |  |

※USER_ID以外の項目（メタデータ）については、型にstringを指定する場合はcategoricalrical属性をtrueで定義する必要がある。
※1フィールドに複数の値を持つ場合は、パイプ | で連結する
※コードなどをフィールドで持つ場合は数値ではなく文字列として定義したほうが良いと思われる。例えば性別で0を男、1を女としたい場合においても、文字列として定義をするべき。


### 2-1-3.Items
アイテムの情報を格納します。アイテムの情報とは、商品のカテゴリ、メーカ名などを指します。Users同様にレコメンド精度を上げつための情報として利用されます。

スキーマ定義は以下の通りです。

| 項目名 | 型 | 説明 | 必須 |
| --- | --- | --- | --- |
| ITEM_ID | string | ユーザを識別するID | 〇 |
| (自由に定義可能) | (自由に定義可能) | アイテム属性情報（メタデータ）１ | 〇 |
| (自由に定義可能) | (自由に定義可能) | アイテム属性情報２ |  |
| (自由に定義可能) | (自由に定義可能) | アイテム属性情報３ |  |
| (自由に定義可能) | (自由に定義可能) | アイテム属性情報４ |  |
| (自由に定義可能) | (自由に定義可能) | アイテム属性情報５ |  |

※ITEM_ID以外の項目（メタデータ）については、型にstringを指定する場合はcategoricalrical属性をtrueで定義する必要がある。
※1フィールドに複数の値を持つ場合は、パイプ | で連結する
※コードなどをフィールドで持つ場合は数値ではなく文字列として定義したほうが良いと思われる。


## 2-2.レシピ

レコメンドにあたって、いろいろなアルゴリズムが存在します。Amazon Personalizeでは、このアルゴリズムのことをレシピといいます。なお、Amazon Personalizeでは、３種類のレコメンドが存在しており、それぞれ利用できるレシピが異なります。

### 2-2-1.USER_PERSONALIZATION（あなたにおすすめの商品）

特定ユーザ向けのアイテムリストをレコメンドします。ユーザIDが引数となります。
利用できるレシピは以下の通りです。

| レシピ | AutoML対象 | Users,Itemsを使用 | 説明 |
| --- | --- | --- | --- |
| HRNN | 〇 |  | ユーザの嗜好や行動が時間とともに変化することに対応したモデル(Hierarchical recurrent neural network) |
| HRNN-metadata | 〇 | 〇 | 類推に当たってメタデータを用いるモデル |
| HRNN-coldstart | 〇 | 〇 | 新しいアイテムが頻繁に追加される場合で、そういったアイテムをすぐに対象としたい場合 |
| popularity-Count |  |  | 単純にInteractionsデータの件数で提案する。他のレシピの評価用 |

引数にアイテムIDが含まれないので、特定商品、特定ユーザに対するレコメンドということはできません。
例えば「あなたに似た人で、この商品を購入している人は、こんな商品もおすすめ」といったことは実現できません。実現したい場合は、一度　USER_PERSONALIZATION　にておすすめのアイテムIDを取得したのち、後述の　PERSONALIZED_RANKING　にて並び替えを行うことで実現します。


### 2-2-2.RELATED_ITEMS（この商品を購入している人はこちらの商品も購入しています）

特定アイテムに類似するアイテムをレコメンドします。アイテムIDが引数になります。
利用できるレシピは以下の通りです。

| レシピ | AutoML対象 | Users,Itemsを使用 | 説明 |
| --- | --- | --- | --- |
| SIMS |  |  | Interactionsデータからアイテム間類似度を算出し、渡したアイテムと類似度の高いリストを返却する |


### 2-2-3.PERSONALIZED_RANKING（あなた向けランキング）

渡したアイテムリストを特定ユーザ向けに並び替えします。ユーザIDとアイテムIDのリストが引数となります。
＞利用シーンがあまり思い当たらない・・・。

利用できるレシピは以下の通りです。

| レシピ | AutoML対象 | Users,Itemsを使用 | 説明 |
| --- | --- | --- | --- |
| Personalized-Ranking |  |  | 渡したアイテムのリストをユーザの嗜好順に並び変えて返却 |



## 2-3.ソリューション・ソリューションバージョン

レコメンドをするためには、データセットグループを用いて事前に学習（トレーニング）しておく必要があります。このトレーニングのための定義をソリューションといい、利用するレシピ、利用するデータセットグループ、トレーニング用の各種パラメータ（ハイパーパラメタ、Interactionsデータの中に複数イベントがある場合はどのイベントを利用するか）を指定します。また、作成したソリューションを基に、実際にトレーニングを行いますが、そのトレーニング結果をソリューションバージョンといいます。
注意しなければならないことは、ソリューションバージョンは、データセットグループのデータが更新されたとしても反映はされません。反映するためには改めてソリューションバージョンを作成する必要があります。もし更新を行わないと、新しいユーザやアイテムに対してのレコメンド精度が落ちることになります。

なお、設定するハイパーパラメタによってレコメンド精度に影響します。そのためハイパーパラメタのチューニングが必要です。比較検証をするにあたっては、Popularity-Countレシピの指標との比較をするとよいようです。
（詳しい検証方法については[Evaluation Solutions]
(https://docs.aws.amazon.com/personalize/latest/dg/working-withtraining-metrics.html)を参照）


## 2-4.キャンペーン

レコメンドのエンドポイントをキャンペーンといいます。キャンペーンの定義をする際に、利用するソリューションバージョンと最小スループットを指定します。この最小スループットは月額費用と性能のトレードオフとなるため、利用シーンに合わせてチューニングしていく必要があります。（大きく設定すると性能もコストも上がる。逆に小さく設定すると性能もコストも下がる。）

## 2-5.イベントトラッカー
リアルタイムにInterectionsデータを登録し、レコメンド結果に反映させることができます。データ登録に当たっては、SDK経由（PutEvents）で行います。このデータ登録を行わないと、USER_PERSONALIZATIONのレコメンド結果がずっと同じになってしまいます。（例えば、どの商品情報の画面に遷移しても同じレコメンドをされる・・・。）
商品詳細画面を表示する前にイベントトラッカーに表示しようとしている商品のデータを登録することで、最新のInterections情報でレコメンドすることが可能になります。

# 3.利用にあたっての注意事項
以下注意事項があります。

1. バケットにあらかじめAmazon Personalizeからのアクセスを許可するバケットポリシーを設定する必要がある。（詳しくは[こちら](https://docs.aws.amazon.com/ja_jp/personalize/latest/dg/data-prep-upload-s3.html)を参照）
2. バケット名に**personalize**という文字列を含める必要があります。含めないとデータを読み取ってくれません。（IAMロールのAmazonPersonalizeFullAccessがそのように定義されている・・・。）
3. **キャンペーンは作成してから削除するまでの間、利用有無にかかわらず課金されます。** 運用しないのであれば、使用後に削除してください。価格ですが、最小スループットの設定によります。仮に1TPSとした場合、全く利用されていないとしても一日で0.20 USD/TPS時間 × 1TPS × 24時間 = 4.8USD（500円）の費用が発生します。万が一100などと設定してしまうと。。。


# 4.おわりに
どのサイトにも当たり前のように存在しているレコメンド機能ですが、実際に開発をするとなると大げさな実装をしていく必要があります。ASPサービスを用いて実現することも可能ですが、AWSにてお手軽に実現できるというのはとても魅力的だなと思いました。


# 参考
[【AWS Black Belt Online Seminar】Amazon Personalize](https://www.youtube.com/watch?v=3blaQhzJhYE)
[【AWS Black Belt Online Seminar】Amazon Personalize PDF資料](https://d1.awsstatic.com/webinars/jp/pdf/services/20190716_AWS_BlackBelt_AmazonPersonalize.pdf)
[Amazon Personalizeを導入してわかった12のこと](https://qiita.com/hibiheion/items/2725632e0272bfcc0824#6-%E6%9C%80%E4%BD%8E%E9%99%90%E5%BF%85%E8%A6%81%E3%81%AAapi%E3%81%AF3%E3%81%A4%E3%81%A0%E3%81%91)
[Amazon Personalizeでレコメンドしてみる話](https://qiita.com/ikegam1/items/22ee984313808e91d64f)
[Amazon Personalize使い方まとめ / CloudFormationとPythonでレコメンドアプリケーションを学習・デプロイする](https://blog.ikedaosushi.com/entry/2019/06/14/011649)
[Amazon Personalize Web-APIで情報推薦サービスを実現する](https://techblog.nhn-techorus.com/archives/15174)