タイムライン機能にストーリーのパーソナライズ推薦を導入した話
Photo by Etienne Girardet on Unsplash
こんにちは、ウォンテッドリーでデータサイエンティストをしている右手 (@ghibney) です。今回は、Wantedly のアプリに 2025 年 12 月に加わったタイムライン機能に、パーソナライズ推薦を導入した事例を紹介します。
私が所属する Visit Recommendation Squad は、主に会社訪問アプリ Wantedly のマッチングを推薦システムで支えています。しかし直近では、タイムラインのような新しい機能や、他プロダクトへの推薦の導入も行っています。チームの中長期的な方向性は、弊社市村のブログ「ウォンテッドリーのデータサイエンティストが今後取り組む主要課題」にまとまっているので、よければあわせてご覧ください。
目次
タイムライン機能と初期課題
推薦モデルについて
候補選びとスコアリングの工夫
限られたデータのなかでどう評価し、判断したか
A/B テストの結果
おわりに
タイムライン機能と初期課題
タイムラインは、日々のキャリアについて考えるきっかけを届けることを目的とした機能です。「シゴト探し」のためだけでなく、普段からキャリアについて考えたい人向けに、パーソナライズされた情報をフィードとして届けます。機能の詳細はリリース記事にまとまっています。
フィードにはニュースなども流れますが、中心となるコンテンツがストーリーです。ストーリーは、企業が日々の仕事の様子や働き方、価値観などをブログ形式で発信するコンテンツで、Wantedly 上ではタイムラインが生まれる前から存在していました。
タイムラインの初期リリースでは、シンプルなルールベースでストーリーの推薦を行っていました。タイムラインの趣旨に合わないストーリーを除いたうえで、職種ベースでおすすめを用意する形です。職種ベースのおすすめは、同じ職種のユーザーには同じ並びを返します。そのため、一人ひとりの関心に合わせて幅広いストーリーを届ける余地が残っていました。
主要指標は「タイムラインを訪れたユーザーのうち、ストーリーを 1 本以上読んだ人の割合」と決め、これを相対で +10% 以上改善することを目標にしました。あわせて、閲覧をより多くのストーリーに行き渡らせることも狙いにしています。
推薦モデルについて
推薦のモデルというと、クリックや読了を教師データにしたモデルを思い浮かべる方が多いと思いますが、今回は、LLM と学習済みの埋め込みモデルを使ったシンプルな推薦システムを実装しました。
学習済みのモデルを利用した理由は、ストーリーの閲覧が人気ストーリーに偏っており、学習に使える行動データがまだ十分に溜まっていなかったためです。
そこで、事前学習済みの日本語テキスト埋め込みで、ストーリーとユーザーを同じベクトル空間にマッピングして、近傍探索でユーザーに近いストーリーを上位に出す、コンテンツベースの構成を選びました。
推薦結果は、日次のバッチであらかじめ計算しておきます。大きく次の 4 ステップです。
- 埋め込みの計算: ストーリーとユーザープロフィールを、日本語の埋め込みモデルでベクトルにする
- 候補選び: このフィードと相性の良いストーリーを LLM で選ぶ
- リランク: ユーザーのベクトルに近いストーリーを近傍探索で上位に並べる
- 書き出し: ユーザーごとの並びを、BigQuery に保存する
近傍探索には、グラフベースの近似最近傍探索を使います。前もって計算しておくため、配信のときは結果を読むだけで済み、タイムラインに必要な応答速度も問題ありません。
ユーザーの表し方は、推薦の質を大きく左右します。今回は、閲覧履歴とプロフィールの両方を使いました。閲覧履歴からは最近読んだストーリーの傾向を、プロフィールの「この先やりたいこと」「自己紹介」「職歴」などからは興味の手がかりを取り込みます。この 2 つは、閲覧の多さに応じて混ぜます。履歴がまだ少ないうちはプロフィールを、履歴が増えるほど履歴に重みをつけます。閲覧履歴がまだないユーザーでも、プロフィールから最初のおすすめを作れるので、これがコールドスタート問題の対策になっています。
候補選びとスコアリングの工夫
先ほどの 4 ステップのうち、候補選びと、リランク時のスコアリングを、もう少し詳しく説明します。
近傍探索は「似ているもの」を上位に出します。ただ、似ていることと、フィードで読んで面白いことは、必ずしも一致しません。そこで候補選びとスコアリングにも手を入れました。
候補選びには LLM を使います。ストーリーの良し悪しを決めるのではなく、このフィードとの相性を見るためです。タイトルや本文の内容から、タイムラインで読まれやすいストーリーかどうかを判断し、相性の良いものを候補にします。
スコアリングでは、同じ傾向のストーリーが上位に固まらないよう、並びに多様性を持たせます。初期のランキングを社内で見たときに「読んでいて面白くない」という声があり、それを反映しました。
こうして作った推薦を、限られたデータのなかでどう評価したかを、次に説明します。
限られたデータのなかでどう評価し、判断したか
データが限られていると、評価も難しくなります。クリックや読了を正解データにしたオフライン評価は、少ないデータでは結果が安定せず、指標によって良し悪しが分かれることもありました。そこで、定性評価とオンラインの A/B テストの 2 段階で確かめました。
定性評価では、社員に実際のランキングを見てもらいました。あわせて、LLM にいくつかのユーザー像を演じさせ、興味を持てそうかを判定させました。前述の「読んでいて面白くない」という声も、ここで出たものです。改善したランキングで評価が上がったのを確認してから、オンラインに進みました。
A/B テストでは、既存の職種ベースのおすすめと、新しいパーソナライズ推薦を、ユーザー単位で約 2 週間比較しました。主要指標は「ストーリーを読むユーザーの割合」とし、ガードレールとして一人あたりの閲覧数などを見ました。
A/B テストの結果
主要な結果は次の表のとおりです。数値はすべて、既存の職種ベースのおすすめに対する相対の変化です。
主要指標である「ストーリーを読むユーザーの割合」は、目標の +10% を大きく上回りました。ガードレールに置いた一人あたりの閲覧数も悪化せず、むしろ改善しています。
副次的な効果として、読まれた著者の数も大きく増えました。特定の人気ストーリーに偏らず、幅広いストーリーが読者に届くようになりました。テキストの内容をもとにしたコンテンツベースの推薦が、良い方向に働いた結果だと考えています。
セグメント別に見ると、効果が大きかったのはコールドスタートの層でした。閲覧履歴のないユーザーや新規ユーザーで改善幅が大きく、プロフィールを起点にした設計の狙いと重なります。
主要指標が目標を大きく上回り、ガードレールも保てたことから、全ユーザーへ展開しました。
おわりに
今回は、学習済みランカーを持たない軽い構成でも成果を出せることが確認できました。コールドスタート向けのブレンドと、LLM を使った候補選びを組み合わせた結果、主要指標は目標以上に改善しています。
今後は、行動データを活用したパーソナライズの強化に取り組みたいと考えています。
ウォンテッドリーでは、ユーザーにとってより良い推薦を届けるために日々開発を続けています。推薦システムづくりに興味がある方は、ぜひ一度カジュアルにお話ししましょう。