通過學(xué)習(xí)排序(或 LTR)contrib 模塊,您可以在 Solr 中配置和運行機器學(xué)習(xí)排序模型。
該模塊還支持 Solr 內(nèi)部的特征提取。您需要在 Solr 之外做的唯一事情就是訓(xùn)練你自己的排序模型。
學(xué)習(xí)排序包含了三個部分,分別是:重新排序、學(xué)習(xí)排序模型以及訓(xùn)練模式,接下來我們將一一介紹。
通過重新排序,您可以運行一個簡單的查詢來匹配文檔,然后使用來自不同的、更復(fù)雜的查詢中的分?jǐn)?shù)重新排列前 N 個文檔。本頁面描述了 LTR 復(fù)雜查詢的使用,Solr 發(fā)行版中包含的其他等級查詢的信息可以在查詢重新排序頁面上找到。
在信息檢索系統(tǒng)中,學(xué)習(xí)排序被用來排名使用經(jīng)過訓(xùn)練的機器學(xué)習(xí)模型來檢索前 N 個文檔。希望這種復(fù)雜的模型可以比 TF-IDF 或 BM25 等標(biāo)準(zhǔn)排序函數(shù)做出更細(xì)致的排序決定。
排序模型計算用于重新排列文檔的分?jǐn)?shù)。不管任何特定的算法或?qū)崿F(xiàn),排序模型的計算可以使用三種類型的輸入:
特征是一個值,一個數(shù)字,表示被評分的文件的數(shù)量或質(zhì)量,或者是要對其進(jìn)行記錄的查詢。例如,文檔通常具有“新近度”質(zhì)量,“過去購買次數(shù)”可能是作為搜索查詢的一部分傳遞給 Solr 的數(shù)量。
一些排名模式預(yù)計在特定的規(guī)模的功能。標(biāo)準(zhǔn)化器可用于將任意特征值轉(zhuǎn)換為標(biāo)準(zhǔn)化值,例如:0..1 或 0..100 的標(biāo)度。
LTR contrib 模塊包含幾個函數(shù)類以及對自定義功能的支持。每個函數(shù)類的 javadoc 都包含一個例子來說明該類的使用方法。函數(shù)工程本身的過程完全取決于您的領(lǐng)域?qū)I(yè)知識和創(chuàng)造力。
函數(shù) | 類 | 示例參數(shù) | 額外的函數(shù)信息 |
---|---|---|---|
字段長度 |
FieldLengthFeature |
|
尚未支持 |
字段值 |
FieldValueFeature |
|
尚未支持 |
原始分?jǐn)?shù) |
OriginalScoreFeature |
|
不適用 |
solr 查詢 |
SolrFeature |
|
支持的 |
solr 過濾器查詢 |
SolrFeature |
|
支持的 |
solr 查詢 + 過濾器查詢 |
SolrFeature |
|
支持的 |
值 |
ValueFeature |
|
支持的 |
(自定義) |
(自定義類擴展函數(shù)) |
正規(guī)化 | 類 | 示例參數(shù) |
---|---|---|
Identity
|
IdentityNormalizer |
|
MINMAX |
MinMaxNormalizer |
|
Standard
|
StandardNormalizer |
|
(自定義) |
(自定義類擴展 Normalizer) |
LTR contrib 模塊包含一個[函數(shù)轉(zhuǎn)換器],用于支持函數(shù)值的計算和返回以便進(jìn)行函數(shù)提取,特別是當(dāng)您還沒有真正的重新排序模型時。
函數(shù)選擇和模型訓(xùn)練在離線和 Solr 之外進(jìn)行。ltr contrib 模塊支持兩種廣義形式的模型以及自定義模型。每個模型類的 javadoc 包含一個示例來說明該類的配置。以 JSON 文件的形式,可以使用提供的 REST API 直接將經(jīng)過培訓(xùn)的一個或多個模型(例如針對不同客戶地區(qū)的不同模型)上傳到 Solr。
一般形式 | 類 | 具體的例子 |
---|---|---|
Linear
|
LinearModel
|
RankSVM, Pranking
|
Multiple Additive Trees
|
MultipleAdditiveTreesModel |
LambdaMART, Gradient Boosted Regression Trees (GBRT)
|
(自定義) |
(自定義類擴展 LTRScoringModel) |
(不適用) |
Solr 附帶的 "techproducts" 示例預(yù)先配置了學(xué)習(xí)排序所需的插件,但默認(rèn)情況下它們是禁用的。
要啟用插件,請在運行示例時指定 solr.ltr.enabled JVM 系統(tǒng)屬性:
bin/solr start -e techproducts -Dsolr.ltr.enabled=true
要上傳 /path/myFeatures.json 文件中的函數(shù),請運行:
curl -XPUT 'http://localhost:8983/solr/techproducts/schema/feature-store' --data-binary "@/path/myFeatures.json" -H 'Content-type:application/json'
要查看剛剛上傳的函數(shù),請在瀏覽器中打開以下 URL:
http://localhost:8983/solr/techproducts/schema/feature-store/_DEFAULT_
例如:/path/myFeatures.json
[
{
"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" : {}
}
]
要將函數(shù)作為查詢的一部分提取,請?zhí)砑?[features] 到 fl 參數(shù)中,例如:
http://localhost:8983/solr/techproducts/query?q=test&fl=id,score,%5Bfeatures%5D
輸出 XML 將包含作為逗號分隔列表的函數(shù)值,類似于此處顯示的輸出:
{
"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"}]
}}
要將 /path/myModel.json 文件中的模型上傳,請運行:
curl -XPUT 'http://localhost:8983/solr/techproducts/schema/model-store' --data-binary "@/path/myModel.json" -H 'Content-type:application/json'
要查看剛剛上傳的模型,請在瀏覽器中打開以下URL:
http://localhost:8983/solr/techproducts/schema/model-store
例如:/path/myModel.json
{
"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
}
}
}
要重新查詢查詢的結(jié)果,請將該 rq 參數(shù)添加到搜索中,例如:
http://localhost:8983/solr/techproducts/query?q=test&rq=%7B!ltr%20model=myModel%20reRankDocs=100%7D&fl=id,score[http://localhost:8983/solr/techproducts/query?q=test&rq=\{!ltr model=myModel reRankDocs=100}&fl=id,score]`
rq 參數(shù)的添加不會改變搜索的輸出 XML。
要獲得重新排序時計算的函數(shù)值,請?zhí)砑?[features] 到 fl 參數(shù)中,例如:
http://localhost:8983/solr/techproducts/query?q=test&rq=%7B!ltr%20model=myModel%20reRankDocs=100%7D&fl=id,score,%5Bfeatures%5D[http://localhost:8983/solr/techproducts/query?q=test&rq=\{!ltr model=myModel reRankDocs=100}&fl=id,score,[features]]
輸出 XML 將包含作為逗號分隔列表的函數(shù)值,類似于此處顯示的輸出:
{
"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"}]
}}
該 ValueFeature 和 SolrFeature 類支持使用外部函數(shù)信息,簡稱 efi。
要上傳 /path/myEfiFeatures.json 文件中的函數(shù),請運行:
curl -XPUT 'http://localhost:8983/solr/techproducts/schema/feature-store' --data-binary "@/path/myEfiFeatures.json" -H 'Content-type:application/json'
要查看剛剛上傳的函數(shù),請在瀏覽器中打開以下URL:
http://localhost:8983/solr/techproducts/schema/feature-store/myEfiFeatureStore
例如:/path/myEfiFeatures.json
[
{
"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}" }
}
]
另外,您可能已經(jīng)注意到該 myEfiFeatures.json 示例使用了 "store":"myEfiFeatureStore" 屬性:store,請在本頁面的 LTR 生命周期部分閱讀更多關(guān)于函數(shù)存儲的內(nèi)容。
要將 myEfiFeatureStore 函數(shù)作為查詢的一部分提取,請將 efi.* 參數(shù)添加到 fl 參數(shù)的 [features] 部分,例如:
http://localhost:8983/solr/techproducts/query?q=test&fl=id,cat,manu,score,[features store=myEfiFeatureStore efi.text=test efi.preferredManufacturer=Apache efi.fromMobile=1]
http://localhost: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 'http://localhost:8983/solr/techproducts/schema/model-store' --data-binary "@/path/myEfiModel.json" -H 'Content-type:application/json'
要查看剛剛上傳的模型,請在瀏覽器中打開以下URL:http://localhost:8983/solr/techproducts/schema/model-store
例如:/path/myEfiModel.json
{
"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
}
}
}
要獲得重新排序期間計算的函數(shù)值,請將 [features] 參數(shù)添加到 fl 參數(shù)中并且將 efi.* 參數(shù)添加到 rq 參數(shù)中,例如:
http://localhost: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]] link:[]
http://localhost: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 參數(shù)的 [features] 部分中沒有 efi. * 參數(shù)。
要提取 myEfiFeatureStore 函數(shù)的功能,同時仍然使用 myModel 進(jìn)行重新排序:
http://localhost: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 參數(shù)中沒有 efi.* 參數(shù)(因為 myModel 沒有使用 efi 函數(shù))以及 fl 參數(shù)的 [features] 部分存在 efi.* 參數(shù)(因為 myEfiFeatureStore 包含了 efi 函數(shù))。
在此頁面的LTR生命周期部分閱讀有關(guān)模型演化的更多信息。
示例訓(xùn)練數(shù)據(jù)和演示“訓(xùn)練和上傳模型”腳本可以在 Apache lucene-solr git repository(鏡像在github.com)的 solr/contrib/ltr/example 文件夾中找到(solr/contrib/ltr/example 文件夾不是在 solr 二進(jìn)制文件釋放)。
LTR contrib 模塊需要:dist/solr-ltr-*.jarJAR。
Learning-To-Rank(學(xué)習(xí)排序)是一個 contrib 模塊,因此它的插件必須在 solrconfig.xml 配置。
<lib dir="${solr.install.dir:../../../..}/dist/" regex="solr-ltr-\d.*\.jar" />
<queryParser name="ltr" class="org.apache.solr.ltr.search.LTRQParserPlugin"/>
<cache name="QUERY_DOC_FV"
class="solr.search.LRUCache"
size="4096"
initialSize="2048"
autowarmCount="4096"
regenerator="solr.search.NoOpRegenerator" />
<transformer name="features" class="org.apache.solr.ltr.response.transform.LTRFeatureLoggerTransformerFactory">
<str name="fvCacheName">QUERY_DOC_FV</str>
</transformer>
可以為查詢解析器和轉(zhuǎn)換器配置線程模塊,以并行化函數(shù)權(quán)重的創(chuàng)建。有關(guān)詳細(xì)信息,請參閱 LTRThreadModule javadocs。
函數(shù)轉(zhuǎn)換器返回密集的 CSV 值,如:featureA=0.1、featureB=0.2、featureC=0.3、featureD=0.0。
對于稀疏的 CSV 輸出,例如:featureA:0.1、featureB:0.2、featureC:0.3,您可以在 solrconfig 中自定義函數(shù)記錄器轉(zhuǎn)換器聲明,如下所示:
<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>
建議您將所有函數(shù)組織到類似于命名空間的存儲中:
查看所有函數(shù)存儲的名稱:
http://localhost:8983/solr/techproducts/schema/feature-store
檢查 commonFeatureStore 函數(shù)存儲的內(nèi)容:
http://localhost:8983/solr/techproducts/schema/feature-store/commonFeatureStore
提取 currentFeatureStore 函數(shù)的函數(shù):
http://localhost:8983/solr/techproducts/query?q=test&fl=id,score,[features store=currentFeatureStore]
提取 nextFeatureStore 函數(shù)的函數(shù),同時 reranking 和 currentModel 基于 currentFeatureStore:
http://localhost:8983/solr/techproducts/query?q=test&rq={!ltr model=currentModel reRankDocs=100}&fl=id,score,[features store=nextFeatureStore]
要查看所有型號:
http://localhost:8983/solr/techproducts/schema/model-store
刪除 currentModel 模型:
curl -XDELETE 'http://localhost:8983/solr/techproducts/schema/model-store/currentModel'
注意:只有在沒有使用模型的情況下,才能刪除函數(shù)存儲。
刪除 currentFeatureStore 函數(shù)存儲:
curl -XDELETE 'http://localhost:8983/solr/techproducts/schema/feature-store/currentFeatureStore'
函數(shù)存儲和模型存儲都是托管資源。在 Solr 集合(或單服務(wù)器模式下的 Solr 核心)重新加載之前,對托管資源所做的更改不會應(yīng)用到活動的 Solr 組件。
例如:/path/commonFeatureStore.json
[
{
"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" : {}
}
]
例如:/path/leftModel.json
{
"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
}
}
}
例如:/path/rightModel.json
{
"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
}
}
}
例如:/path/featureStore201701.json
[
{
"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" : {}
}
]
例如:/path/linearModel201701.json
{
"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
}
}
}
例如:/path/featureStore201702.json
[
{
"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" : {}
}
]
例如:/path/treesModel201702.json
{
"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"
}
}
]
}
}
更多建議: