学习排序
使用学习排名(或简称LTR)模块,您可以在 Solr 中配置和运行机器学习的排名模型。
该模块还支持在 Solr 中记录功能。您在 Solr 外部唯一需要做的事情就是训练自己的排名模型。
学习排名概念
重新排名
重新排名允许您运行一个简单的查询以匹配文档,然后使用不同、更复杂的查询中的得分重新对前 N 个文档进行排名。此页面描述了LTR复杂查询的使用方法,有关 Solr 分发中包含的其他排名查询的信息,请参阅查询重新排名。
学习排名模型
排名模型
排名模型计算用于重新对文档进行排名的分数。无论使用哪种特定算法或实现,排名模型的计算都可以使用三种类型的输入
-
表示评分算法的参数
-
表示正在评分的文档的功能
-
表示正在为其对文档进行评分的查询的功能
训练模型
特征工程
LTR 模块包括多个特性类以及对自定义特性的支持。每个特性类的 javadoc 都包含一个示例来说明该类的用法。然后,特性工程本身的过程完全取决于你的领域专业知识和创造力。
特性 | 类 | 示例参数 | 外部特性信息 |
---|---|---|---|
字段长度 |
|
(尚未)支持 |
|
字段值 |
|
(尚未)支持 |
|
原始分数 |
|
不适用 |
|
solr 查询 |
|
支持 |
|
solr 筛选查询 |
|
支持 |
|
solr 查询 + 筛选查询 |
|
支持 |
|
值 |
|
支持 |
|
(自定义) |
(扩展 Feature 的自定义类) |
归一化器 | 类 | 示例参数 |
---|---|---|
恒等 |
|
|
最小值和最大值 |
|
|
标准 |
|
|
(自定义) |
(扩展 Normalizer 的自定义类) |
特性记录
ltr 模块包括一个 [features]
转换器,以支持计算和返回特性值,用于 特性提取 目的,包括并且尤其是在你还没有实际重新排序模型时。
特性选择和模型训练
特性选择和模型训练在离线和 Solr 外部进行。ltr 模块支持两种通用的模型形式以及自定义模型。每个模型类的 javadoc 都包含一个示例来说明该类的配置。以 JSON 文件的形式,你的训练模型或模型(例如,针对不同客户地理位置的不同模型)可以使用提供的 REST API 直接上传到 Solr 中。
通用形式 | 类 | 具体示例 |
---|---|---|
线性 |
RankSVM、Pranking |
|
多重加法树 |
LambdaMART、梯度提升回归树 (GBRT) |
|
神经网络 |
RankNet |
|
(包装器) |
(不适用) |
|
(自定义) |
(扩展 AdapterModel 的自定义类) |
(不适用) |
(自定义) |
(扩展 LTRScoringModel 的自定义类) |
(不适用) |
模块
通过 ltr
Solr 模块 提供,在使用前需要启用该模块。
LTR 配置
学习到排名是一个模块,因此其插件必须在 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_
特征存储。
发现所有特征存储的名称
http://localhost:8983/solr/techproducts/schema/feature-store
检查 commonFeatureStore
特征存储的内容
http://localhost:8983/solr/techproducts/schema/feature-store/commonFeatureStore
模型
-
模型使用来自一个特征存储的特征。
-
如果没有指定存储,则将使用默认
_DEFAULT_
特征存储。 -
模型不必使用特征存储中定义的所有特征。
-
多个模型可以使用相同的特征存储。
记录 currentFeatureStore
的特征
http://localhost:8983/solr/techproducts/query?q=test&fl=id,score,[features store=currentFeatureStore]
在使用 currentModel
根据 currentFeatureStore
重新排序时,记录 nextFeatureStore
特征
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'
只有在没有模型使用特征存储时才能删除特征存储。 |
删除 currentFeatureStore
特征存储
curl -XDELETE 'http://localhost: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
来使用。
myWrapperModel 中未配置任何 "features" ,因为将使用包装模型(myModel )的特征;还要注意,为包装模型配置的 "store" 必须与包装模型的 "store" 相匹配,即在此示例中,使用了名为 largeModelsFeatureStore 的特征存储。 |
<lib dir="/path/to/models" regex=".*\.json" /> 在此情况下不起作用,因为如果 <lib /> 指示文件,则 SolrResourceLoader 会将给定的资源视为 JAR。 |
作为上述 DefaultWrapperModel
的替代方案,可以 增加 ZooKeeper 的文件大小限制。
应用更改
特征存储和模型存储都是 受管资源。对受管资源所做的更改不会应用到活动 Solr 组件,直到重新加载 Solr 集合(或单服务器模式下的 Solr 核心)。
LTR 快速入门
Solr 中包含的 "techproducts"
示例经过预配置,可以从 ltr
Solr 模块 加载学习排序所需的插件,但默认情况下这些插件处于禁用状态。
要启用插件,请在运行 techproducts
示例时指定 solr.ltr.enabled
JVM 系统属性
bin/solr start -e techproducts -Dsolr.ltr.enabled=true
上传特征
要在 /path/myFeatures.json
文件中上传特征,请运行
curl -XPUT 'http://localhost:8983/solr/techproducts/schema/feature-store' --data-binary "@/path/myFeatures.json" -H 'Content-type:application/json'
要查看刚上传的特征,请在浏览器中打开以下 URL
http://localhost: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" : {}
}
]
记录特征
要记录查询中的一部分特征,请将 [features]
添加到 fl
参数,例如
http://localhost: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 '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
{
"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
参数添加到您的搜索中,例如
http://localhost:8983/solr/techproducts/query?q=test&rq={!ltr model=myModel reRankDocs=100}&fl=id,score
添加 rq
参数不会更改搜索的输出。
要获取重新排序期间计算的特征值,请将 [features]
添加到 fl
参数,例如
http://localhost: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"}]
}}
运行重新排序查询,交错两个模型
要重新排序查询的结果,交错两个模型 (myModelA, myModelB),请将 rq
参数添加到您的搜索中,在输入中传递两个模型,例如
http://localhost:8983/solr/techproducts/query?q=test&rq={!ltr model=myModelA model=myModelB reRankDocs=100}&fl=id,score
要获取交错在重新排序期间为搜索结果挑选的模型,请将 [interleaving]
添加到 fl
参数,例如
http://localhost: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
模型标识符作为一种模型传递,并将比较模型作为另一种模型传递,例如
http://localhost:8983/solr/techproducts/query?q=test&rq={!ltr model=_OriginalRanking_ model=myModel reRankDocs=100}&fl=id,score
添加 rq
参数不会更改搜索的输出。
要获取交错在重新排序期间为搜索结果挑选的模型,请将 [interleaving]
添加到 fl
参数,例如
http://localhost: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"}]
}}
运行带有交错的重新排序查询,传递特定算法
要对查询结果进行重新排序,使用特定算法交错两个模型,请将 interleavingAlgorithm
本地参数添加到 ltr 查询解析器,例如
http://localhost: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 'http://localhost:8983/solr/techproducts/schema/feature-store' --data-binary "@/path/myEfiFeatures.json" -H 'Content-type:application/json'
要查看刚上传的特征,请在浏览器中打开以下 URL
http://localhost: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
特征作为查询的一部分,请将 efi.*
参数添加到 fl
参数的 [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
{
"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
}
}
}
运行重新排序查询
要获取重新排序期间计算的特征值,请将 [features]
添加到 fl
参数和 efi.*
参数添加到 rq
参数,例如
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]
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
参数的 [features]
部分中没有 efi.*
参数。
重新排序时记录特征
要在使用 myModel
重新排序时记录 myEfiFeatureStore
特征
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
参数中没有 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。
模型处理特征的空值
此功能仅适用于 MultipleAdditiveTreesModel。
在某些情况下,特征的空值与零值具有不同的含义。有些模型经过训练以区分两者(例如 https://xgboost.readthedocs.io/en/stable/faq.html#how-to-deal-with-missing-values),在 Solr 中引入了额外的 missing
分支参数来支持此功能。
当相应特征值为 null 时,这定义要遵循的分支。使用默认配置,null 值和零值具有相同的含义。
要处理空值,需要修改 myFeatures.json
文件。需要向每个可能采用空值的特征添加一个 defaultValue
参数,其值设为 NaN
。
[
{
"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"
}
}
]
此外,模型配置需要两个附加参数
-
isNullSameAsZero
需要在模型params
中定义,并将其设置为false
; -
需要将
missing
参数添加到相应特征支持空值的每个分支。这可以在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
时,特征向量会发生变化。
-
稠密格式:显示所有特征值,还显示可以为零或空值的默认值。
-
稀疏格式:仅显示非默认值。
例如
给定之前定义的特征;如果它们的值为 matchedTitle=0
和 productReviewScore=0
,稀疏格式将返回 productReviewScore:0
(0 是 matchedTitle=0
的默认值,因此不会返回,0 不是 productReviewScore=0
的默认值,因此会返回)。
实现和贡献
- Solr Learning-To-Rank 在底层如何工作?
-
有关实现概述,请参阅
ltr
javadocs。 - 我如何编写附加模型和/或特征?
-
欢迎提供更多模型、功能、标准化程序和交错算法。相关链接
LTR 示例
一个功能存储,多个排名模型
-
leftModel
和rightModel
都使用来自commonFeatureStore
的功能,这两个模型之间的唯一区别是附加到每个功能的权重。 -
使用的约定
-
commonFeatureStore.json
文件包含commonFeatureStore
功能存储的功能 -
leftModel.json
文件包含名为leftModel
的模型 -
rightModel.json
文件包含名为rightModel
的模型 -
模型的功能和权重按名称按字母顺序排列,这使得可以轻松查看这两个模型之间的共性和差异。
-
存储功能按名称按字母顺序排列,这使得可以轻松查找模型中使用的功能
-
[
{
"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
年月)是功能存储和模型名称的一部分 -
模型的功能和权重按名称按字母顺序排列,这使得可以轻松查看这两个模型之间的共性和差异。
-
存储功能按名称按字母顺序排列,这使得可以轻松查看这两个功能存储之间的共性和差异。
-
[
{
"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` 中的两个特征
{
"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`)。
查询
http://localhost: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` 的情况下进行日志记录 + 重新排序查询将打印模型存储中的所有特征。
查询
http://localhost: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`)。
查询
http://localhost: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"
}
}
]
若要返回密集型 CSV 值,例如:`featureA=0.1,featureB=0.2,featureC=0.0`,请将 `format=dense` 参数传递给特征记录器转换器
http://localhost: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"}]
}}
若要返回稀疏型 CSV 值,例如:`featureA=0.1,featureB=0.2`,请将 `format=sparse` 参数传递给特征记录器转换器
http://localhost: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"}]
}}