🔎

HottyDBでAI検索システムを作る方法

2022/09/29に公開

HottyDB[1]は、検索エンジンとレコメンドエンジンの機能を搭載したRDBMS(リレーショナルデータベース)です。
本記事では、HottyDBを使ってAI検索システムを実装する方法を解説したいと思います!

AI検索システムとは?

AI検索システムとは、機械学習を使って検索結果のランキングを最適化する[2]ことができるシステムのことです。

AI検索システムの作り方

本記事の構成は下記のようになっております。

  1. 【準備】テーブルの作成
  2. 転置インデックスを用いた全文検索
  3. 機械学習による検索結果のランキング改善(AI検索)

0. 【準備】テーブルの作成

最初に、本記事で検索対象テーブルとして用いる「記事テーブル(article)」を下記コマンドで作成します。

CREATE TABLE article (
  id INT,
  title VARCHAR(256)
  likes_count INT
)

idtitleは説明不要だと思います。
likes_count は記事のいいね数を表します。
機械学習によるランキング改善で並び順を最適化する際にこちらは使います。

1. 転置インデックスを用いた全文検索

通常のSQLでもLIKE句を使えば全文検索を行うことは可能ですが、テーブルのフルスキャンが必要であったりと実用的ではありません。
HottyDBでは、SQLに似たコマンドで転置インデックスを作成し、高速な全文検索を実現することができます。

転置インデックスとは?

転置インデックスとは、検索対象テキストをトークン(単語のようなもの)と呼ばれる短い文字列に分割し、そのトークンをキーとしてそれを含むテキストIDのリスト(ポスティングリストと呼ぶ)を保持する方式です。

言葉だけだとわかりづらいので、具体例を見てみましょう。

テキストID テキスト
1 I am good
2 She is good
3 He is bad

という3つの文書に転置インデックスを作成すると、

トークン ポスティングリスト
good 1, 2
is 2, 3
I 1
am 1
She 2
He 3
bad 3

のようになります。
例えば、good は テキストID 1にも2にも含まれるので、goodのポスティングリストは1, 2となります。

ここで、is goodを検索キーワードとしてテキスト検索する場合、
isのポスティングリストと、goodのポスティングリストの両方に含まれるテキストID(つまり2)が検索結果として出力されます。

このように、転置インデックスを利用することで、テキスト検索時にテーブルのフルスキャンをすることなく高速に検索結果を返すことができるようになります。

また、ポスティングリストに

トークン ポスティングリスト
good 1:3, 2:4

のように、テキスト内にそのトークンが出現した頻度(1:3はテキストID1 にはgoodが3回出現したの意味)も格納することで、類似度計算をすることも可能となります。

HottyDBで転置インデックスを作るには?

記事テーブルarticletitleフィールドにs1という名前の転置インデックスを作成する場合、HottyDBでは下記のようなSQLコマンドを実行します。

CREATE SEARCH INDEX s1 ON article (title)

HottyDBで転置インデックスを利用した全文検索を実行する

転置インデックスを作成したら、SELECT文で転置インデックスを利用したテキスト検索を実行することが可能です。
例えば、title機械学習という文字列を含む記事をテキスト検索する場合、下記のようなSELECT文になります。

SELECT id, title, _similarity
FROM SEARCH(article, title, '機械学習') 
ORDER BY _similarity DESC

FROM句の後にあるSEARCHメソッドに注目してください。
SEARCH(テーブル名, フィールド名, 検索キーワード) とすることで、転置インデックスを利用した検索結果を返すことができます。
このSEARCHメソッドの出力は、通常のテーブルと同じように扱うことができるのです!(他テーブルとJOINすることも可能だし、GROUP BYなどで集約することも可能!)

またここで、_similarityという見慣れないフィールドが突然出てきました。
これは、SEARCHメソッドが自動的に追加するフィールドです。
_similarityは検索キーワードと該当レコードとの類似度を表すスコアになっています。

ORDER BY _similarity DESC とすることで、類似度の高い順に検索結果を並べることが可能です。

単純な全文検索の問題点

転置インデックスを利用したテキスト検索では、フルスキャンを回避することができ、類似度計算もできるようになりました。
しかし、単純に類似度順に検索結果を並べることは必ずしも最適なランキングとは言えません。例えば、articleテーブルの例では類似度だけでなく、いいね数likes_countも考慮に入れたランキングにしたくなりますが、単純な方法ではそれができません。

高度な検索システムでは、検索結果のランキングを類似度以外の指標も組み合わせて機械学習によりランキングを最適化しています。

次の節では、機械学習を用いて検索結果のランキングを最適化する方法を解説します。

2. 機械学習による検索結果のランキング改善(AI検索)

検索結果のランキングを機械学習により最適化することを 機械学習ランキングMLR) やランキング学習と呼びます。
HottyDB でこの機械学習ランキング(MLR)をする場合、以下の4つの手順を実行する必要があります。少し手順が多いですが、通常の機械学習システムの学習パイプラインを構築する手間と比べればとても簡単です。

  1. (準備1)MLRテンプレートの作成
  2. (準備2)MLRモデルの作成
  3. (推論)機械学習ランキングの推論(並び替え)
  4. (学習)機械学習ランキングの学習

もちろん準備の手順は初回に一度実行すればよく、通常時は推論と学習を繰り返し実行するだけです。
先に推論を行うのは、推論結果を学習に使う必要があるからです。

ここでの例では、「検索時の類似度」と「記事のいいね数」を特徴量とし、クリックされたレコードを正解とする機械学習ランキングを行う手順を紹介していきます。

2-1. (準備1)MLRテンプレートの作成

最初の準備はMLRテンプレートと呼ばれるSELECT文のテンプレートを作成することです。
MLRテンプレートとは、機械学習ランキングを行う対象のテーブルデータを生成するテンプレートのことです。

言葉だけだとわかりづらいと思うので、実際にMLRテンプレートを作成するコマンドを見てみましょう。

CREATE MLR_TEMPLATE t1 
KEY(id)
SELECT id, title, likes_count, _similarity
FROM SEARCH(article, title, ?)

1行目では、t1という名前のMLRテンプレートの作成を宣言しています。

2行目は、3行目以降のSELECT文の出力フィールドのうち、レコードのIDとなるものをKEYとして指定しています。
これは機械学習ランキングの学習フェーズで正解データ(Clickを正解とする)を指定するときに重要となります。

3行目以降は機械学習ランキングで並び替えをしたいSELECT文を指定します。
このSELECT文では、以下のフィールドを含める必要があります。

  • 機械学習ランキングの特徴量となるフィールド(例の場合likes_count_similarity
  • 検索結果のレスポンスで使うフィールド(例の場合id, title, likes_count
  • レコードのIDとなり、2行目のKEYで指定しているフィールド(例の場合id

また、4行目のSEARCHメソッド内の ?に注目してみましょう。
?はプレースホルダーを意味し、テンプレート作成時点では値を決められない定数(この場合検索キーワード)を仮置きすることができます。
MLRテンプレートという名前の謂れはここから来ています。
プレースホルダーは何個でも設定することができ、検索キーワード以外にもWHERE句の条件を仮置きすることなども可能です。
このプレースホルダーは、のちの機械学習ランキングの推論時に挿入することになります。

2-2. (準備2)MLRモデルの作成

続いて、先ほど作成したMLRテンプレートt1を指定し、MLRモデルm1を作成します。
MLRモデルでは、MLRテンプレートの出力フィールドのうち、特徴量として使うフィールド名を指定します(この場合、likes_count_similarity)。

CREATE MLR_MODEL m1 WITH t1 (likes_count, _similarity)

準備は以上で完了です。それでは実際に機械学習ランキングの推論と学習を行うフェーズを見てみましょう。

2-3. (推論)機械学習ランキングの推論(並び替え)

機械学習ランキングの学習は、推論結果を利用して実行するので先に推論フェーズの手順を解説します。
機械学習ランキングにおける推論とは、機械学習により最適化されたランキングでレコードを並び替えることを意味します。

推論は、下記のようなSELECT文を実行することで行われます(検索キーワードを機械学習としたテキスト検索)。

SELECT id, title, likes_count, _similarity, 
  _request_id, _key_id, _score
FROM MLR(m1, '機械学習')(30, 0)

3行目のFROM句から見ていきましょう。見慣れないMLRというメソッドが登場しています。
このMLRメソッドを実行することで、機械学習ランキングの推論が実行されます。
1つ目の引数m1では、準備2で作成したMLRモデル名を指定しています。
2つ目の引数は、準備1で作成したMLRテンプレートのプレースホルダーに定数をセットするものです。準備1では、検索キーワードの部分をプレースホルダーにしていたので、そこに機械学習という値をセットしていることになります。
プレースホルダーを複数記述していた場合には、MLR(m1, '機械学習', 'xxx', 'yyy', ...)のように、複数セットすることができます。
MLRメソッドの次のカッコに(30, 0) というものがありますが、これは(LIMIT, OFFSET)を意味しています。
LIMITは検索結果を何件取得するか、OFFSETは何件目から取得開始するか?という意味です。

つまり、MLRメソッドの出力は、MLRテンプレートのプレースホルダーに値をセットした状態でSELECT文を実行し、それを準備2で作成したMLRモデルで並び替えたもの、ということになります。

続いて1,2行目の出力フィールドについて見ていきましょう。
1行目はarticleテーブルが持つフィールドとSEARCHメソッドの類似度なので既に説明済みです。
問題は2行目です。3つの新しいフィールドが出てきていますので、1つずつ説明していきます。

  • _request_id: 検索リクエストを一意に特定するIDで、学習データを送信する際に利用します。
  • _key_id: 検索結果内でアイテムを一意に特定するIDで、学習データを送信する際に利用します。MLRテンプレートでKEYに指定したフィールドの値と同じ値が返ります。
  • _score: アイテムの機械学習ランキングにおけるスコアを返します。

以上で機械学習ランキングの推論周りの説明は終わりです。
では最後に、その検索結果を表示し、クリックされたレコードを学習させるフェーズについて説明していきます。

2-4. (学習)機械学習ランキングの学習

機械学習ランキングの学習では、検索結果一覧の中でクリックされたアイテムとそうでないアイテムの違いを学習させる必要があります。
検索結果一覧自体は_request_idをキーとしてHottyDBの中に記憶させていますが、どの検索結果アイテムがクリックされたかは別途HottyDB側に伝えて上げる必要があります。

そのためのコマンドがINSERT MLR_POSITIVE命令です。

_request_id=1の検索リクエストにおいて、article.id=4 がクリックされた場合のコマンドは次のようになります。

INSERT MLR_POSITIVE(m1, 1, 4)

1つ目の引数は準備2で作成したMLRモデルのモデル名です。
2つ目の引数は、推論時に取得した _request_idの値を指定します。どの検索リクエストにおいての学習なのかを指定するためです。
3つ目の引数は、クリックされた検索結果の _key_idの値を指定します。どの検索結果アイテムがクリックされたのかをHottyDBに伝えます。

以上で、HottyDBにおいて機械学習ランキングを実行する手順の解説は終わりです。
機械学習ランキングの手順は少々複雑で、わかりづらいところもあったかと思いますが、それでも通常の機械学習システムを構築するのと比べれば格段に簡単になっていると思います。

導入事例

最後にこのHottyDBの機械学習ランキング機能を使った導入事例を紹介して、この記事は終わりにしようと思います。

HottyTech検索

https://tech.hottydb.com/

HottyTech検索とは?

HottyTech検索」は、Tech記事の検索とレコメンデーションのサービスです。
Tech記事のキーワード検索、関連記事レコメンデーションなどの機能をHottyDBにより実現しています。

Tech記事といっても現状はQiitaのAPIで取得できた記事に限られますが、その記事の中から興味のある記事を検索することができるサービスです。

主な機能

「HottyTech検索」の主な機能は次の4つです。

  1. キーワード検索機能(全文検索+機械学習ランキング=AI検索)
  2. 関連記事レコメンデーション機能(協調フィルタリング)
  3. 関連記事レコメンデーション機能(類似記事検索)
  4. 「あなたにおすすめの記事」機能

キーワード検索機能を使うと今回紹介したAI検索の機能を体感することができます。
HottyTech検索では、機械学習ランキングの特徴量として、記事の「いいね数」「文字数」「投稿者の記事数」「投稿者のフォロワー数」「キーワードとの類似度」を利用しています。

HottyTech検索の作り方

下記の記事でHottyDBを使ってHottyTech検索を作る方法を詳しく解説していますので、よろしければこちらも見てみてください。

https://qiita.com/toru1055/items/e7239c00f7c9ee96ed3f

さいごに

以上で本記事は終わりです。
是非皆様もHottyDBを活用していただき、忌憚ないフィードバックをいただけると幸いです。
(フィードバックはこちらまで)

脚注
  1. HottyDBに関しては前回の記事で説明していますので、こちらを参照してください。 ↩︎

  2. ランキング学習や機械学習ランキング(MLR)とも呼ばれています。 ↩︎

Discussion