Gunosyデータ分析ブログ

Gunosyで働くデータエンジニアが知見を共有するブログです。

プッシュ通知にパーソナライズを導入して開封率が 50% 向上したはなし

はじめに

こんにちは、GunosyTechLab MediaML 所属の suchida です。 本記事では、2022 年春頃に auサービスToday のニュース記事プッシュ通知に導入したパーソナライズシステムについてご紹介いたします。

プッシュ通知とは

本記事におけるプッシュ通知とは、速報ニュースや話題となったニュースを各ユーザーのスマホに直接通知するサービスのことです。 auサービスToday では、毎日決まったタイミングに行うプッシュ通知(定時プッシュ)と不定期に行うプッシュ通知(速報プッシュ)を行っています。 プッシュ通知により、ユーザー目線ではアプリを開かなくても重要なニュースを知ることができ利便性の向上が期待できます。 また、事業者目線では DAU の底上げ効果や起動頻度が減少しているユーザーの呼び戻し効果が期待できます。

パーソナライズシステムの導入

従来では、プッシュするニュース記事の選定は編集チームが毎時間帯に行っており、全ユーザーに共通のニュースが通知される仕組みになっていました。 そこで新しくパーソナライズシステムを導入することで、プッシュ開封率の改善が期待できないか検証することになりました。 初手から全てのプッシュに適用するのはリスクが大きいので、まずは夜の定時プッシュを対象にして検証を進めていきました。

事前分析

パーソナライズシステムを導入する前に、軽く事前分析を行いました。 そもそもパーソナライズに効果が期待できるのかどうか把握しておくためです。

下図は、ユーザーを 9 つのクラスタ*1に分類して、各クラスタのプッシュ開封率の時系列遷移をプロットしたものです。 概ねどのタイミングのプッシュ通知でも各クラスタが同様の遷移を見せていることが確認できます。

ユーザークラスタごとのプッシュ開封率

また、赤い矢印で示してあるような特定のクラスタの開封率が高くなるプッシュ記事も存在していることが確認できました。 これらのクラスタは主にスポーツ好きに分類されるユーザー群であることが分かっています。 赤い矢印のプッシュ記事を確認してみると、スポーツ関連のニュースが送信されていることが確認でき、ユーザーの興味とプッシュ記事が近しい際に開封率も高くなることが確認できました。 その他にも同様の傾向が確認でき、実際にパーソナライズに効果が期待できそうだということになりました。

パーソナライズシステム

それではパーソナライズシステムにおける一連の処理を見ていきましょう。

A. 候補記事選定(自動)

まずは、プッシュしたい候補記事を自動で選定していきます。 なるべく多くのユーザーにマッチした記事を推薦するためには候補記事の数を大きく取りたいところですが、次の工程 B があるため最大でも 50 記事程度に候補記事を絞らないといけません。 そのため、以下のような処理を行い候補記事を選定しています。

NG 判定
  • プッシュ NG な記事を判定します。auサービスToday 独自の NG 基準*2があるので、明らかに NG に該当する記事は正規表現*3で判定しています。ユーザーにとってプッシュ通知はアプリの印象に直結するため、慎重に判定します。また、誹謗中傷や煽り・釣り記事などの扇情的な記事については別途稼働しているシステムの結果で対応しています。扇情記事については以下のブログも参考にしていただけると幸いです。

data.gunosy.io

多様性の確保
  • 類似記事をひとつに集約します。auサービスToday はキュレーションアプリなので、複数の媒体社様から同じ話題に関する記事が入稿されることがあります。候補記事群が同じ話題の記事ばかりになるとパーソナライズがうまく機能しなくなってしまいますので、類似記事の集約を行い候補を多様に保つことでより多くのユーザーにマッチした推薦を行えるようにします。この処理には別途稼働しているシステムの結果を利用しています。
  • 候補記事群の記事カテゴリが類似しすぎないように、適度にばらけさせます。カテゴリごとに記事入稿数に偏りがあるため単純に全データを利用してしまうと、候補記事群もその偏りを引き継いでしまうからです。
スコアリング
  • 記事人気スコアによって価値を変化させます。アプリ上のユーザーログを集計した記事統計量を利用しています。
  • 記事作成時間によって価値を変化させます。古い記事は情報自体が古くなってしまっている可能性があるため価値減衰を行います。ただし、古くても価値の変わらない記事*4も存在するため、必要な記事にのみ価値減衰を行います*5

B. 候補記事選定(手動)

次に、編集チームによる候補記事の最終チェックが行われます。 ここでは、工程 A で挙げたプッシュ NG 基準に従って、様々な観点から候補記事をチェックしていきます。 工程 A の漏れにも対応してもらっており、現状、自動選定された候補記事のうち 10% 程度がこちらで NG 判定となっているような印象です。 こちらは、定期的に NG 記事の共通点を確認し、判定ロジックにフィードバックしています。

C. おすすめプッシュ記事の割り当て

最後に各ユーザーに対しておすすめできる 1 記事を割り当てていきます。 パーソナライズシステムのコアの部分です。 別システムにて記事ベクトルとユーザーベクトルを事前に生成しているので、それを利用しています。 具体的には、ベクトル間のコサイン類似度を計算しスコアが最大の記事をユーザーのおすすめプッシュ記事として割り当てています。

ベクトルについては以下の記事が参考になるかもしれないので、よければチェックしてみてください。 data.gunosy.io

システムフロー

システムの全体フローは下図のようになっています。

システムフロー

各処理を行うバッチは EKS 上で稼働しており、データ保管には DynamoDB, S3 といったサービスを利用しています。 おすすめ記事割り当ての処理はできるだけ高速に行いたいので、事前に必要なユーザーベクトルを収集し複数の npz*6 に圧縮して保管し、割当処理時にすぐ利用できるようにしています。 割当処理は編集チームの作業結果に依存しており、仮に割当処理に時間がかかってしまう場合はその分編集チームに前倒しで作業してもらう必要がでてしまうためです。 プッシュ送信タイミングは固定されているので処理の後ろ倒しはできません。 また、編集チームには他の業務との兼ね合いがあるため気軽に作業時間をずらすことは難しく、割当処理の処理速度には注意が必要です。 無論、チーム都合に関わらずどのバッチ処理でも高速化を目指しています。

また編集チームによる NG 判定処理は、既存の管理画面があるのでそこに新しく判定画面を作成し利用していただいています。

A/B テスト

こちらは、実際に A/B テストを実施した際のサマリになります。 プッシュ開封率は約 50% 改善しており、DAU や新規 RR にもプラスの影響が確認できました 🎉

A/B サマリ

集計値はプッシュされたユーザー全体を見ているため、パーソナライズされたユーザー群のみに絞るとより効果は出ていると思われます。 実際、事前分析で触れたユーザークラスタの一つであるスポーツクラスタ*7のプッシュ開封率は約 60% 改善していました。

今後の課題

今回の A/B を通して見えてきた課題としては以下の点が挙げられます。

  • ニュースの話題の大きさによるパーソナライズ記事の切り替え
    • 例えば、有名グループの解散報道など明らかにユーザーの興味を引き開封されそうな話題が存在する際に、普段どおりのパーソナライズ記事を送るのではなく一律で話題記事を送るほうが開封率が高くなるのではないか、という具合です。実際、プッシュ通知の A/B をしていても A/B 実施時期(の話題の閑散具合)により数値がガラッと変わることは少なくないです。
  • コサイン類似度の値が小さいときに無理におすすめ記事の割り当てを行う必要はない可能性
    • 現状、コサイン類似度の値に関わらず最大の記事をおすすめ記事としてプッシュしているのですが、類似度が全体的に低いのであればその値は信頼せず、確率的に開封されやすい記事を送るほうがいいかもしれません。これについては他の自社アプリで検証フェーズに入っているところです。

おわりに

今回の結果を踏まえて、パーソナライズシステムは夕方のプッシュ通知にも導入しています。 上記に挙げた課題以外にも数多くの課題が挙げられており、優先順位をつけ改修に取り組んでいきたいと思います!!

*1:クラスタ生成にはユーザーベクトルと k-means を利用しています。ETL にて毎日ユーザークラスタ割り当てを行っています

*2:タイトルと本文の内容が一致していないか、露骨な卑猥表現を含んでいないかなど

*3:機械学習を導入しても良いかもしれません

*4:豆知識・ライフハックなど

*5:現状は記事に付与されているカテゴリーをベースに行っています

*6:Python の NumPy 情報を保持したまま圧縮する方法

*7:クラスタに属しているユーザーは全員推薦対象ユーザーになります