BASEプロダクトチームブログ

ネットショップ作成サービス「BASE ( https://thebase.in )」、ショッピングアプリ「BASE ( https://thebase.in/sp )」のプロダクトチームによるブログです。

Amazon Personalizeでリアルタイムに変化をするレコメンドを試してみました!

f:id:sugiiiii:20211216111204p:plain

この記事はBASEアドベントカレンダー2021 17日目の記事です。

はじめに

DataStrategyチームの杉です。

ショッピングアプリPay IDではさまざまなショップでの商品購入が可能です。
"探す"タブにはおすすめ機能がついており、利用者にあった商品やショップのレコメンドを行なっています。

おすすめ商品の掲載例

おすすめの商品ではさまざまなアルゴリズムを並行に運用しており、その中のひとつとしてAmazon Personalizeを利用しています。

このアルゴリズムの計算は今まで1日に1回のbatch処理で行なっていました。
しかし、閲覧や購入のログをリアルタイムに利用することでよりマッチしたおすすめ商品を掲載することができるのではという想いでevent trackerを用いたリアルタイムに変化をするレコメンドに挑戦をしました。

この記事では、event trackerをどう実装したかをメインにお伝えしたいと思います。

Amazon Personalizeとは

Amazon Personalizeについては以前に@pigooosukeさんが発表をしているので運用しているおすすめの全体の構成やAmazon Personalizeの利用注意点などについてはこちらで見ることができます。

https://speakerdeck.com/pigooosuke/aws-personalize-recsys
(現在の構成と異なる部分もあります)

Amazon Personalizeを使用することでメンテナンスコストを下げることや精度の高いおすすめを提供することができています。

event trackerについて

Amazon Personalizeではevent trakcerを使うことでリアルタイムなイベントを反映させた結果の推論結果を取得することができます。

作成、eventの送信はどちらもboto3で行うことが可能です。

①event trackerの作成

personalize = boto3.client(service_name='personalize', region_name=AWS_REGION)

response = personalize.create_event_tracker(
    name=EVENT_TRACKER_NAME,
    datasetGroupArn=dataset_group_arn
)

②eventが発生するたびにput eventを行う

personalize_runtime = boto3.client(
    service_name='personalize-runtime', region_name=AWS_REGION)

personalize_events.put_events(
    trackingId=tracking_id,
    userId=userId,
    sessionId=sessionId,
    eventList=[{
        'sentAt': timestamp,
        'eventType': 'view',
        'itemId': '12345'
    },
    {
        'sentAt': timestamp,
        'eventType': 'view',
        'itemId': '6789'
    }]
)

eventの送信はuser_id単位で送ります。
また、session_idを用いることでその時点では未知なユーザに対してもデータを溜めることが可能です。

推論への影響はすぐに反映され、eventの影響を確認することができます。
event内容によっては必ずしも推論結果に影響するわけではないので、put eventをしても変わらないこともあるということには注意が必要です。

event trackerを導入後の構成

eventとして溜めていくデータとしては2種類あります。

  • DBに記録された購入情報など
  • 行動ログ

これらをリアルタイムにevent trackerに流し込んでいくために以下の構成にしました。

メインのworkerは2台あります

①Kafka->SQS

DBの更新イベントと行動ログをKafkaで取得し、SQSへ随時eventを送ります。
ここではRDSに接続をし必要情報の紐付けなども行なっています。

②SQS->put_event

SQSからAmazon Personalizeのevent trakcerへput eventをするような動きをしています。

SQSを挟むことで急激なトラフィックなどが来てもevent trackerに流し込む部分の負荷が高くならないようにしました。

event trackerの注意点

event trackerの検証を行なっているうえで、注意点に出会いました。
いくつかありましたが、その中でも2つご紹介させていただきます。

1. 未知商品に対してはeventを追加しても影響がない

データセットには以下の3種類あります。

  • Item
  • User
  • User-item interaction

このItemに入っていない商品は推論結果として出現しません。
そのため、未知商品をeventとして追加をしても推論結果が変わることや推論結果として新しく商品が登場することはありませんでした。

ここで未知商品を反映させるためには商品登録時にPutItemsをする必要があります。

2. "interactions"データセットimportだけではput eventの内容は消えない

今までdailyで計算をする際にデータセットを毎日importすることで上書きをしていました。
これはデータセットの肥大化を防ぐことを目的として行なっておりました。

put eventで追加したデータは"interactions"データセットとして追加されていきます。

そのため、今回リアルタイムに追加をしたeventの内容と、毎日の集計しているデータセットの中身が被ってしまう問題が発生しました。

"interactions"データセットを削除することでevent trakcerに追加した中身を消すことができます。
しかし、"interactions"データセットを削除するためにはevent trackerの削除やfilterの削除も必要です。

そのため、実際に試したところ、約20~30分filterが不在になることとなりました。
(この時間は今回試したデータセットの大きさの場合であり、データセットの大きさなどで変化します。)

f:id:sugiiiii:20211216111217p:plain

filterではすでに購入した商品などを除くような処理をいれているため、filterがないことはよくないと判断をし、最終的には"interactions"データセットは初期load以降はevent trackerで補うように変更をし毎日の作り直しをやめました。

さいごに

今回、リアルタイムな閲覧情報などをAmazon Personazlieのevent trackerで導入することで変化するレコメンドについてご紹介をしました。
また、ご紹介した機能は検証中のため、現在全ユーザに公開されている機能ではありません。

これからももっとよりよい精度と新しい発見を提供できるようにレコメンドに磨きをかけていきたいと思います。

最後までお読みいただきありがとうございました。明日はkikuchiさんとcuresevenです!