一休.com Developers Blog

一休のエンジニア、デザイナー、ディレクターが情報を発信していきます

【検索改善】マイクロサービス化から適合率向上まで

はじめに

こんにちは。宿泊検索チームの渥美 id:atsumim です。

最近は検索改善のプロジェクトを行っており、特にキーワードでの検索の改善を行っています。
今回はその中でこの1年くらいの改善についてお話しします。

言葉の定義

先にこの記事で用いる言葉の説明をします。

ハード検索

指定した条件と完全に一致する結果のみを返す検索方法です。
今回は ID に変換される検索のことを指します。
ID なので一文字でも違うと、異なる条件として取り扱われます。
より具体的に言えば、下記の検索パネルから選択できる条件はすべて ID に変換されます。

例えば箱根は are=160418 となります

ソフト検索

指定した条件と部分的に一致する結果も返す検索方法です。
今回は ID に変換されない検索(つまり純粋なキーワード)のことを指します。
例えば 一休 と検索したときに 一休み一休さん などの結果が含まれることになります。
より具体的に言えば、上記の検索パネルからできないキーワードのことになります。

箱根かに問題 🦀

ことの発端は「かに」でした。
まずは下記のスクリーンショットをご覧ください。
一年前の一休.com で「箱根, かに」を検索した画面です。

検索結果A 検索結果B

同じ条件であるはずの「箱根」「かに」の検索結果が異なることがわかります。
検索結果Aでは56件、検索結果Bでは96件となっています。
また、表記も 箱根, かに箱根 かに で微妙に異なっています。

なぜこのようなことが起きたのでしょう。
原因は検索方法の違いにあります。

検索結果A
「ハード検索 + ソフト検索」の検索方法です。
細かく見ると「ハード検索: 箱根 , ソフト検索: かに 」という検索になります。
一休.com で使われるクエリパラメータに変換すると ?are=160418&kwd=かに という形になります。

検索結果B
一方、検索結果B は「ソフト検索」のみの検索方法です。
細かく見ると「ソフト検索: 箱根, かに 」という検索になります。
一休.com で使われるクエリパラメータに変換すると ?kwd=箱根 かに という形になります。

ソフト検索では、クチコミの文章や施設・プランの紹介文などからもデータを取得しています。
そのため、施設が実際に箱根になくても、 箱根 というワードがクチコミに入っていると検索結果に表示されてしまっていたのです。
また、クチコミのデータの中には「穏やかに過ごせました」や「静かに楽しめました」などの文章が入っています。 これもソフト検索で「かに」に引っかかってしまい、本来箱根の旅館でかにを食べたいのに全く別の結果が返ってきている状態でした。
これを「箱根かに問題」と呼びます🦀

システム的な問題

「箱根かに問題」が根本的になぜ起きたのか、原因はシステム構成にありました。
元々の検索システムの構成は下記のようになっていました。

Before

システム構成

先に図の説明をします。

キーワードを検索すると、まずバックエンドからサジェストAPIが呼び出されます。
サジェストAPI は1つの単語に対して「キーワードを変換したID( are など)」または「変換できなかったキーワード( kwd )」を返却します。
この「ID に変換できなかったキーワード」に対してキーワードAPIが呼ばれます。
キーワードAPI は前述の通り、「クチコミ」や「施設の説明文」などの文章からキーワードにマッチした施設のデータを返却します。
それを元に検索結果がフロントエンドで描画されます。

これが元々の構成です。

問題点

問題となっていたのは、サジェストAPI です。
本来、その名の通りキーワードに対応するサジェストを表示するために使うのが サジェストAPI です。

本来のサジェスト用途
しかしこれを検索のために使っていたために問題が起きていたのです。
サジェストAPIはそもそも1つの単語しか受け取りません。
つまり、例えば「箱根 かに」という2語のキーワードを1語として受け取り「kwd=箱根 かに」というように解釈してしまいます。

これはサジェストの用途であれば問題がないのですが、検索用途では問題になります。
本来「箱根」は are=160418 という ID に変換されるべきなのです。
また、返ってきた kwd に対してフロントエンドでも変換を行う実装が入っており、検索周りの実装を複雑にしていました。

これが「箱根かに問題」の実態です。
もちろん「かに」だけが問題が起きるわけではなく、上で見たように2語以上の単語を検索すると問題が起こるようになっていました。

上記をまとめると、箱根かに問題は下記の2つに分解できます。

  • 使うべきではないサジェスト API を検索に使っている
    • 「箱根」がキーワードとして認識されている
    • キーワード検索に関する実装がフロントエンドにも漏れ出している
  • キーワード API の精度が高くない
    • 「穏やかに」などのキーワードを含まずに純粋な「かに」を抽出したい

マイクロサービスの導入

前者の「使うべきではないサジェスト API を検索に使っている」という課題はマイクロサービスを立てることで解決しました。 以下が新しいシステム構成です。
フロントエンドのキーワード解釈の実装もこのマイクロサービスに寄せています。

After

このマイクロサービスは、例えば

{
  "keyword":"箱根 かに"
}

というリクエストに対して

{
  "areaIds": [
    "160418"
  ],
  "keyword": "かに"
}

というレスポンスを返します。
キーワードをクエリに変換するサービスなので「クエリサービス」と名付けました。
これは我々が求めていたシンプルな形のものです。
かにも綺麗に分かれています₍₍⁽⁽🦀₎₎⁾⁾

また、元々サジェストAPI はデータサイエンス部の管轄で、属人的になっていました。
しかし、今回クエリサービスはデータサイエンスのメンバーだけでなく、検索チームがオーナーシップを持って開発するように取り決めをしました。

適合率を上げる

一方、後者の「キーワード API の精度が高くない」という課題に関しては長期的なメンテナンスが必要です。 我々はこの課題に対して「ハード変換できるキーワードを増やす」というアプローチを取りました。 専門的に言うと長期的には「再現率」を改善し、短中期的には「適合率」を上げるようにしたのです。

今までは 箱根 などのエリアや、朝食付き といったメジャーな検索条件に関しては、すでにキーワードから ID に変換できていました。
しかし「市区町村名」や「グループホテル名」などに関しては ID 変換をしていませんでした。
これらを変換し、適合率を上げるようにした、というわけです。
ID 変換できるキーワードが増えると、キーワードAPI に流れるキーワードは減るので、結果的により検索精度が上がります。

進め方

ソフト検索されているキーワードを監視して、検索需要が高いものから優先して ID 変換するようにしました。 これらはワードクラウドで視覚的に見えるようにしており、文字の大きいものほど検索需要が大きいキーワードということになります。
執筆時の一ヶ月前(2023/07/21)の実際のデータを載せます。
この時点ではグループホテルが変換できていませんでした。

グループホテル変換前の様子

ふふドーミーイン , 星野リゾート が大きい割合を占めているのがわかると思います。
では「グループホテル名」を ID 変換できるようになった今の様子を見てみましょう。

グループホテル変換後の様子

ふふドーミーイン などのグループホテルはなくなり、オールインクルーシブ がデカデカと台頭するようになりました。
(星野リゾート系列は一休では取り扱いがなく、ID がないので , 星のや , omo などが変換できず残っていますが、)全体がまるっと変わったのが見て取れます。

このように検索需要のあるキーワードをハード変換することで精度の高い検索結果を提供する、というのがここ数ヶ月の改善です。 並行してキーワードAPI は随時改善しており、「かに」などの食材については純粋な「かに」が抽出できるようになっています。

将来の展望

システム構成を見直し、ハード変換のカバレッジを上げて今期は過ごしてきました。
しかし、まだまだキーワード改善の余地はたくさんあります。
直近では ChatGPTに自社の情報を組み込みたい① - 一休.com Developers Blog で書かれているように、ChatGPT を使って検索体験を全く異なるものにできないか検証をしています。

「ユーザーの頭の中にあることをそのまま検索できる」ような検索体験を提供できるよう、引き続き開発を行っていきます 🦀

さいごに

一休では随時エンジニアを募集しています。
上記のような検索改善に興味がある方はぜひ下記からご応募ください。

www.ikyu.co.jp

カジュアル面談も実施しているので、話だけ聞きたい!という方でもお待ちしております。 hrmos.co