ランキング学習を体験する最近俄に(?)脚光を浴びてきた「ランキング学習(Learning-to-Rank、以下LTRと略すこともある)」をSolrで試す方法を紹介しよう。思い浮かべる方もいるかもしれない。勉強会」でシーマークの山本社長が発表したNLP4Lを使った方法を採り上げたい。以下の理由からSOLR-8542よりはるかに使い方が簡単だからだ。詳しいマニュアル(日本語と英語)が付属また、NLP4Lはランキング学習の論文で紹介される一般的な特徴であるTF、IDF、TF*IDFなどが扱えるのに対し、SOLR-8542はこれらの特徴は扱えない(扱う予定もなさそう)。SOLR-8542はモデルを利用する部分でSolrに依存するところが大きいが、NLP4Lでは大事な部分はLuceneレベルで行われ、LTRの主要な部分の実装がコンパクトである。したがってElasticsearch対応も比較的簡単である。SOLR-8542の方が優れている部分もあり、使用する特徴をSolrのクエリ式で書けるところはNLP4Lよりも柔軟で優位性があるといえる。LTRの学習データについてLTRは教師あり学習を基本とする。degreeと呼んでいる)がつけられている一連のレコードである。この形式のデータを学習するアルゴリズムはPointwiseアプローチと呼ばれる。他にも「あるクエリについて文書ペアがどちらがより関連度が高いか」というラベルがついたデータを扱うPairwise、「あるクエリについて文書集合が関連度順にどのようにリストされるか」というラベルがついたデータを扱うListwiseがある。クリックログ、NLP4Lでは特別に「インプレッションログ」と呼んで通常のアクセスログと区別している)からクリックモデルを計算して関連度を自動算出する」方法が用意されている。本記事では説明の簡略化のため前者の「アノテーションGUI」を使った方法を採り上げる。本番システムで人手でアノテーションを行うのはなにかと大変だ。本記事を読んでランキング学習の手順を理解したら、ぜひ後者の「アクセスログからクリックモデルを計算して関連度を自動算出する」方法に挑戦していただきたい。以下、NLP4Lでのランキング学習の手順の概要である。この順番で以降説明を進める。前述の通り、NLP4Lには詳細なLTRのためのマニュアルが付属するのでここであらためて記事にする必要もないかもしれないが、本記事では対象文書セットとしてlivedoorニュースコーパスを用いることで、一連の操作方法をより具体的に説明している。興味のある方は、下記手順通りにインストールと設定を進めれば、Solrでランキング学習の実際を体験することができる。詳細を知りたい場合にはNLP4Lのマニュアルをご覧いただきたい。6.3.0(本記事執筆時の最新)をダウンロード、展開する。本記事では/opt/nlp4l/solr-6.3.0ディレクトリにSolrを展開するとして話を進める。solr-6.3.0.tgzSolrを起動し、collection1という名前のコアを作成する。適当なディレクトリにてgithubで公開されているNLP4L/solrプロジェクトをダウンロード、ビルド、Solrにデプロイする。/opt/nlp4l/solr-6.3.0/server/solr-webapp/webapp/WEB-INF/libNLP4L/solrはtypesafe社のconfigライブラリが必要なので、以下のように入手、ビルド、Solrにデプロイする。/opt/nlp4l/solr-6.3.0/server/solr-webapp/webapp/WEB-INF/libSolrに付属のJettyのwebapp設定を次のように行う。選択可能な特徴を以下のようにJSON設定ファイルに用意する。]}また、solrconfig.xmlを以下のように編集する。リクエストハンドラのdefaultsパラメータに以下を追加する。bodyNLP4L-LTRからの特徴抽出リクエストに応答するためのリクエストハンドラを以下のように設定する。最後に、PRankクエリを呼び出すPRankQParserPluginを次のように設定する(PRank以外にRankingSVMが選択可能)。Component関連の設定もここで削除しておこう。ニュースコーパスをSolrに登録するために、まずスキーマを設定する(APIを通じてスキーマ変更するのが推奨だが、面倒なのでエディタで編集してしまう)。urlされに不要なcopyField設定は取り除いておく。ここでSolr設定の変更を有効化するためにコアのリロードまたは再起動を行う。ニュースコーパスを入手し、Solrに登録する。以下のように入手し起動する。NLP4L-LTRというメニューを選び、画面上部に表示されるメニューのConfigをクリックする。<<New>>リンクをクリックすると、新しいConfig設定をするように促される。次の表を参考に設定する。アノテーションの種別。現在はpointwiseしか選べない。これは現在のNLP4Lが学習アルゴリズムがPointwiseのものしか扱えない、という意味ではない。実際、NLP4LがサポートしているRankingSVMはPairwiseであるが、Pointwise形式のデータを内部でPairwiseに変換している。pointwiseにて人手でつける星の数をいくつからいくつまでとするか。学習アルゴリズムのファクトリクラス名を指定する。PRankTrainerFactoryまたはRankingSVMTrainerFactoryが選べる。教師データ作成時、人手でアノテーションする際、連携先となるSolrのURL。特徴抽出する際の連携先となるSolrのURL。solrconfig.xmlに設定したリクエストハンドラのURLを記載する。特徴抽出時に参照する、Solr側に配置されたJSON設定ファイル名。Solrのユニークキーのフィールド名。Solr文書のタイトルフィールド名。人手によるアノテーション実施時に、タイトルとして画面表示されるフィールド名を指定する。Solr文書の本文フィールド名。人手によるアノテーション実施時に、本文として画面表示されるフィールド名を指定する。学習して得たモデルファイルをSolrにデプロイするときに使用するクラスのファクトリ。}[Save]ボタンをクリックして[Load]をクリックすると、画面上部にtestという名前のConfigがロードされたことが示され、Query、Annotation、Feature、Trainingというメニュー項目が現れる。教師データを作成する場合はQueryまたはAnnotationメニューを使う。前述の通り、本記事ではアノテーションGUIを使った教師データの作成方法を説明する。アクセスログ(インプレッションログ)からクリックモデルを計算することで教師データを安価に用意したい場合は、Queryメニューの[Import]ボタンをクリックしてログファイルをロードする。Queryメニューにはファイルを選択するボタンがあり、これをクリックするとクエリ一覧が記載されたテキストファイルを選べるようになる。このテキストファイルには1行1クエリを記載しておく。このファイルをロードすると、下図のようにクエリが表示される。このクエリのリンクをクリックすると連携先のSolrにてクエリが実行され、Annotation画面に結果が表示される。この画面ではSearchテキストボックスに選択したクエリが表示されているが、Queryメニューから始めなくても、Annotationメニューを選んでこのSearchテキストボックスに直接クエリを入れても同じである。Annotation画面にて各クエリと返された文書の関連度を考えながら、右側に表示されている星の数を適切に選んでいく。1画面分終わったら、[Save]ボタンで保存し、[Next]で次のクエリに進む。一通り終了したら次のステップである特徴抽出に進む。特徴抽出Featureメニューを選択する。すると下図のようなプログレスバーが現れる。[Extract]で特徴抽出が開始するが、すでにプログレスバーが緑色になっているときは、まず[Clear]ボタンをクリックしてから[Extract]を行う。終了するとDONEと表示される。ランキング学習Trainigメニューを選択し、左側にある<<New>>をクリックする。するとSolrに配置した設定ファイル(ltr_features.conf)にしたがって特徴を選ぶチェックボックスが現れる。このチェックボックスで適当に特徴を選んで[Start]をクリックする。ここでも学習の進行状況がプログレスバーで示され、終了すると下のようにモデルファイルの内容が表示される。ここではPRankを選択したので、各特徴に対する重みと、3つの閾値(星の数を最大3にしたことに由来)が返される。}}モデルのデプロイランキング学習が終了すると[Deploy]ボタンが表示されるので、これをクリックすることで連携先のSolrにHTTPで転送される。Solr側ではこの学習モデルを有効化するために、コアのリロードが必要である。Solrの管理画面からコアのリロードを行うのが簡単だ。...}パラメータを利用する。queryParserを呼び出すには次のように検索を実行する。学生&debugQuery=onSolr標準のリランクは、(前述のsolrconfig.xmlの設定にしたがい)最初に通常のedismaxクエリを実行し、次に上位の200クエリ(reRankDocsのデフォルト)についてランキング学習モデルに基づいた再ランキングを行う。デバッグ情報のスコア詳細欄を見ると最初の2行は次のようになっている。score最初の行は2段階クエリのスコアの和が14.37461になっていることを示し、次の行は第1段階のクエリ(ここでは通常のedismax)のスコアが10.37461であることを示している。3行目以降はedismaxのスコア詳細なのでここではスキップしよう。第2段階のクエリ、つまりPRankのクエリで計算したスコア合計は2.0であり、その詳細は下記のブロックで示されている。265)2.0というスコアは2倍(reRankWeightのデフォルト)され4.0となり、最終スコア合計が14.37461となる。2.0というスコアはどうやって計算されたかというと、モデルで与えられた重みを使って計算した結果が-2338.074707となるが、これは境界値の[-2374.0,6450.0]の範囲内にあるため2.0となる。まとめlivedoorニュースコーパスはフィールド数、文書数とも少ないので十分な教師データを作るのが難しいが、実運用されているフィールド数、文書数とも大きなデータにおいて、ランキング学習は通常のSimilarityが算出するスコアをより良く改善することが期待できる。比較のポイント商用検索エンジンを購入した企業担当者は読まないでください。McCandlessFastVectorHighlighterについて解説記事を寄稿しました。