Amazon Personalizeのイベント追加前後のレコメンド内容の変化を調べてみた
Amazon Personalizeでは過去のユーザの行動によるアイテムとのインタラクションデータを元にしたレコメンドが可能です。 ユーザやアイテムは日毎に増えるので、それらに対応できるように日次や高頻度でレコメンド内容を更新したいということがあるかと思います。 Amazon Personalizeはイベントを収集する機能があり、イベントデータが追加されることで、キャンペーンによるリアルタイムレコメンドに即座に反映させることができます。 イベントデータを追加することで、ソリューションバージョンを更新しなくても新しいデータに対応できるこの機能を試してみたので紹介します。
やってみる
- データセット: MovieLens 100K Dataset | GroupLens
- スキーマ
- Interactions: USER_ID, ITEM_ID, EVENT_VALUE, TIMESTAMP, EVENT_TYPE
- 対象レシピ: HRNN-Coldstart
- やること
- 準備
- データ
- データセットグループ、スキーマ、データセット、データインポート
- ソリューション(HRNN)、ソリューションバージョン
- イベント追加前後でのレコメンド内容の比較
- イベントデータセット削除後のレコメンド内容の確認
- 未学習ユーザに対するイベント追加前後のレコメンド内容の確認
試した内容の各スクリプトについては以下のノートブックとラッパースクリプトをご確認ください。
- ノートブック: devio_samples/personalize_events_demo.ipynb at master · tandfy/devio_samples
- Boto3のPersonalize APIをラップしたスクリプト: devio_samples/personalize_util.py at master · tandfy/devio_samples
準備
データ
まずはデータをダウンロードし、データフレームに読み込みます。
学習に使用するインタラクションデータは次のようなデータです。今回は各インタラクションをクリックイベントとして扱うために、EVENT_TYPE
にCLICK
を入れています。
学習には使用しませんが、アイテムデータもデータフレームに読み込みます。その際に、ジャンルが分かりやすいように加工しています。
ソリューションの作成
Personalizeのデータセットグループを作成し、そこにインタラクション用データセットを作成します。ソリューションの学習に使えるようにデータセットにインタラクション用データを読み込みます。
インタラクション用データセットは次のようなフィールド定義を使って作成しました。イベントデータに対応できるようにEVENT_TYPE
を設定します。
fields = [ { "name": "USER_ID", "type": "string" }, { "name": "ITEM_ID", "type": "string" }, { "name": "TIMESTAMP", "type": "long" }, { "name":"EVENT_TYPE", "type":"string" } ]
データのインポートが完了したら、HRNNでソリューションとソリューションバージョンを作成します。
これらの詳細の手順は今回割愛します。ドキュメントをご確認ください。
キャンペーンの作成
作成したソリューションバージョンを元にキャンペーンを作成します。
personalize_client.create_campaign( name=f'{self.solution_name}-{solution_version_name}', solutionVersionArn=solution_version_arn, minProvisionedTPS=min_provisioned_tps, )
イベントトラッカーの作成
データセットグループにイベントトラッカーも作成します。イベントトラッカーはデータセットグループにつき、一つしか作成できません。また、イベントトラッカーを作成することで、イベントデータを蓄積するためのデータセットも合わせて作成されます。
personalize_client.create_event_tracker( name=self.dataset_group_name, datasetGroupArn=self.dataset_group_arn )
イベント追加前後でのレコメンド内容の比較
作成したキャンペーンとイベントトラッカを使用して、イベント追加前後のレコメンド内容を比較してみます。
まずは対象ユーザのレコメンド内容を確認してみます。比較のために、イベントを追加するユーザと追加しないユーザを確認します。
対象ユーザ202にイベントを追加してみます。
event_tracker.put_events( user_id=202, session_id=1, event_list=[EventObject(event_type, {'itemId': '7'})] )
追加後にキャンペーンでリアルタイムレコメンドを実行してみます。レコメンド内容は次の通りになりました。
ユーザ202へのレコメンド内容が変わっていることがわかります。
レコメンドデータ全体で比較したところ次のようになりました。
今回、イベントを追加したユーザはレコメンド内容が変化しましたが、追加していないユーザに対するレコメンド内容は変化しませんでした。これは今回の検証ではこうなっただけで、必ずしもイベントを追加することでレコメンド内容が変化し、イベントを追加したユーザと異なるユーザのレコメンド内容が変化しないとは限らないと考えられます。イベントを追加することでそのイベント内容をソリューションバージョンに反映したレコメンドができますが、イベントがレコメンド内容に具体的にどのような影響を与えるかは分からないと考えた方が良さそうです。
また、バッチレコメンドでも同様に実験してみましたが、イベント追加後もレコメンド内容は変化しませんでした。ドキュメントには次のようにキャンペーンしか言及されていないため、バッチレコメンドではこのイベントの即時反映は効果がないものと考えられます。
履歴データとは異なり、キャンペーンが作成されると、キャンペーンからレコメンデーションを取得するときは新しく記録されたイベントデータが自動的に使用されます。
イベントデータセット削除後のレコメンド内容の確認
イベントデータセットを削除して、キャンペーンによるレコメンド内容が変化するか確認してみます。
イベントデータセット削除後のレコメンド内容は次のようになりました。
イベントデータセット削除後とイベント追加後のレコメンド内容を比較したところ、レコメンド内容は変化していないようです。
イベントデータセットを削除した状態で、イベントを追加してみたところ、イベントの追加ができ、さらにそのレコメンド内容はイベント追加前と変化していました。イベントデータセット削除後でもキャンペーンへのイベントデータの反映は可能なようです。
未学習ユーザに対するイベント追加前後のレコメンド内容の確認
続いて、ソリューションバージョン作成時のインタラクションデータに含まれていないユーザ、すなわち未学習ユーザに関連するイベントを追加し、そのユーザへのレコメンド内容を確認してみます。
※ イベントデータセットを削除してしまったので、念のため、イベントトラッカーを作成し直して、検証しました。
未学習ユーザはインタラクションデータからこのように設定しました。
untrained_user_ids = [df.USER_ID.max() + 1, df.USER_ID.max() + 2]
イベント追加前の未学習ユーザへのレコメンドは次のような内容でした。
未学習ユーザ同士のレコメンド内容は同じものになっています。
次に、未学習ユーザの1人に2つのイベントデータを追加します。
event_tracker.put_events( user_id=df.USER_ID.max() + 1, session_id=1, event_list=[EventObject(event_type, {'itemId': '7'}), EventObject(event_type, {'itemId': '50'})] )
イベント追加後のレコメンド内容は次のような内容になりました。
イベントを追加した未学習ユーザのレコメンド内容は、イベント追加前から変化していることがわかります。
さいごに
Amazon Personalizeのイベント追加前後のレコメンドデータの変化について検証した内容をお伝えしました。キャンペーンとイベントトラッカーを活用することで、ユーザの行動イベントをニアリアルタイムに反映したレコメンドが可能となります。ユーザの動きが早いサービスにおいては特に、この恩恵を強く受けることができそうです。キャンペーンによるリアルタイムレコメンドは非常に便利ですが、起動時間と実際の秒単位のトランザクション数(TPS)に応じた料金がかかります。リアルタイムレコメンドとバッチレコメンドには機能面や費用面などそれぞれ特徴があるため、ユースケースに応じて上手く使い分けたいですね。