こんにちは。自然言語処理エンジニアの石原です。
Yahoo!ショッピングでは、ユーザーが目的の商品にたどり着きやすくなるよう、検索機能の改善を継続的に進めています。 本記事では、その中から、直前の検索クエリに応じて検索サジェストの候補を並び替える取り組みを紹介します。
Yahoo!ショッピングの検索サジェスト
検索サジェストは、検索クエリの自動補完として、検索窓に入力している途中で検索したいクエリの候補を提示する機能です。Web検索やECサイトの検索でよく見られる機能で、Yahoo!ショッピングでもユーザーが商品を探し始める入口の1つになっています。
たとえば、検索窓に「ワンピース」と入力したときに、「ワンピース レディース」「ワンピース 夏」「ワンピースカード」などの候補が表示されます。ユーザーは候補を選ぶことで、検索語をすべて入力しなくても検索できます。
検索サジェストでは、表示できる候補数に限りがあります。特にスマートフォンのように画面が限られる環境では、ユーザーが探しているものに近い候補を上位に出せるかどうかが、検索体験に大きく影響します。
同じ入力でもユーザーの意図は変わる
では、サジェスト候補はどのように並べればよいでしょうか。
検索頻度やクリック情報などの集計値を使って候補を並べることが考えられます。よく検索される候補やよく選ばれる候補を上位に出すことで、多くのユーザーにとって選びやすい候補を提示できます。
一方で、同じ入力文字列でも、上位に出すべき候補はユーザーがいま何を探しているかによって変わります。
たとえば「ワンピース」という入力は、ファッションのワンピースを探している場合もあれば、漫画作品に関連する商品を探している場合もあります。検索頻度ベースで並べると、上位にもファッション系の候補と漫画系の候補が混ざって表示されます。
このように、入力文字列だけでは、ユーザーがどちらの意図で検索しようとしているのかを決めきれない場合があります。では、どのようにすれば検索意図を反映した候補を上位に出せるでしょうか。
直前クエリを考慮したランキングモデル
入力中の文字列だけでは検索意図を判断しにくい場合でも、直前の検索クエリを見ると、ユーザーが探しているものの文脈を推測できることがあります。
たとえば、下の図のように直前に「呪術廻戦 フィギュア」と検索していたユーザーが、続けて「ワンピース」と入力している場合を考えます。この状況では、服のワンピースよりも、漫画作品に関連する商品を探している可能性が高そうです。
では、このような検索意図の違いを、ログからどのように捉えればよいでしょうか。ここで利用できるのがクリックログです。検索サジェストでは、入力中のクエリに対して複数の候補を表示し、ユーザーはその中から検索したい候補を選びます。このログを見ることで、「直前にどのような検索をしていたときに、 どの候補が選ばれたか」を確認できます。
ある入力に対して複数のサジェスト候補が表示され、その中からユーザーがクリックした候補がある場合、クリックされた候補を正例、同時に表示されていた他の候補を負例として扱います。このデータを使うことで、直前クエリの文脈に対してクリックされやすい候補が上位に来るようなランキング学習が可能になります。
ランキングモデルには、Yahoo!ショッピングの検索クエリで事前学習したBERT(Bidirectional Encoder Representations from Transformers)をファインチューニングして使います。学習では、図中の(1)「直前のクエリ」、(2)「入力中のクエリ」、(3)「サジェスト候補」を候補ごとに組み合わせ、次の形式でBERTに入力します。
[CLS] {(1)直前の検索クエリ} [SEP] {(2)入力中のクエリ} [SEP] {(3)サジェスト候補} [SEP]
たとえば、直前のクエリが「呪術廻戦 フィギュア」、入力中のクエリが「ワンピース」の場合、サジェスト候補ごとに次のような入力を作ります。
[CLS] 呪術廻戦 フィギュア [SEP] ワンピース [SEP] ワンピース レディース [SEP]
[CLS] 呪術廻戦 フィギュア [SEP] ワンピース [SEP] ワンピース 夏 [SEP]
[CLS] 呪術廻戦 フィギュア [SEP] ワンピース [SEP] ワンピースカード [SEP]
...
[CLS] 呪術廻戦 フィギュア [SEP] ワンピース [SEP] ワンピースフィギュア [SEP]
...
各候補の入力からクリックされやすさのスコアを出します。学習時は、同じ表示機会に出た候補群のスコアをSoftmaxにかけ、クリックされた候補を正解としてCross Entropy lossを計算します。
推論時は、学習済みモデルで取得済みのサジェスト候補それぞれにスコアを付け、そのスコアが高い順に候補を並べ替えます。直前クエリを入力に加えることで、モデルは入力中のクエリと候補の関係だけでなく、その候補が直前の検索文脈に合っているかも考慮できます。
オフライン評価
まず、ログを使ったオフライン評価でリランクの効果を確認しました。評価では、候補が表示されたログに残った候補全件(最大20件)をリランクしました。評価指標にはMRR、hits@1、hits@3を使いました。
MRRは、クリックされた候補が何位に出ているかを見る指標です。クリックされた候補が上位にあるほど高くなります。hits@1やhits@3は、クリックされた候補が上位1件、または上位3件に含まれている割合を見る指標です。
評価結果は、既存の表示順に対する相対改善率として示します。
| 手法 | MRR | hits@1 | hits@3 |
|---|---|---|---|
| クリック数ベース | +2.4% | +9.3% | −1.4% |
| BERT(直前クエリなし) | +7.1% | +18.1% | +1.8% |
| BERT(直前クエリあり) | +11.6% | +26.9% | +5.2% |
まず、入力中クエリご とに候補のクリック数を集計して並び替える方法では、MRRとhits@1が改善した一方、hits@3はわずかに低下しました。
次に、BERTに直前クエリを入れない場合でも、すべての指標でクリック数順に並び替える方法を上回りました。入力中のクエリと候補の組み合わせをモデルでスコアリングすることで、単純な集計値だけでは捉えにくい候補間の違いを反映できていると考えられます。
さらに、BERTに直前クエリを入れた場合が最も高い改善になりました。直前クエリを加えることで、入力中のクエリだけでは判断しにくい検索意図を反映できていることが確認できます。
リランク結果の例
それでは、並び替え例を見てみましょう。
「ワンピース」の例
入力中のクエリが「ワンピース」の場合の、BERTによるリランク結果です。
| 順位/直前のクエリ | なし | レディース tシャツ | 呪術廻戦 フィギュア |
|---|---|---|---|
| 1 | ワンピース レディース | ワンピース レディース | ワンピースフィギュア |
| 2 | ワンピースカード | ワンピース 夏 | ワンピースカード |
| 3 | ワンピース 春 | ワンピース 春 | ワンピース レディース |
| 4 | ワンピース 夏 | ワンピース 長袖 | ワンピース 112巻 |
| 5 | ワンピース 長袖 | ワンピース 半袖 | ワンピース 夏 |
直前クエリがない場合は、ファッション系の候補と漫画系の候補が混在しています。一方で直前クエリを使うと、「レディース tシャツ」の後ではファッション系の候補が、「呪術廻戦 フィギュア」の後では漫画系の候補がそれぞれ上位に来ています。
「す」の例
入力が「す」のように短い場合、候補にはさまざまなカテゴリが混在します。たとえば、スマートフォン関連、ゲーム関連、靴、飲料など、複数カテゴリの候補が出やすくなります。
以下は、入力中のクエリが「す」の場合のBERTによるリランク結果です。
| 順位/直前のクエリ | なし | スマホカバー | マリオカート | 靴 | ミネラルウォーター |
|---|---|---|---|---|---|
| 1 | スマートウォッチ | スマホケース | スイッチ2 | スニーカー | 水 |
| 2 | スニーカー | スニーカー | スマートウォッチ | スノーシューズ | スニーカー |
| 3 | スマホケース | スマートウォッチ | スニーカー | スマホケース | スマートウォッチ |
| 4 | 炊飯器 | スマホショルダー | スマホケース | スマートウォッチ | スマホケース |
| 5 | スーツケース | スマートリング | スマートタグ | スーツケース | 炊飯器 |
このように、上の例では、短い入力で候補のカテゴリが混在している場合でも、直前クエリに近いカテゴリの候補が1位に来ています。
オンライン評価
オフライン評価で改善が見られたため、サジェスト表示に適用してA/Bテストを行ったところ、サジェスト候補のCTR(Click Through Rate、クリック率)が相対で 約7%改善しました。
オフライン評価で見られた候補順位の改善を、実際のユーザー行動でも確認できました。
おわりに
本記事では、Yahoo!ショッピングの検索サジェストで、直前クエリを使ってサジェスト候補をリランクする取り組みを紹介しました。
直前クエリを使うことで短期的な文脈を反映した候補順位を作ることができ、オフライン評価とA/Bテストのどちらでも改善を確認できました。
今後は、直前クエリ以外の文脈情報の利用に加えて、クリックログに含まれる表示位置の影響を考慮した学習や、モデル軽量化・運用改善を検討していきます。


