Upgrade to Pro — share decks privately, control downloads, hide ads and more …

マルチテナント型SaaSにおける汎用的なUser-itemレコメンド構築の第一歩

Avatar for Yusuke Horibe Yusuke Horibe
May 06, 2025
62

 マルチテナント型SaaSにおける汎用的なUser-itemレコメンド構築の第一歩

Recommendation Industry Talks #6で発表した資料です。
多様なユーザー体験の実現を目指し、コミュニティ運営プラットフォーム「Commune」のホーム画面の投稿フィードに「おすすめ」タブを新設してパーソナライズされた投稿レコメンド(For You レコメンド)を導入した事例を紹介しています。

Avatar for Yusuke Horibe

Yusuke Horibe

May 06, 2025
Tweet

Transcript

  1. © Commune Inc. All rights reserved ⾃⼰紹介 2 堀部 勇介(Yusuke

    Horibe) 2014~2016 Webアナリスト@広告代理店 2016~2018 データアナリスト@EC事業会社 2018~2023 データサイエンティスト@EC事業会社 2023/12~データサイエンティスト@Commune X:@suk1yak1 趣味:短期分析コンペ、キャンプ、編み物(かぎ針編み)
  2. © Commune Inc. All rights reserved 従業員コミュニティ 5 顧客コミュニティ LTV向上

    インサイト獲得 新規獲得 理念新規‧ ⾵⼟改⾰ エンゲージ メント向上 イノベー ション推進 ⼈材育成 対象 ⽬的 ユーザー ファン 会員 社員 アルバイト‧パート パートナー コミューンが提供するプロダクト
  3. © Commune Inc. All rights reserved 6 コミュニティ運営のための多種多様な機能があります(⼀般的なSNSとの⼤きな差分) ポイント/バッジ DM機能

    ネイティブアプリ ポップアップ AI⾃動⽣成 カスタム リアクション グループ ⾃動ダイジェスト メール UIタイプ カスタマイズ 分析 ダッシュボード イベント 管理者⼆要素認証 webhook お知らせ/通知 アンケート ユーザー情報 取得‧管理 アイスブレイク コメント コンテンツ投稿 各種タグ埋め込み グループ⾃動追加 チェックイン(β版) ⽴ち上げ⽀援 ⽉次レポート コミューンの機能⼀覧
  4. © Commune Inc. All rights reserved For You レコメンド What

    ユーザーごとにパーソナライズした 投稿をレコメンド Where コミュニティのホーム画⾯に表⽰される 投稿フィードに新しく「おすすめ」タブを追加 リリース時の投稿
  5. © Commune Inc. All rights reserved 導⼊の背景‧課題 背景:⽬指したいコミュニティ像 同じコミュニティの中でもユーザーの趣味‧嗜好は多種多様 パーソナライズにより、誰でも居⼼地のいい体験にしたい

    課題:画⼀的な体験 既存の投稿フィードは新着順のような全ユーザー同じロジックのみ → まずは閲覧数の多いTOP画⾯にある投稿フィードをパーソナライズ
  6. © Commune Inc. All rights reserved 実装の制約 ‧Vertex AI Pipelines(KFP)の仕様としてパイプラインを⼀度

    JSON 形式にコンパイルする 必要あり ‧コンパイルのタイミングで各コンポーネントにマシンスペックを割り当て ‧学習‧推論:⽇次で実⾏ ‧API:予め推論しておいた結果をユーザー‧コミュニティIDをキーとして呼び出し ‧対応できない点:アイテムのコールドスタート(新着投稿) 全コミュニティ共通のパイプライン x マシンスペック ⽇次のバッチ実⾏
  7. © Commune Inc. All rights reserved 採⽤した⼿法:2stage レコメンド • 理由:

    コミュニティの⼤⼩に関係なく、 安定して調整しやすい構成のため • ⽅針: 候補⽣成フェーズでデータ量を絞り込み → メモリ使⽤量を抑制 & ⾼速化 実装の⽅針:軽量&改善しやすさ重視
  8. © Commune Inc. All rights reserved 新規ユーザー向けロジック 「登録初期の関⼼」を反映 ロジック 過去のユーザーが会員登録から30⽇以内に

    アクション(閲覧‧いいね‧コメント‧ブックマーク)した⼈気投稿 スコアの付け⽅の⼯夫 登録直後のアクションを重要視 → 登録から⽇が浅いタイミングでのアクションほど⾼スコアを付与
  9. © Commune Inc. All rights reserved ユーザーが未アクションの⼈気の投稿 ロジック アクションが新しいほど⾼スコア 例:いいね=2

    / (⽇数+1)、閲覧=1 / (⽇数+1) フィルタリング 対象のユーザーが過去にアクションした投稿は除外 休眠ユーザー向けロジック
  10. © Commune Inc. All rights reserved 選定基準 ‧CPUのみで動作可能 ‧省メモリかつ⾼速 使⽤ライブラリ

    ‧Polars(省メモリ&⾼速) ‧LightGBM(軽量なモデル学習) ‧DWHのBigQuery も含め、Apache Arrow 対応で効率的に連携 技術選定のポイント
  11. © Commune Inc. All rights reserved データセットの設計 atmaCup #16 を参考に作成(分析コンペは役に⽴つ)

    ⽬的‧説明変数 ‧予測対象  各ユーザーの⽇別でインタラクションした投稿ID群 ‧特徴量  予測対象のセッションから直近2週間のインタラクション履歴 データスキーマ ‧session_id:date x user_id で⼀意のID ‧seq_no  :投稿を⾒た順番(特徴量の重み付けで多⽤) ‧item_id  :投稿ID ‧score   :アクションがあれば1
  12. © Commune Inc. All rights reserved 候補抽出ロジック① ルールベースで多様な投稿をカバー • 最近の⼈気投稿   セッションの後半に⾒られやすい投稿(score

    x seq_no) • ちょっと前の⼈気投稿 セッションの前半に⾒られやすい投稿(score / seq_no) • 新規投稿 アクションのないフレッシュな投稿も候補に • 未視聴投稿者の⼈気投稿 ユーザーがまだ⾒ていない投稿者の⼈気投稿(セレンディピティ) Polarsのみで計算
  13. © Commune Inc. All rights reserved 候補抽出ロジック② ⾏列計算ベースで⽂脈を捉える • 遷移確率行列 「Aを見た後にBを見やすい」

    • 二次確率遷移行列 ↑のより長期的な遷移パターンも考慮( 2ステップ先まで) • 共起行列 ユーザーの中期的な興味の傾向を反映 • BPR(Bayesian Personalized Ranking) 「この人はAよりBを好む」ような相対的な好みの傾向を学習 Polarsのみで計算
  14. © Commune Inc. All rights reserved Reranking特徴量① 候補⽣成時のデータを活⽤した特徴量 ⾏列を利⽤した特徴量 ‧ユーザーの⾏動ログと、投稿ごとの⾏列を組み合わせて、セッション x

    投稿単位での集 約特徴量を作成 ‧合計値、最⼤値、重み付き集計(新しいアクションほどスコアが⾼くなるよう重みづけ)
  15. © Commune Inc. All rights reserved Reranking特徴量② その他の追加した特徴量 セッション関連の特徴量 ‧ログの集約情報 ‧セッションに含まれる投稿数

    投稿‧投稿者に関する特徴量 ‧投稿カテゴリ、投稿者情報 ‧投稿本⽂の⽂字数‧⾏数、画像の有無 ‧投稿作成⽇からの経過⽇数 ‧投稿者のロール(⼀般 / 関係者 / 管理者) ユーザー関連の特徴量 ‧ユーザー登録からの経過⽇数 ‧フォロー‧フォロワー関係(ユーザー間のつながり) RFM × アクション特徴量 指標 説明 Recency 最後にアクションした⽇からの経過⽇数 Frequency アクションを⾏った⽇数 Monetary アクションの総回数(コメント‧投稿‧閲覧など) ユーザー‧投稿‧セッションそれぞれの情報を組み合わせ
  16. © Commune Inc. All rights reserved Cross Validation戦略 train valid

    test train valid test user_idによるGroupKFold TimeseriesSplit 採⽤⼿法:user_idによるGroupKFold TimeseriesSplitと⽐較した結果  → GroupKFoldの⽅が map@50 が約1.04倍向上(オフライン&testデータ) ※改善の余地あり
  17. © Commune Inc. All rights reserved PoC時のフィードバック収集⽅法 Streamlitでデモを作成  コミュニティとユーザーを選択する    と、レコメンドされる投稿群とユーザー 

    のアクション投稿 を表⽰ フィードバック依頼先  ロイヤルユーザーを把握しているコミュ  ニティ運営の代⾏やサポートをしている  チーム 特定ユーザーを想定した上で活用イメージを検証
  18. © Commune Inc. All rights reserved デモからのフィードバック①:クリックベイトへの対応 フィードバック  クリックされやすいが内容の薄い‧あまりよくない投稿が上位にレコメンドされる 定量的に⾒ると

     閲覧されるが、いいねやリアクションがつかない投稿が多い 対応策  ⽬的変数の重みづけを調整   → すべてのアクションを同じ重み(=1)で扱っていたのを⾒直し 閲覧:1、 それ以外のアクション: 2
  19. © Commune Inc. All rights reserved デモからのフィードバック②:新規向けコンテンツが既存ユーザーに出てくる フィードバック  既存ユーザーに、新規ユーザー向けの投稿がレコメンドされていて違和感 定量的に⾒ると

     ユーザーの会員登録からの経過⽇数に応じてコンテンツの出し分けが必要 対応策  ユーザー特徴量に → 会員登録からの経過⽇数を追加  投稿特徴量に → ユーザーが投稿を閲覧した時の会員登録からの経過⽇数の平均を追加
  20. © Commune Inc. All rights reserved デモからのフィードバック③:投稿内のキーワードから趣味‧嗜好を反映したい フィードバック  カテゴリにはないキーワード(例:番組名‧出演者名など)から、  ユーザーの興味を汲み取ってほしい

    定量的に⾒ると  アクションした投稿本⽂に頻出する単語の傾向からユーザーごとの趣味‧嗜好を特定 対応策  投稿本⽂に対して、TF-IDF → SVD(次元圧縮) を適⽤  軽量な埋め込み特徴量として追加し、趣味傾向を反映
  21. © Commune Inc. All rights reserved デモからのフィードバック④:終了したキャンペーン投稿が出てくる フィードバック  募集が終了したキャンペーン関連の投稿がレコメンドされてしまう 定量的に⾒ると

     投稿とキャンペーンを紐づけてキャンペーン終了⽇を過ぎていれば除外対象 対応策  投稿内のURLからキャンペーンIDを正規表現で抽出  キャンペーンマスタと突合し、終了⽇が今⽇以前の投稿は除外
  22. © Commune Inc. All rights reserved オフライン評価も悪くないし、「これはいけるかも!」と思っていた⽮先―― コミュニティ開いた時にデフォルト で「おすすめ」が表⽰されちゃう ToB(新着情報をしっかり⾒せた

    い)の⼈たちからすると⾒せ⽅が変 わって困ってる モニターキャンペーンに関⼼が⾼い ユーザーに数ヶ⽉前のモニター投稿 ばかりが表⽰される。 新着のモニター以外のユーザー投稿 が優先的に表⽰されて欲しい。 運営も同様でホーム画⾯ですぐ新着 ユーザー投稿が閲覧できないことが 不便 デフォルトは「新着」順に戻して欲しい
  23. © Commune Inc. All rights reserved 管理者を除外していた ‧⼀般ユーザーのみを学習‧推論対象に設定  → 結果、新規ユーザー向けの古い管理者投稿が「おすすめ」に表⽰されてしまった

    介⼊群の全ユーザーに同じデフォルト表⽰を適⽤ ‧おすすめ表⽰を全ユーザーに⼀律で設定  → 管理者や超アクティブ層には新着順の⽅が適していた(事前に予⾒できたかも) 管理者投稿ばかりが出てしまう ‧公式投稿(管理者)は反応が集まりやすくスコアが⾼くなりがち  → 古い投稿でもスコアが⾼くなりがちになっていた しくじりポイント:初回リリースで⾒えてきた課題
  24. © Commune Inc. All rights reserved 管理者を推論対象に含める(ただし学習対象からは除外) ‧新規ユーザーと同じロジックでは体験が悪いため ‧学習データではアクションが多すぎてノイズになるため除外 デフォルト表⽰の⾒直し

    ‧ABテストを中⽌して、全ユーザー「おすすめ」→ 「新着」順に変更 ‧特に管理者‧アクティブユーザーに配慮 管理者投稿の扱いを調整 ‧管理者投稿は過去2週間以内のものだけ推薦  → 過去キャンペーン等の古い投稿を除外しきれない問題に対応 フィードバックへの対応まとめ
  25. © Commune Inc. All rights reserved 古い投稿でも価値を感じてくれるセグメントで効果あり 新規ユーザー  クリック率とクリック後のリアクション率が⾼い(⼀番効果が⾼かった) 休眠ユーザー

     クリック後のリアクション率が⾼い そこそこアクティブなユーザー(アクティブユーザー × 閲覧ページ数:中程度)  クリック率が⾼い  → 閲覧ページ数の多い‧少ないアクティブユーザーでは負けていた 効果のあったセグメント vs 新着順
  26. © Commune Inc. All rights reserved 嬉しい悲鳴:OOM(Out of Memory) 何が起きた?

    ‧最⼤規模のコミュニティでアクティブユーザーが急増! ‧リリース当初は問題なかったがOOM発⽣
  27. © Commune Inc. All rights reserved OOM対策:まずは簡単にできる⼯夫から 序盤の前処理 or 精度に影響が少ないところから実施

    データ型の最適化 → 必要最⼩限の⼩さい型への変換(reduce_mem_usage) 交差検証の分割数を減らす → cross validationのn_splits = 5 → 3 に変更 特徴量作成時のログ量を制限 ‧対象期間:   最⼤14⽇間 → アクションのあった直近7⽇間 ‧閲覧ログ数:   上限なし→最⼤400件まで
  28. © Commune Inc. All rights reserved Future Work② 新着投稿の推薦  • コミュニティにおいて、SNSと同様新着投稿が重

    要 • リアルタイム推論 or レコメンドと新着投稿のイン ターリービングを検討
  29. © Commune Inc. All rights reserved Future Work③ 推薦理由の表⽰ • 推薦理由の明⽰により、ユーザー体

    験の向上とフィードバック収集の促 進 • 案1: 各コンテンツごとに推薦理由を 付与 • 案2:推薦理由ごとの枠を設け、裏 側で複数のロジックを活⽤
  30. © Commune Inc. All rights reserved Future Work⑤ コミュニティ‧ユーザーに応じた複数ロジックの出しわけ  • 学習データが不⼗分な⼩規模コミュニティ向け

    に、コミュニティ横断のロジックを適⽤する • ユーザーやコミュニティのセグメントをより細 かくわけて、求めるジョブに応じたロジックを 作成