Learning To Rank
Learning To Rank(略してLTR)モジュールを使用すると、Solrで機械学習ランキングモデルを構成して実行できます。
このモジュールは、Solr内部での特徴量ロギングもサポートしています。Solrの外部で行う必要があるのは、独自のランキングモデルをトレーニングすることだけです。
Learning to Rankの概念
再ランキング
再ランキングを使用すると、マッチングドキュメントの単純なクエリを実行し、別の、より複雑なクエリからのスコアを使用して上位N個のドキュメントを再ランキングできます。このページでは、LTRの複雑なクエリの使用について説明します。Solrディストリビューションに含まれる他のランククエリに関する情報は、クエリ再ランキングにあります。
Learning To Rankモデル
情報検索システムでは、Learning to Rankは、トレーニング済みの機械学習モデルを使用して、取得した上位N個のドキュメントを再ランキングするために使用されます。そのような高度なモデルは、TF-IDFやBM25などの標準的なランキング関数よりも、よりニュアンスのあるランキング決定を行うことができると期待されています。
ランキングモデル
ランキングモデルは、ドキュメントを再ランキングするために使用されるスコアを計算します。特定のアルゴリズムや実装に関係なく、ランキングモデルの計算では、次の3種類の入力を使用できます。
-
スコアリングアルゴリズムを表すパラメーター
-
スコアリングされるドキュメントを表す特徴
-
ドキュメントがスコアリングされているクエリを表す特徴
インターリーブ
インターリーブは、オンライン検索品質評価のアプローチであり、ユーザーに返される最終的なランク付けされたリストで結果をインターリーブすることにより、2つのモデルを比較できます。
-
現在、Team Draft Interleavingアルゴリズムのみがサポートされています(また、その実装はすべての結果が同じシャードからのものであると想定しています)
トレーニングモデル
特徴量エンジニアリング
LTRモジュールには、カスタムフィーチャーのサポートだけでなく、いくつかのフィーチャークラスが含まれています。各フィーチャークラスのjavadocには、そのクラスの使用方法を示す例が含まれています。次に、フィーチャーエンジニアリングのプロセス自体は、完全にあなたのドメインの専門知識と創造性次第です。
特徴 | クラス | パラメーターの例 | 外部の特徴情報 |
---|---|---|---|
フィールド長 |
|
(まだ)サポートされていません |
|
フィールド値 |
|
(まだ)サポートされていません |
|
元のスコア |
|
該当なし |
|
solrクエリ |
|
サポート |
|
solrフィルタークエリ |
|
サポート |
|
solrクエリ + フィルタークエリ |
|
サポート |
|
値 |
|
サポート |
|
(カスタム) |
(Featureを拡張するカスタムクラス) |
正規化器 | クラス | パラメーターの例 |
---|---|---|
Identity |
|
|
MinMax |
|
|
Standard |
|
|
(カスタム) |
(Normalizer を拡張するカスタムクラス) |
フィーチャーロギング
ltr モジュールには、[features]
トランスフォーマーが含まれており、特徴抽出の目的で、特に実際のランキングモデルをまだ持っていない場合に、フィーチャー値の計算と返却をサポートします。
フィーチャー選択とモデルトレーニング
フィーチャー選択とモデルトレーニングは、Solr の外部でオフラインで行われます。ltr モジュールは、カスタムモデルだけでなく、2 つの一般的な形式のモデルをサポートしています。各モデルクラスの javadoc には、そのクラスの構成を示す例が含まれています。トレーニング済みのモデル(または、異なる顧客の地域向けの異なるモデルなど)を JSON ファイル形式で、提供されている REST API を使用して Solr に直接アップロードできます。
一般的な形式 | クラス | 具体的な例 |
---|---|---|
線形 |
RankSVM、Pranking |
|
複数加法木 |
LambdaMART、勾配ブースティング回帰木 (GBRT) |
|
ニューラルネットワーク |
RankNet |
|
(ラッパー) |
(該当なし) |
|
(カスタム) |
(AdapterModel を拡張するカスタムクラス) |
(該当なし) |
(カスタム) |
(LTRScoringModel を拡張するカスタムクラス) |
(該当なし) |
モジュール
これは、使用前に有効にする必要がある ltr
Solr モジュールを介して提供されます。
LTR の構成
Learning-To-Rank はモジュールであるため、そのプラグインは solrconfig.xml
で構成する必要があります。
最小要件
-
必要なモジュール JAR を含めます。デフォルトではパスは Solr コアからの相対パスであるため、構成に合わせて調整するか、
$solr.install.dir
を明示的に指定する必要がある場合があることに注意してください。<lib dir="${solr.install.dir:../../../..}/modules/ltr/lib/" regex=".*\.jar" />
-
ltr
クエリパーサーの宣言。<queryParser name="ltr" class="org.apache.solr.ltr.search.LTRQParserPlugin"/>
-
フィーチャー値キャッシュの構成。
<cache name="QUERY_DOC_FV" class="solr.search.CaffeineCache" size="4096" initialSize="2048" autowarmCount="4096" regenerator="solr.search.NoOpRegenerator" />
-
[features]
トランスフォーマーの宣言。<transformer name="features" class="org.apache.solr.ltr.response.transform.LTRFeatureLoggerTransformerFactory"> <str name="fvCacheName">QUERY_DOC_FV</str> </transformer>
-
[interleaving]
トランスフォーマーの宣言。<transformer name="interleaving" class="org.apache.solr.ltr.response.transform.LTRInterleavingTransformerFactory"/>
LTR ライフサイクル
フィーチャーストア
すべてのフィーチャーを名前空間のようなストアに整理することをお勧めします。
-
ストア内のフィーチャーには一意の名前を付ける必要があります。
-
ストア間では、同一または類似のフィーチャーが同じ名前を共有できます。
-
ストア名が指定されていない場合は、デフォルトの
_DEFAULT_
フィーチャーストアが使用されます。
すべてのフィーチャーストアの名前を検出するには
https://127.0.0.1:8983/solr/techproducts/schema/feature-store
commonFeatureStore
フィーチャーストアの内容を検査するには
https://127.0.0.1:8983/solr/techproducts/schema/feature-store/commonFeatureStore
モデル
-
モデルは、1 つのフィーチャーストアのフィーチャーのみを使用します。
-
ストアが指定されていない場合は、デフォルトの
_DEFAULT_
フィーチャーストアが使用されます。 -
モデルは、フィーチャーストアで定義されているすべてのフィーチャーを使用する必要はありません。
-
複数のモデルが同じフィーチャーストアを使用できます。
currentFeatureStore
のフィーチャーのログを記録するには
https://127.0.0.1:8983/solr/techproducts/query?q=test&fl=id,score,[features store=currentFeatureStore]
currentFeatureStore
に基づく currentModel
で再ランキングしながら nextFeatureStore
のフィーチャーのログを記録するには
https://127.0.0.1:8983/solr/techproducts/query?q=test&rq={!ltr model=currentModel reRankDocs=100}&fl=id,score,[features store=nextFeatureStore]
すべてのモデルを表示するには
https://127.0.0.1:8983/solr/techproducts/schema/model-store
currentModel
モデルを削除するには
curl -XDELETE 'https://127.0.0.1:8983/solr/techproducts/schema/model-store/currentModel'
フィーチャーストアは、それを使用しているモデルがない場合にのみ削除できます。 |
currentFeatureStore
フィーチャーストアを削除するには
curl -XDELETE 'https://127.0.0.1:8983/solr/techproducts/schema/feature-store/currentFeatureStore'
大きなモデルの使用
SolrCloud では、ZooKeeper のバッファの制限により、大きなモデルのアップロードが失敗する場合があります。この場合、DefaultWrapperModel
は、モデル定義をアップロードされたファイルから分離するのに役立ちます。
DefaultWrapperModel
を介して /path/to/models/myModel.json
に配置された大きなモデルを使用することを検討していると仮定します。
{
"store" : "largeModelsFeatureStore",
"name" : "myModel",
"class" : "...",
"features" : [
"..."
],
"params" : {
"...": "..."
}
}
まず、<lib/>
ディレクティブを使用して、ディレクトリを Solr のリソースパスに追加します
<lib dir="/path/to" regex="models" />
次に、DefaultWrapperModel
を構成して myModel.json
をラップします
{
"store" : "largeModelsFeatureStore",
"name" : "myWrapperModel",
"class" : "org.apache.solr.ltr.model.DefaultWrapperModel",
"params" : {
"resource" : "myModel.json"
}
}
myModel.json
は初期化中にロードされ、model=myWrapperModel
を指定して使用できるようになります。
ラップされたモデル (myModel ) のフィーチャーが使用されるため、myWrapperModel では "features" は構成されていません。また、ラッパーモデルに構成された "store" は、ラップされたモデルのストアと一致する必要があることにも注意してください。つまり、この例では largeModelsFeatureStore という名前のフィーチャーストアが使用されています。 |
<lib dir="/path/to/models" regex=".*\.json" /> は、この場合は期待どおりに機能しません。<lib /> がファイルを示している場合、SolrResourceLoader は指定されたリソースを JAR と見なすためです。 |
上記の DefaultWrapperModel
の代わりに、ZooKeeper のファイルサイズ制限を増やすことも可能です。
変更の適用
フィーチャーストアとモデルストアはどちらもマネージドリソースです。マネージドリソースに加えられた変更は、Solr コレクション(またはシングルサーバーモードの場合は Solr コア)がリロードされるまで、アクティブな Solr コンポーネントには適用されません。
LTR のクイックスタート
Solr に付属している "techproducts"
の例は、ltr
Solr モジュールから learning-to-rank に必要なプラグインをロードするように事前構成されていますが、デフォルトでは無効になっています。
プラグインを有効にするには、techproducts
の例を実行するときに solr.ltr.enabled
JVM システムプロパティを指定してください。
bin/solr start -e techproducts -Dsolr.ltr.enabled=true
フィーチャーのアップロード
/path/myFeatures.json
ファイル内のフィーチャーをアップロードするには、次を実行してください
curl -XPUT 'https://127.0.0.1:8983/solr/techproducts/schema/feature-store' --data-binary "@/path/myFeatures.json" -H 'Content-type:application/json'
アップロードしたフィーチャーを表示するには、ブラウザで次の URL を開いてください
https://127.0.0.1:8983/solr/techproducts/schema/feature-store/_DEFAULT_
[
{
"name" : "documentRecency",
"class" : "org.apache.solr.ltr.feature.SolrFeature",
"params" : {
"q" : "{!func}recip( ms(NOW,last_modified), 3.16e-11, 1, 1)"
}
},
{
"name" : "isBook",
"class" : "org.apache.solr.ltr.feature.SolrFeature",
"params" : {
"fq": ["{!terms f=cat}book"]
}
},
{
"name" : "originalScore",
"class" : "org.apache.solr.ltr.feature.OriginalScoreFeature",
"params" : {}
}
]
フィーチャーのロギング
クエリの一部としてフィーチャーをログに記録するには、fl
パラメータに [features]
を追加します。例:
https://127.0.0.1:8983/solr/techproducts/query?q=test&fl=id,score,[features]
出力には、以下に示す出力に似た、カンマ区切りのリストとしてフィーチャー値が含まれます
{
"responseHeader":{
"status":0,
"QTime":0,
"params":{
"q":"test",
"fl":"id,score,[features]"}},
"response":{"numFound":2,"start":0,"maxScore":1.959392,"docs":[
{
"id":"GB18030TEST",
"score":1.959392,
"[features]":"documentRecency=0.020893794,isBook=0.0,originalScore=1.959392"},
{
"id":"UTF8TEST",
"score":1.5513437,
"[features]":"documentRecency=0.020893794,isBook=0.0,originalScore=1.5513437"}]
}}
フィーチャーロギングパラメータ
フィーチャーロガーのトランスフォーマーは、以下で説明するパラメータを受け入れます。それらの使用方法の例は、以下のLTR の例セクションにあります。
store
-
再ランキングなし
オプション
デフォルト:
_DEFAULT_
再ランキング
オプション
デフォルト: モデルのフィーチャーストア
このパラメータは、フィーチャーのログ記録に使用するフィーチャーストアを指定します。
再ランキングクエリでは、使用されるデフォルトのフィーチャーストアはモデルのフィーチャーストアです(例:
[features]
)。 logAll
-
再ランキングなし
デフォルト:
true
再ランキング
ロガーとモデルが同じフィーチャーストアを持っている
デフォルト:
false
再ランキング
ロガーとモデルが異なるフィーチャーストアを持っている
デフォルト:
true
このパラメータは、ログに記録するフィーチャーを指定します。
true
に設定すると、フィーチャーストアのすべてのフィーチャーが出力されます。
false
に設定すると、モデルで使用されているフィーチャーのみが出力されます。
再ランキングクエリが渡されていない場合、logAll = 'true' のみがサポートされます。false を渡すと、Solr 例外が発生します。 |
再ランキングクエリが渡されるロギングシナリオでは、ロガーの store がモデルの store と異なる場合、logAll = 'true' のみがサポートされます。false を渡すと、Solr 例外が発生します。 |
format
-
オプション
デフォルト:
dense
このパラメータは、フィーチャーのログ記録に使用するフォーマットを指定します。サポートされる値は、
dense
とsparse
です。デフォルトの動作をスパースに変更するには、
solrconfig.xml
のフィーチャーロガートランスフォーマー宣言に<str name="defaultFormat">sparse</str>
を記述します
<transformer name="features" class="org.apache.solr.ltr.response.transform.LTRFeatureLoggerTransformerFactory">
<str name="fvCacheName">QUERY_DOC_FV</str>
<str name="defaultFormat">sparse</str>
<str name="csvKeyValueDelimiter">:</str>
<str name="csvFeatureSeparator"> </str>
</transformer>
モデルのアップロード
/path/myModel.json
ファイル内のモデルをアップロードするには、次を実行してください
curl -XPUT 'https://127.0.0.1:8983/solr/techproducts/schema/model-store' --data-binary "@/path/myModel.json" -H 'Content-type:application/json'
アップロードしたモデルを表示するには、ブラウザで次の URL を開いてください
https://127.0.0.1:8983/solr/techproducts/schema/model-store
{
"class" : "org.apache.solr.ltr.model.LinearModel",
"name" : "myModel",
"features" : [
{ "name" : "documentRecency" },
{ "name" : "isBook" },
{ "name" : "originalScore" }
],
"params" : {
"weights" : {
"documentRecency" : 1.0,
"isBook" : 0.1,
"originalScore" : 0.5
}
}
}
再ランキングクエリの実行
クエリの結果を再ランキングするには、検索に rq
パラメータを追加します。例:
https://127.0.0.1:8983/solr/techproducts/query?q=test&rq={!ltr model=myModel reRankDocs=100}&fl=id,score
rq
パラメータを追加しても、検索の出力は変更されません。
再ランキング中に計算されたフィーチャー値を取得するには、fl
パラメータに [features]
を追加します。例:
https://127.0.0.1:8983/solr/techproducts/query?q=test&rq={!ltr model=myModel reRankDocs=100}&fl=id,score,[features]
出力には、以下に示す出力に似た、カンマ区切りのリストとしてフィーチャー値が含まれます
{
"responseHeader":{
"status":0,
"QTime":0,
"params":{
"q":"test",
"fl":"id,score,[features]",
"rq":"{!ltr model=myModel reRankDocs=100}"}},
"response":{"numFound":2,"start":0,"maxScore":1.0005897,"docs":[
{
"id":"GB18030TEST",
"score":1.0005897,
"[features]":"documentRecency=0.020893792,isBook=0.0,originalScore=1.959392"},
{
"id":"UTF8TEST",
"score":0.79656565,
"[features]":"documentRecency=0.020893792,isBook=0.0,originalScore=1.5513437"}]
}}
2 つのモデルをインターリーブする再ランキングクエリの実行
クエリの結果を再ランキングするには、2 つのモデル (myModelA、myModelB) をインターリーブします。検索に rq
パラメータを追加し、入力に 2 つのモデルを渡します。例:
https://127.0.0.1:8983/solr/techproducts/query?q=test&rq={!ltr model=myModelA model=myModelB reRankDocs=100}&fl=id,score
再ランキング中に計算された検索結果に対してインターリーブが選択したモデルを取得するには、fl
パラメータに [interleaving]
を追加します。例:
https://127.0.0.1:8983/solr/techproducts/query?q=test&rq={!ltr model=myModelA model=myModelB reRankDocs=100}&fl=id,score,[interleaving]
出力には、以下に示す出力に似た、各検索結果に対して選択されたモデルが含まれます
{
"responseHeader":{
"status":0,
"QTime":0,
"params":{
"q":"test",
"fl":"id,score,[interleaving]",
"rq":"{!ltr model=myModelA model=myModelB reRankDocs=100}"}},
"response":{"numFound":2,"start":0,"maxScore":1.0005897,"docs":[
{
"id":"GB18030TEST",
"score":1.0005897,
"[interleaving]":"myModelB"},
{
"id":"UTF8TEST",
"score":0.79656565,
"[interleaving]":"myModelA"}]
}}
モデルと元のランキングをインターリーブする再ランキングクエリの実行
インターリーブを使用して検索品質評価を行う場合、モデルを元のランキングと比較すると役立つ場合があります。クエリの結果を再ランキングするには、モデルを元のランキングとインターリーブします。検索に rq
パラメータを追加し、特別な組み込みの OriginalRanking
モデル識別子を 1 つのモデルとして、比較モデルをもう 1 つのモデルとして渡します。例:
https://127.0.0.1:8983/solr/techproducts/query?q=test&rq={!ltr model=_OriginalRanking_ model=myModel reRankDocs=100}&fl=id,score
rq
パラメータを追加しても、検索の出力は変更されません。
再ランキング中に計算された検索結果に対してインターリーブが選択したモデルを取得するには、fl
パラメータに [interleaving]
を追加します。例:
https://127.0.0.1:8983/solr/techproducts/query?q=test&rq={!ltr model=_OriginalRanking_ model=myModel reRankDocs=100}&fl=id,score,[interleaving]
出力には、以下に示す出力に似た、各検索結果に対して選択されたモデルが含まれます
{
"responseHeader":{
"status":0,
"QTime":0,
"params":{
"q":"test",
"fl":"id,score,[features]",
"rq":"{!ltr model=_OriginalRanking_ model=myModel reRankDocs=100}"}},
"response":{"numFound":2,"start":0,"maxScore":1.0005897,"docs":[
{
"id":"GB18030TEST",
"score":1.0005897,
"[interleaving]":"_OriginalRanking_"},
{
"id":"UTF8TEST",
"score":0.79656565,
"[interleaving]":"myModel"}]
}}
特定のアルゴリズムを渡してインターリーブを使用する再ランキングクエリの実行
特定のアルゴリズムを使用して 2 つのモデルをインターリーブすることにより、クエリの結果を再ランキングするには、ltr クエリパーサーに interleavingAlgorithm
ローカルパラメータを追加します。例:
https://127.0.0.1:8983/solr/techproducts/query?q=test&rq={!ltr model=myModelA model=myModelB reRankDocs=100 interleavingAlgorithm=TeamDraft}&fl=id,score
現在、サポートされている(デフォルトの)アルゴリズムは 'TeamDraft' のみです。
外部フィーチャー情報
ValueFeature クラスと SolrFeature クラスは、外部フィーチャー情報、略して efi
の使用をサポートしています。
フィーチャーのアップロード
/path/myEfiFeatures.json
ファイル内のフィーチャーをアップロードするには、次を実行してください
curl -XPUT 'https://127.0.0.1:8983/solr/techproducts/schema/feature-store' --data-binary "@/path/myEfiFeatures.json" -H 'Content-type:application/json'
アップロードしたフィーチャーを表示するには、ブラウザで次の URL を開いてください
https://127.0.0.1:8983/solr/techproducts/schema/feature-store/myEfiFeatureStore
[
{
"store" : "myEfiFeatureStore",
"name" : "isPreferredManufacturer",
"class" : "org.apache.solr.ltr.feature.SolrFeature",
"params" : { "fq" : [ "{!field f=manu}${preferredManufacturer}" ] }
},
{
"store" : "myEfiFeatureStore",
"name" : "userAnswerValue",
"class" : "org.apache.solr.ltr.feature.ValueFeature",
"params" : { "value" : "${answer:42}" }
},
{
"store" : "myEfiFeatureStore",
"name" : "userFromMobileValue",
"class" : "org.apache.solr.ltr.feature.ValueFeature",
"params" : { "value" : "${fromMobile}", "required" : true }
},
{
"store" : "myEfiFeatureStore",
"name" : "userTextCat",
"class" : "org.apache.solr.ltr.feature.SolrFeature",
"params" : { "q" : "{!field f=cat}${text}" }
}
]
ロギング機能
クエリの一部としてmyEfiFeatureStore
のフィーチャーをログに記録するには、fl
パラメータの[features]
部分にefi.*
パラメータを追加します。例:
https://127.0.0.1:8983/solr/techproducts/query?q=test&fl=id,cat,manu,score,[features store=myEfiFeatureStore efi.text=test efi.preferredManufacturer=Apache efi.fromMobile=1]
https://127.0.0.1:8983/solr/techproducts/query?q=test&fl=id,cat,manu,score,[features store=myEfiFeatureStore efi.text=test efi.preferredManufacturer=Apache efi.fromMobile=0 efi.answer=13]
モデルのアップロード
/path/myEfiModel.json
ファイルにあるモデルをアップロードするには、以下を実行してください。
curl -XPUT 'https://127.0.0.1:8983/solr/techproducts/schema/model-store' --data-binary "@/path/myEfiModel.json" -H 'Content-type:application/json'
アップロードしたモデルを表示するには、ブラウザで次の URL を開いてください
https://127.0.0.1:8983/solr/techproducts/schema/model-store
{
"store" : "myEfiFeatureStore",
"name" : "myEfiModel",
"class" : "org.apache.solr.ltr.model.LinearModel",
"features" : [
{ "name" : "isPreferredManufacturer" },
{ "name" : "userAnswerValue" },
{ "name" : "userFromMobileValue" },
{ "name" : "userTextCat" }
],
"params" : {
"weights" : {
"isPreferredManufacturer" : 0.2,
"userAnswerValue" : 1.0,
"userFromMobileValue" : 1.0,
"userTextCat" : 0.1
}
}
}
リランククエリの実行
リランキング中に計算されたフィーチャー値を取得するには、fl
パラメータに[features]
を追加し、rq
パラメータにefi.*
パラメータを追加します。例:
https://127.0.0.1:8983/solr/techproducts/query?q=test&rq={!ltr model=myEfiModel efi.text=test efi.preferredManufacturer=Apache efi.fromMobile=1}&fl=id,cat,manu,score,[features]
https://127.0.0.1:8983/solr/techproducts/query?q=test&rq={!ltr model=myEfiModel efi.text=test efi.preferredManufacturer=Apache efi.fromMobile=0 efi.answer=13}&fl=id,cat,manu,score,[features]
fl
パラメータの[features]
部分にefi.*
パラメータがないことに注意してください。
リランキング中のフィーチャーのロギング
myModel
でリランキングしながら、myEfiFeatureStore
のフィーチャーのログを記録するには
https://127.0.0.1:8983/solr/techproducts/query?q=test&rq={!ltr model=myModel}&fl=id,cat,manu,score,[features store=myEfiFeatureStore efi.text=test efi.preferredManufacturer=Apache efi.fromMobile=1]
rq
パラメータにefi.*
パラメータがない(myModel
がefi
フィーチャーを使用していないため)ことと、fl
パラメータの[features]
部分にefi.*
パラメータがある(myEfiFeatureStore
にefi
フィーチャーが含まれているため)ことに注意してください。
トレーニング例
トレーニングデータの例とデモのtrain_and_upload_demo_model.py
スクリプトは、Apache Solr Gitリポジトリ(github.comでミラーリングされています)のsolr/modules/ltr/example
フォルダにあります。この例のフォルダは、Solrのバイナリリリースには同梱されていません。
高度なオプション
LTRThreadModule
フィーチャーの重みの生成を並列化するために、クエリパーサーやトランスフォーマーにスレッドモジュールを設定できます。詳細については、LTRThreadModuleのjavadocを参照してください。
フィーチャーのnull値を処理するモデル
この機能は、MultipleAdditiveTreesModelでのみ使用できます。
一部のシナリオでは、フィーチャーのnull値はゼロ値とは異なる意味を持ちます。2つを区別するようにトレーニングされたモデルがあります(例:https://xgboost.readthedocs.io/en/stable/faq.html#how-to-deal-with-missing-values)。Solrでは、この機能をサポートするために追加のmissing
ブランチパラメータが導入されました。
これは、対応するフィーチャー値がnullの場合に従うブランチを定義します。デフォルト設定では、null値とゼロ値は同じ意味を持ちます。
null値を処理するには、myFeatures.json
ファイルを変更する必要があります。null値になる可能性のある各フィーチャーに、NaN
値を持つdefaultValue
パラメータを追加する必要があります。
[
{
"name": "matchedTitle",
"class": "org.apache.solr.ltr.feature.SolrFeature",
"params": {
"q": "{!terms f=title}${user_query}"
}
},
{
"name": "productReviewScore",
"class": "org.apache.solr.ltr.feature.FieldValueFeature",
"params": {
"field": "product_review_score",
"defaultValue": "NaN"
}
}
]
また、モデル構成には2つの追加パラメータが必要です。
-
isNullSameAsZero
はモデルのparams
で定義し、false
に設定する必要があります。 -
missing
パラメータは、対応するフィーチャーがnull値をサポートする各ブランチに追加する必要があります。これはleft
とright
のいずれかの値を取ることができます。
{
"class":"org.apache.solr.ltr.model.MultipleAdditiveTreesModel",
"name":"multipleadditivetreesmodel",
"features":[
{ "name": "matchedTitle"},
{ "name": "productReviewScore"}
],
"params":{
"isNullSameAsZero": "false",
"trees": [
{
"weight" : "1f",
"root": {
"feature": "matchedTitle",
"threshold": "0.5f",
"left" : {
"value" : "-100"
},
"right": {
"feature" : "productReviewScore",
"threshold": "0f",
"missing": "left",
"left" : {
"value" : "50"
},
"right" : {
"value" : "65"
}
}
}
}
]
}
}
モデルのisNullSameAsZero
がfalse
の場合、フィーチャーベクターが変化します。
-
dense形式:すべてのフィーチャー値が表示されます。ゼロまたはnull値の場合もあるデフォルト値も表示されます。
-
sparse形式:デフォルト値ではない値のみが表示されます。
例:
前に定義したフィーチャーがmatchedTitle=0
とproductReviewScore=0
である場合、sparse形式はproductReviewScore:0
を返します(0はmatchedTitle=0
のデフォルト値であるため返されず、0はproductReviewScore=0
のデフォルト値ではないため返されます)。
実装と貢献
- SolrのLearning-To-Rankはどのように機能しますか?
-
実装の概要については、
ltr
javadocを参照してください。 - 追加のモデルやフィーチャーを記述するにはどうすればよいですか?
-
さらなるモデル、フィーチャー、ノーマライザー、インタリービングアルゴリズムの貢献を歓迎します。関連リンク
LTRの例
1つのフィーチャーストア、複数のランキングモデル
-
leftModel
とrightModel
は両方ともcommonFeatureStore
のフィーチャーを使用しており、2つのモデルの違いは各フィーチャーに付加される重みだけです。 -
使用される規則
-
commonFeatureStore.json
ファイルには、commonFeatureStore
フィーチャーストアのフィーチャーが含まれています。 -
leftModel.json
ファイルには、leftModel
という名前のモデルが含まれています。 -
rightModel.json
ファイルには、rightModel
という名前のモデルが含まれています。 -
モデルのフィーチャーと重みは名前でアルファベット順にソートされているため、2つのモデルの共通点と相違点を簡単に確認できます。
-
ストアのフィーチャーは名前でアルファベット順にソートされているため、モデルで使用されるフィーチャーを簡単に検索できます。
-
[
{
"store" : "commonFeatureStore",
"name" : "documentRecency",
"class" : "org.apache.solr.ltr.feature.SolrFeature",
"params" : {
"q" : "{!func}recip( ms(NOW,last_modified), 3.16e-11, 1, 1)"
}
},
{
"store" : "commonFeatureStore",
"name" : "isBook",
"class" : "org.apache.solr.ltr.feature.SolrFeature",
"params" : {
"fq": [ "{!terms f=category}book" ]
}
},
{
"store" : "commonFeatureStore",
"name" : "originalScore",
"class" : "org.apache.solr.ltr.feature.OriginalScoreFeature",
"params" : {}
}
]
{
"store" : "commonFeatureStore",
"name" : "leftModel",
"class" : "org.apache.solr.ltr.model.LinearModel",
"features" : [
{ "name" : "documentRecency" },
{ "name" : "isBook" },
{ "name" : "originalScore" }
],
"params" : {
"weights" : {
"documentRecency" : 0.1,
"isBook" : 1.0,
"originalScore" : 0.5
}
}
}
{
"store" : "commonFeatureStore",
"name" : "rightModel",
"class" : "org.apache.solr.ltr.model.LinearModel",
"features" : [
{ "name" : "documentRecency" },
{ "name" : "isBook" },
{ "name" : "originalScore" }
],
"params" : {
"weights" : {
"documentRecency" : 1.0,
"isBook" : 0.1,
"originalScore" : 0.5
}
}
}
モデルの進化
-
linearModel201701
はfeatureStore201701
のフィーチャーを使用します。 -
treesModel201702
はfeatureStore201702
のフィーチャーを使用します。 -
linearModel201701
とtreesModel201702
、およびそれらのフィーチャーストアは、両方が必要な場合、共存できます。 -
linearModel201701
が削除されたら、featureStore201701
も削除できます。 -
使用される規則
-
<store>.json
ファイルには、<store>
フィーチャーストアのフィーチャーが含まれています。 -
<model>.json
ファイルには、<model>
というモデル名が含まれています。 -
「世代」ID(例:
YYYYMM
年-月)は、フィーチャーストア名とモデル名の一部です。 -
モデルのフィーチャーと重みは名前でアルファベット順にソートされているため、2つのモデルの共通点と相違点を簡単に確認できます。
-
ストアのフィーチャーは名前でアルファベット順にソートされているため、2つのフィーチャーストアの共通点と相違点を簡単に確認できます。
-
[
{
"store" : "featureStore201701",
"name" : "documentRecency",
"class" : "org.apache.solr.ltr.feature.SolrFeature",
"params" : {
"q" : "{!func}recip( ms(NOW,last_modified), 3.16e-11, 1, 1)"
}
},
{
"store" : "featureStore201701",
"name" : "isBook",
"class" : "org.apache.solr.ltr.feature.SolrFeature",
"params" : {
"fq": [ "{!terms f=category}book" ]
}
},
{
"store" : "featureStore201701",
"name" : "originalScore",
"class" : "org.apache.solr.ltr.feature.OriginalScoreFeature",
"params" : {}
}
]
{
"store" : "featureStore201701",
"name" : "linearModel201701",
"class" : "org.apache.solr.ltr.model.LinearModel",
"features" : [
{ "name" : "documentRecency" },
{ "name" : "isBook" },
{ "name" : "originalScore" }
],
"params" : {
"weights" : {
"documentRecency" : 0.1,
"isBook" : 1.0,
"originalScore" : 0.5
}
}
}
[
{
"store" : "featureStore201702",
"name" : "isBook",
"class" : "org.apache.solr.ltr.feature.SolrFeature",
"params" : {
"fq": [ "{!terms f=category}book" ]
}
},
{
"store" : "featureStore201702",
"name" : "originalScore",
"class" : "org.apache.solr.ltr.feature.OriginalScoreFeature",
"params" : {}
}
]
{
"store" : "featureStore201702",
"name" : "treesModel201702",
"class" : "org.apache.solr.ltr.model.MultipleAdditiveTreesModel",
"features" : [
{ "name" : "isBook" },
{ "name" : "originalScore" }
],
"params" : {
"trees" : [
{
"weight" : "1",
"root" : {
"feature" : "isBook",
"threshold" : "0.5",
"left" : { "value" : "-100" },
"right" : {
"feature" : "originalScore",
"threshold" : "10.0",
"left" : { "value" : "50" },
"right" : { "value" : "75" }
}
}
},
{
"weight" : "2",
"root" : {
"value" : "-10"
}
}
]
}
}
フィーチャーのロギング
logAllパラメータ
次のような完全なフィーチャーストアがあるとします。
[
{
"store" : "completeFeaturesStore",
"name" : "documentRecency",
"class" : "org.apache.solr.ltr.feature.SolrFeature",
"params" : {
"q" : "{!func}recip( ms(NOW,last_modified), 3.16e-11, 1, 1)"
}
},
{
"store" : "completeFeaturesStore",
"name" : "isBook",
"class" : "org.apache.solr.ltr.feature.SolrFeature",
"params" : {
"fq": ["{!terms f=cat}book"]
}
},
{
"store" : "completeFeaturesStore",
"name" : "originalScore",
"class" : "org.apache.solr.ltr.feature.OriginalScoreFeature",
"params" : {}
}
]
completeFeaturesStore
のフィーチャーのうち2つだけを使用する単純な線形モデルがあるとします。
{
"store" : "completeFeaturesStore",
"name" : "linearModel",
"class" : "org.apache.solr.ltr.model.LinearModel",
"features" : [
{ "name" : "isBook" },
{ "name" : "originalScore" }
],
"params" : {
"weights" : {
"isBook" : 1.0,
"originalScore" : 0.5
}
}
}
store
およびlogAll
パラメータを定義せずにロギング+リランキングクエリを実行すると、モデルフィーチャーのみが出力されます(デフォルト:store=model store
およびlogAll=false
)。
クエリ
https://127.0.0.1:8983/solr/techproducts/query?q=test&rq={!ltr model=linearModel reRankDocs=100}&fl=id,score,[features]
出力
{
"responseHeader":{
"status":0,
"QTime":0,
"params":{
"q":"test",
"fl":"id,score,[features]",
"rq":"{!ltr model=linearModel reRankDocs=100}"}},
"response":{"numFound":2,"start":0,"maxScore":1.0005897,"docs":[
{
"id":"GB18030TEST",
"score":1.0005897,
"[features]":"isBook=0.0,originalScore=1.959392"},
{
"id":"UTF8TEST",
"score":0.79656565,
"[features]":"isBook=0.0,originalScore=1.5513437"}]
}}
store
パラメータを定義せずにlogAll = true
を設定してロギング+リランキングクエリを実行すると、モデルストアのすべてのフィーチャーが出力されます。
クエリ
https://127.0.0.1:8983/solr/techproducts/query?q=test&rq={!ltr model=linearModel reRankDocs=100}&fl=id,score,[features logAll=true]
出力
{
"responseHeader":{
"status":0,
"QTime":0,
"params":{
"q":"test",
"fl":"id,score,[features logAll=true]",
"rq":"{!ltr model=linearModel reRankDocs=100}"}},
"response":{"numFound":2,"start":0,"maxScore":1.0005897,"docs":[
{
"id":"GB18030TEST",
"score":1.0005897,
"[features]":"documentRecency=0.020893792,isBook=0.0,originalScore=1.959392"},
{
"id":"UTF8TEST",
"score":0.79656565,
"[features]":"documentRecency=0.020893792,isBook=0.0,originalScore=1.5513437"}]
}}
次のような別のフィーチャーストアがあるとします。
[
{
"store": "differentFeaturesStore",
"name": "valueFeature1",
"class": "org.apache.solr.ltr.feature.FieldValueFeature",
"params": {
"field": "field1"
}
},
{
"store": "differentFeaturesStore",
"name": "valueFeature2",
"class": "org.apache.solr.ltr.feature.FieldValueFeature",
"params": {
"field": "field2"
}
}
]
logAll
パラメータを定義せずに、モデルストアとは異なるstore
パラメータを定義してロギング+リランキングクエリを実行すると、選択されたフィーチャーストアのすべてのフィーチャーが出力されます(デフォルト:logAll=true
)。
クエリ
https://127.0.0.1:8983/solr/techproducts/query?q=test&rq={!ltr model=linearModel reRankDocs=100}&fl=id,score,[features store=differentFeaturesStore]
出力
{
"responseHeader":{
"status":0,
"QTime":0,
"params":{
"q":"test",
"fl":"id,score,[features store=differentFeaturesStore]",
"rq":"{!ltr model=linearModel reRankDocs=100}"}},
"response":{"numFound":2,"start":0,"maxScore":1.0005897,"docs":[
{
"id":"GB18030TEST",
"score":1.0005897,
"[features]":"valueFeature1=0.1,valueFeature2=2.0"},
{
"id":"UTF8TEST",
"score":0.79656565,
"[features]":"valueFeature1=1.3,valueFeature2=4.0"}]
}}
formatパラメータ
次のようなフィーチャーストアがあるとします。
[
{
"store": "myFeaturesStore",
"name": "featureA",
"class": "org.apache.solr.ltr.feature.FieldValueFeature",
"params": {
"field": "field1"
}
},
{
"store": "myFeaturesStore",
"name": "featureB",
"class": "org.apache.solr.ltr.feature.FieldValueFeature",
"params": {
"field": "field2"
}
},
{
"store": "myFeaturesStore",
"name": "featureC",
"class": "org.apache.solr.ltr.feature.FieldValueFeature",
"params": {
"field": "field3"
}
}
]
featureA=0.1,featureB=0.2,featureC=0.0
のようなdense CSV値を返すには、フィーチャーロガートランスフォーマーにformat=dense
パラメータを渡します。
https://127.0.0.1:8983/solr/techproducts/query?q=test&fl=id,score,[features store=myFeaturesStore format=dense]
出力
{
"responseHeader":{
"status":0,
"QTime":0,
"params":{
"q":"test",
"fl":"id,score,[features store=myFeaturesStore format=dense]"}},
"response":{"numFound":2,"start":0,"maxScore":1.0005897,"docs":[
{
"id":"GB18030TEST",
"score":1.0005897,
"[features]":"featureA=0.1,featureB=0.2,featureC=0.0"},
{
"id":"UTF8TEST",
"score":0.79656565,
"[features]":"featureA=1.3,featureB=0.0,featureC=2.1"}]
}}
featureA=0.1,featureB=0.2
のようなsparse CSV値を返すには、フィーチャーロガートランスフォーマーにformat=sparse
パラメータを渡します。
https://127.0.0.1:8983/solr/techproducts/query?q=test&fl=id,score,[features store=myFeaturesStore format=sparse]
出力
{
"responseHeader":{
"status":0,
"QTime":0,
"params":{
"q":"test",
"fl":"id,score,[features store=myFeaturesStore format=sparse]"}},
"response":{"numFound":2,"start":0,"maxScore":1.0005897,"docs":[
{
"id":"GB18030TEST",
"score":1.0005897,
"[features]":"featureA=0.1,featureB=0.2"},
{
"id":"UTF8TEST",
"score":0.79656565,
"[features]":"featureA=1.3,featureC=2.1"}]
}}