8の付く日です。
はじめに
ダイナミッククリエイティブ
広告主のサイトに訪れたことがあるユーザーに対して、閲覧履歴をもとに興味がありそう(クリックやコンバージョンしそう)な広告を自動で生成することです。ユーザー一人一人に最適化した広告が表示できます。
unis
株式会社オプトには unis というダイナミッククリエイティブのツールがあります。
ちょっとLPは放置気味にしか見えないですね・・・。
こちらでは商品の固定表示とCV順についてしか説明してないですが、他にも
- 指定した商品(カテゴリ)の固定表示
- ランキング(CV、接触など)
- 閲覧履歴からCVしていないものを再度表示
- 協調フィルタリング
などがあります。
商品のプロモーションにも使えるしパーソナライズもできるってことですね。
協調フィルタリングにはsparkを使っています。
仕組み
訓練データの作成
unisを導入しているクライアントのサイトにはunisのタグが埋め込まれていて、閲覧や購入などのイベントを取得しています。これらのイベント情報(閲覧履歴)を1時間ごとにRedshiftに読み込んで集計します。
集計したデータはクライアントごとに (ユーザーID, 商品ID, レート)
の形にしてS3にアンロードします。
学習
S3に置いた訓練データを使って学習します。
学習にはEMRでsparkの協調フィルタリング(ALS)を使用します。
学習の結果得られたユーザーの特徴行列と商品の特徴行列を再びS3に保存します。
学習は12時間ごとに行なっています。
cf. https://www.slideshare.net/uryyyyyyy/spark-mllib-70290015
推薦
サーバーにユーザーの特徴行列と商品の特徴行列を読み込みます。
ユーザーIDと商品IDを受け取り、ユーザーIDが読み込んだ行列に存在すればそのユーザーへのおすすめ度を計算します。
ユーザーIDが存在しない場合、今度は商品IDを用いて商品の特徴行列を使いその商品の類似商品を計算します。
スコアが高い商品N件を推薦します。
苦労(工夫)した点
レスポンスは100ms以内に返しやがれ
広告配信を行なっているため、バナーの表示に数秒とかかかるのは致命的です。
サーバーにはscalaを使用していましたが、行列計算はけっこう遅かったのでそこだけjavaで書いています。
200QPSでも遅延しないようにしやがれ
100ms以下で計算できればそれでいいというわけではなく、配信強化時は秒間数百件以上の配信が行われます。
キャッシュを用いて同じユーザーや商品のときの計算を行わないようにしたり、訓練データの作り方を変えてそもそも不人気な商品を取り除いたり、使うユーザー数に上限を設けるなど特徴行列が小さくなるようにしました。
それでも限界を超えるようなリクエストがくると爆発します。
おわりに
広告の効果が向上し、配信量が増えると上記の苦労した点で述べた箇所が爆発する諸刃の剣みたいなシステムが完成しました。
1年前に導入し、今日まで小さな改善を積み重ねてますが、クライアントの業種やサイトのユーザーによって全く効果がないということもわかり始めてきました。手法一つで汎用的に何にでも使えるということはありえません。
来年は欠点を克服した新システムの導入に努めていきます。