この記事は、ただの集団 AdventCalendar 2019の21日目の記事です。
はじめに
担当日前日に「Elasticsearch で Learning-to-rank やりたいので、環境構築の手順とその使い方についてまとめてね。ヨロピコ!」と振られたので、今回は Elasticsearch with learning-to-rank の構築手順とその使い方を紹介します。
今回作成したものはコチラ
Learning-to-rank とは
検索エンジンにおける learning-to-rank とは、機械学習と検索するデータを使って、検索結果のランキングの順序を改善する手法のことです。順序学習やランキング学習とも呼ばれています。
今回は、Elasticsearch の learning-to-rank のプラグイン を使います。learning-to-rank のレポジトリに demo を使って、ランキング改善を体験してみたいと思います。
環境構築
demo を試すために、事前に以下の環境構築をします。
- Java の実行環境
- Python3 の実行環境
- Elasticsearch に learning-to-rank プラグインを導入
プラグイン入り Elasticsearch の構築は、docker image を使うと楽です。
以下、Elasticsearch with learning-to-rank docker image のサンプル
FROM elasticsearch:7.4.1
RUN bin/elasticsearch-plugin install -b http://es-learn-to-rank.labs.o19s.com/ltr-1.1.2-es7.4.1.zip
環境構築後、learning-to-rank のレポジトリをクローンして demo ディレクトリに移動しましょう。
$ git clone https://github.com/o19s/elasticsearch-learning-to-rank.git
$ cd elasticsearch-learning-to-rank/demo
demo ディレクトリへ移動後、順番にスクリプトを実行して learning-to-rank を体験する。
データとライブラリの準備
prepare.py を実行して、検索データと学習モデルを作成するライブラリ(Ranklib)をダウンロードします。
$ python prepare.py
実行すると、映画のデータ(tmdb.json)とランキング学習のライブラリ(RankLibPlus-0.1.0.jar)をダウンロードします。(tmdb.jsonはサイズが大きいのでダウンロードに時間がかかるので注意!)
ダウンロード完了後、Elasticsearch の環境を整えます。
Elasticsearch の環境を整える
learning-to-rank のプラグインを導入した Elasticsearch を立ち上げ、データを入れます。Elasticsearch 起動後、index_ml_tmdb.py を実行してインデックスの設定とデータの挿入を行います。以下のスクリプトを実行すると、tmdb.json を Elasticsearch にインサートします。
$ python index_ml_tmdb.py
インデックスの設定とデータの挿入が完了したら、次は学習に使う feature を設定します。以下のスクリプトを実行すると、学習に使う field の設定と feature raw データから feature を作成します。(設定されるフィールドは demo/1.json と demo/2.json 参照。例では、title と overview を参照している。)
$ python load_features.py
raw データを feature に変換する field の準備ができたら、モデル作成を行います。
モデルを作成する
モデルを作成するために train.py を実行する。train.py を介して Ranklib の jar を実行してモデル作成を行います。
$ python train.py
サンプルでは、sample_judgements.txt にあるキーワードが検索されたときに、検索キーワードを含む結果が上位に来るようなモデルを生成します。
モデル作成後、モデルは elasticsearch にデプロイされます。
検索する
実際に試してみます。search.py を実行すると、以下の検索結果が得られます。
$ python search.py Rambo
{"query": {"multi_match": {"query": "Rambo", "fields": ["title", "overview"]}}, "rescore": {"query": {"rescore_query": {"sltr": {"params": {"keywords": "Rambo"}, "model": "test_6"}}}}}
Rambo
Rambo III
Rambo: First Blood Part II
First Blood
In the Line of Duty: The F.B.I. Murders
Son of Rambow
Spud
$
learning-to-rank あり/なしを比較すると、以下のようになります。
## search with learning-to-rank
1 Rambo
2 Rambo III
3 Rambo: First Blood Part II
4 First Blood
5 In the Line of Duty: The F.B.I. Murders
6 Son of Rambow
7 Spud
## search without learning-to-rank
1 Rambo
2 Rambo III
3 First Blood
4 Rambo: First Blood Part II
5 In the Line of Duty: The F.B.I. Murders
6 Son of Rambow
7 Spud
学習結果が反映されている!
まとめ
今回は、Elasticsearch で Learning-to-rank を試す手順の紹介と、learning-to-rank を検索エンジンに反映までやりました。今回使ったライブラリをお手軽に試せるようにレポジトリにまとめましたので、使っていただければ幸いです。
また、この記事では実行手順のみを紹介しましたが、機会があれば learning-to-rank のロジックや今回使ったライブラリの特徴作成について紹介したいです。