排序配置¶
排序(Sort) 阶段在精排之后执行,在这里可以进行排序以及打散、窗口规则等逻辑。
排序的配置与召回的配置是类似的。具体的排序配置定义放在 SortConfs 。SortNames 提供分场景(scene) 的配置,每个 scene 对应一组排序名称。如果场景没有显式的配置,则走 default 场景配置。
BoostScoreSort¶
当调用精排模型后,每个 item 会有个模型 score, 有时候根据业务运营需求,需要对 score 进行操作,即提降权操作。引擎服务本身支持自定义 function 来支持提降权操作,具体操作参考这里 ,但这里需要自定义开发代码。
为了更方便的设置提降权操作,我们这里也支持通过规则设置来进行提降权操作。规则设置上,分为两部分
设置条件规则,通过 item 或者 user 的某些属性,比如召回id, 类目,画像特征等属性来判断是否符合规则条件
设置提降权表达式,目前只支持对 score 设置表达式,比如 score * 1.2, score * 0.5 等等
整体配置如下:
{
"Name": "BoostScoreSort",
"SortType": "BoostScoreSort",
"Debug": false,
"BoostScoreConditions": [
{
"Conditions": [
{
"Name": "recall_name",
"Domain": "item",
"Type": "string",
"Value": "OTSGlobalHot",
"Operator": "equal"
}
],
"Expression": "score * 2"
},
{
"Conditions": [
{
"Name": "recall_name",
"Domain": "item",
"Type": "string",
"Value": "UserTopicRecall",
"Operator": "equal"
}
],
"Expression": "score * 1.2"
}
]
}
Name 自定义的 sort 名称
SortType 类型, 固定值 BoostScoreSort
Debug 测试标记,这里为 ture 情况下, 提降权之前的原始 score 会以 org_score 记录到 item 的 properties 中,然后请求中打开 debug 标记,可以看到 item属性值。这只为了方便调试,线上不应该打开
BoostScoreConditions 具体的提降权规则配置, 可以设置成多条规则,每一条规则对于匹配的数据进行相应的提降权操作。具体的每条规则设置如下:
Conditions 条件规则, 可以设置多个匹配规则。匹配规则具体设置可以参考这里。 匹配规则和 FilterParams 里的设置是一致的。
Name 可以理解成 item 或 user 的 properties 的属性名称。recall_name 指的是召回id 这个特征。
Domain 可以取值为 user 或者 item,默认是 item。指的是 Name 选项属于 item 特征还是 user 特征,Name 必须在 item 或 user 的 properties 里找到。
Type 会将特征值转化为指定类型进行比较。
Value 此值将会和 item 或 user 的 properties 中 Name选项对应的特征值进行比较。如果相同,将会执行 Expression 表达式。
Expression 提降权表达式,目前 score 指的是原始的 item 的score, 目前只支持 score 的引用,不支持其它额外属性的引用。
BoostScoreByWeight¶
根据业务需求,不同 item 可能会有不同的权重,这个权重是 item 表中的一个字段,需要通过权重字段对 score 进行提降权 计算公示: weight * item.Score
整体配置如下:
{
"Name": "BoostScoreByWeight",
"SortType": "BoostScoreByWeight",
"TimeInterval": 172800,
"BoostScoreByWeightDao": {
"AdapterType": "hologres",
"HologresName": "pai_rec",
"HologresTableName": "test",
"ItemFieldName": "item_id",
"WeightFieldName": "weight"
}
}
Name 自定义的 sort 名称。
SortType 类型, 固定值 BoostScoreByWeight。
TimeInterval 时间间隔,单位秒, 每隔多长时间拉取一次 item 表。
BoostScoreByWeightDao item 表的一些数据库配置
AdapterType 数据库类型,比如 hologres, mysql
HologresName 已注册的数据源配置名称,当数据源是 hologres 时设置
HologresTableName 数据表名称
ItemFieldName 对应 item id 的字段名称,一般是表主键
WeightFieldName 权重字段
ItemRankScore¶
在精排阶段,只是从模型获取得分,并没有对 item 进行实际的排序。 ItemRankScore 可以对 item 进行倒序排序,这个是引擎内置的。 可以直接在 SortNames 中使用。
DiversityRuleSort¶
在推荐结果进行输出时,我们除了考虑要抓住用户的兴趣点,还要考虑推荐条目多样性的需求,即不同品类,不同属性的物品可以混合输出。
这里我们配置的规则参考如下:
具体配置详情:
{
"Name": "DiversityRuleSort",
"SortType": "DiversityRuleSort",
"DiversitySize": 100,
"ExcludeRecalls": [
"ColdStartVideoVectorRecall",
"LinUcbRecall_default2"
],
"DiversityRules": [
{
"Dimensions": [
"primaryId"
],
"IntervalSize": 1,
"WindowSize": 10,
"FrequencySize": 3
}
]
}
Name 自定义的 sort 名称
SortType 类型, 固定值 DiversityRuleSort
DiversitySize 多样性窗口大小,可以默认不指定。当不指定的时候,默认值为当前请求的 Size 大小。举个例子,比如在精排有500个条目,DiversitySize 会控制多少个条目需要多样性排序,很多情况下,不需要对 500 个都进行多样性排序。
ExcludeRecalls 需要排除多样性排序的召回 id 列表。 在有冷启动召回的情况,这些条目的维度信息可能确实,可以不进行多样性控制。
DiversityRules 多样性规则列表,可以设置多个规则,Item 条目都满足的情况下,才会加入多样性列表。当也有时候会出现,遍历了所有的条目后,都无法符合规则的话,会把当前最前面的条目加入到列表中,保证 item 是有序的。
上面说明中有两个打散策略,IntervalSize 控制最小间隔, 此值也可以不设置,说明不需要控制间隔
WindowSize 和 FrequencySize 控制窗口规则, 如果不需要控制窗口规则,这两个值可以不设置
DPPSort¶
DPP多样性打散算法参考资料:《基于行列式点过程的推荐多样性提升算法的直观理解》。
前提条件:使用DPP算法的前提是已经有了item里的embedding向量,而且这个embedding向量能够表示item本身的内容,embedding的相似度能够表示item内容层面的相似度,而不是其他层面(如行为)的相似度。举例如下:
建议: item 图片embedding / 文本描述信息的embedding / 类目、属性等静态item内容组合得到的embedding
不建议: 基于用户行为数据训练模型得到的embedding
本质上,想要打散的维度一定要能够在embedding里反映出来。比如,我们希望在推荐列表在商品价格这个维度有一些多样性,那么在训练模型得到embedding向量时就一定要有价格特征,否则就无法达到我们预期的效果。
PAI-Rec中使用DPP算法时的配置:
{
"SortConfs":[
"Name":"DPPSort",
"SortType": "DPPSort",
"DPPConf": [
{
"Name": "DPPSort",
"DaoConf": {
"AdapterType": "hologres",
"HologresName": "geeko_rec"
},
"TableName": "item_embedding_metric_learning",
"TableSuffixParam": "embedding_date",
"TablePKey": "product_id",
"EmbeddingColumn": "embedding",
"Alpha": 4.5,
"NormalizeEmb": "false",
"WindowSize": 10
}
]
],
"SortNames": {
"home_feed": ["ItemRankScore", "DPPSort"]
}
}
上面的配置给推荐场景 home_feed
配置了需要使用DPP算法的重排模块。其中,ItemRankScore
是表示对商品列表按照score降序排列的Sort模块的名字,在pairec里内置了 ItemRankScore
插件来做倒序排列。
配置项的说明如下:
配置项 |
说明 |
---|---|
HologresName |
hologres的链接字符串的key |
TableName |
item的embedding向量hologres表名 |
TableSuffixParam |
不为空时,表示需要去pairec配置中心获取场景名为pairec的配置项。配置项的key为 |
TablePKey |
向量hologres表的主键 |
EmbeddingColumn |
向量hologres表的embedding字段名 |
Alpha |
DPP算法用来平衡相关性和多样性的参数;值越大越偏向于相关性 |
NormalizeEmb |
是否需要对embedding向量做L2 normalize;如果生成embedding时已经做了L2 normalize则不需要再做,否则需要配置为true |
WindowSize |
多样性算法的翻滚窗口大小;只保证窗口内的item列表的多样性 |
MultiRecallMixSort¶
一般情况下,我们会有很多路召回,为了运营需求或者根据召回的类型,需要混合输出。比如
对冷启动召回有曝光数量的要求
多某一路召回有位置的要求
也可能包括多个混排规则。整体配置如下:
{
"SortConfs": [
{
"Name": "MixSort",
"SortType": "MultiRecallMixSort",
"RemainItem": false,
"MixSortRules": [
{
"MixStrategy": "random_position",
"NumberRate": 0.1,
"RecallNames": [
"OTSGlobalHot"
]
},
{
"MixStrategy": "fix_position",
"Positions": [
1,
3,
5
],
"RecallNames": [
"RecallName1"
]
}
]
}
]
}
Name 自定义的 sort 名称
SortType 类型, 固定值 MultiRecallMixSort
RemainItem 是否保留所有的item , 比如有 500 个 item 需要处理,但我们一次请求假设有 30 个, 当为 false 情况下, item 数量只会保留混排的结果, 当为 true 情况下, 剩余的 item 也保留下来,不过在 30 item 结果的后面。 这样后续还可以再对接 sort 进行进一步控制处理
MixSortRules 里面包含混排的规则列表
MixStrategy 混排策略,目前只有两个, random_position 标识位置随机, fix_position 标识固定位置, fix_position 的情况下,需要指定 Positions。 Positions 的位置从 1 开始, 在上面的例子中, RecallName1 的召回 item 在 位置 1, 3, 5 上进行输出。
NumberRate 空值输出的数量, random_position 下设置。 有效值为 0 ~ 1, 具体数量通过 请求的Size * NumberRate 算出。 这里也可以使用绝对值,使用 Number 代替 NumberRate
RecallNames 召回的名称,可以设置多个,设置多个的情况下,共享配置,但是具体哪个召回,不固定,顺序由进入到此 Sort 的位置决定
除了使用召回名称来匹配条目进行过滤,还可以使用条件过滤筛选出 item , 然后进行曝光。
{
"SortConfs": [
{
"Name": "MixSortByItemFeature",
"SortType": "MultiRecallMixSort",
"RemainItem": false,
"MixSortRules": [
{
"MixStrategy": "random_position",
"NumberRate": 0.1,
"Conditions": [
{
"Name": "gender",
"Domain": "item",
"Type": "string",
"Value": "man",
"Operator": "equal"
}
]
}
]
}
],
"SortNames": {
"default": [
"ItemRankScore",
"MixSortByItemFeature"
]
}
}
Conditions 设置的过滤条件。 可以设置多个。 匹配规则具体设置可以参考这里。 匹配规则和 FilterParams 里的设置是一致的。
Conditions 也支持数组集合的 contains 的操作
"Conditions": [
{
"Name": "tag_rules",
"Domain": "item",
"Type": "[]string",
"Value": [
"goods_boost_tag_dwh_new"
],
"Operator": "contains"
}
]
item 的属性 tag_rules 是一个 string 数组, 如果数组包含 goods_boost_tag_dwh_new 说明条件成立。
"Conditions": [
{
"Name": "shoe_valid_size",
"Domain": "item",
"Type": "[]string",
"Value": "user.shoe_size_list",
"Operator": "not_contains"
}
]
两个 string 数组, item 属性 shoe_valid_size 和 user 的属性 shoe_size_list 都是数组, 两者的集合没有交集的话,条件成立。