重排(Sort)階段在精排之後進行,在這裡可以進行排序以及打散、添加視窗規則等邏輯。
如何配置
重排的配置對應配置總覽中的 SortConfs,SortConfs 是一個 []object 結構,可以配置多個重排策略,目前 PAI-Rec 內建的有 BoostScoreSort、BoostScoreByWeight、ItemRankScore、DiversityRuleSort、DPPSort 和 MultiRecallMixSort。
重排公用配置一覽
每種重排配置,都會用到公用配置中的一部分,在此統一解釋,在單獨的重排配置中則不再贅述。
配置樣本:
{
"SortConfs": [
{
"Name": "",
"SortType": ""
}
]
}欄位名 | 類型 | 是否必填 | 描述 |
Name | string | 是 | 自訂重排名稱,可以在 SortNames 中引用 |
SortType | string | 是 | 排序類型,枚舉值
|
提降權重排(BoostScoreSort)
當調用精排模型後,每個 item 會有個模型返回的 score,有時候根據業務營運需求,需要對 score 進行操作,即提降權操作。
提降權操作在設定上分為兩部分
設定條件規則,通過 item 或者 user 的某些屬性,比如類目,性別等屬性來判斷是否符合規則條件
設定提降權運算式,目前只支援對 score 設定運算式,比如 score * 1.2, score * 0.5 等等
配置樣本
{
"SortConfs": [
{
"Name": "BoostScoreSort",
"SortType": "BoostScoreSort",
"Debug": false,
"BoostScoreConditions": [
{
"Conditions": [
{
"Name": "sex",
"Domain": "item",
"Type": "string",
"Value": "gender",
"Operator": "equal"
}
],
"Expression": "score * 2"
}
]
}
]
}上面配置中所表達的意思為:對特徵(sex)的值等於male的item,score乘以2。
欄位名 | 類型 | 是否必填 | 描述 |
Name | string | 是 | 自訂 sort 名稱 |
SortType | string | 是 | 重排類型,固定值: BoostScoreSort |
Debug | bool | 否 | 測試標記,這裡為 true 情況下, 提降權之前的原始 score 會以 org_score 記錄到 item 的 properties 中,然後請求中開啟 debug 標記,可以看到 item屬性值。這隻為了方便調試,線上不應該開啟 |
BoostScoreConditions | json array | 是 | 提降權的條件配置,可以配置多個,可以根據不同的條件,進行提降權 |
| []FilterParamConfig | 是 | 提降權的條件規則 |
| string | 是 | 提降權 score 的運算式, score 表示當前的物品得分。運算式裡可以引用 item 的屬性,比如 item_weight 是 item 的屬性,運算式可以這樣設定: score * item_weight 。 |
FilterParamConfig 配置如下:
欄位名 | 類型 | 是否必填 | 描述 |
Name | string | 是 | item 或者 user 的特徵名 |
Domain | string | 是 | 枚舉值,item/user。指的是 Name 選項屬於 item 特徵還是 user 特徵,Name 必須在 item 或 user 的 properties 裡找到。 |
Operator | string | 是 | 枚舉值:equal/not_equal/in/not_in/greater/greaterThan/less/lessThan/contains/not_contains |
Type | string | 是 | 特徵的類型 |
Value | object | 是 | 特徵的值 |
具體的條件設定,可以參考數量調整過濾(AdjustCountFilter)。
權重提降權重排(BoostScoreByWeight)
在對item進行提降權的時候,不同的item可能會有不同的權重,這個權重是item表中的一個欄位,需要通過權重欄位對score進行提降權。
score的計算公式:weight * item.score
配置樣本
{
"SortConfs": [
{
"Name": "BoostScoreByWeight",
"SortType": "BoostScoreByWeight",
"TimeInterval": 172800,
"BoostScoreByWeightDao": {
"AdapterType": "hologres",
"HologresName": "pai_rec",
"HologresTableName": "test",
"ItemFieldName": "item_id",
"WeightFieldName": "weight"
}
}
]
}BoostScoreByWeightDao
欄位名 | 類型 | 是否必填 | 描述 |
AdapterType | string | 是 | 資料來源的類型,當前只支援 hologres |
HologresName | string | 是 | 在資料來源配置(HologresConfs)中配置好的 holo 的自訂名稱,如資料來源配置中的 holo_info |
HologresTableName | string | 是 | holo 中 item 權重表的表名 |
ItemFieldName | string | 是 | item 權重表的主鍵 |
WeightFieldName | string | 是 | item 權重表中的權重欄位 |
Item分數重排(ItemRankScore)
ItemRankScore 可以通過 item 的 score 對 item 進行倒序排序,這個是引擎內建的,可以直接在 SortNames 中使用。
多樣性重排(DiversityRuleSort)
在推薦結果進行輸出時,我們除了考慮要抓住使用者的興趣點,還要考慮推薦條目多樣性的需求,即不同品類,不同屬性的物品可以混合輸出。
這裡我們配置的規則參考如下:
推薦多樣性打散規則
術語定義:
打散維度:用來打散的item屬性,比如類目、作者、Tag等
打散策略:
最小間隔k,即最多允許某一打散維度連續出現k次。
最多次數m,即在大小為n的視窗內同一打散維度item不允許出現超過m次。
打散邏輯:
打散規則只在同一次請求的返回結果裡做,不需要考慮跨請求的多樣性。
可以配置多個打散維度。
可以針對每個打散維度配置多個打散策略,並且每個打散策略可以配置不同的參數(k,m,n)。
配置樣本
{
"SortConfs": [
{
"Name": "DiversityRuleSort",
"SortType": "DiversityRuleSort",
"DiversitySize": 100,
"DiversityRules": [
{
"Dimensions": ["spfl"],
"WindowSize": 10,
"FrequencySize": 1
}
],
"ExcludeRecalls": [
"ColdStartVideoVectorRecall",
"LinUcbRecall_default2"
],
"Conditions": [
{
"Name": "spflPick",
"Domain": "user",
"Type": "string",
"Value": "",
"Operator": "equal"
}
]
}
]
}此重排需要配合 ExcludeRecalls 參數使用。
DiversityRules
欄位名 | 類型 | 是否必填 | 描述 |
Name | string | 是 | 自訂 sort 名稱 |
SortType | string | 是 | 重排類型,固定值:DiversityRuleSort |
DiversitySize | int | 否 | 打散的物品數量,預設值為請求的 size 大小 |
Conditions | []FilterParamConfig | 否 | 打散規則條件,使用者屬性符合一定條件下才能走打散規則。具體條件設定,可以參考條件匹配 Operator 樣本。這裡的條件是根據 user 的屬性來設定的,需要設定 Domain = user |
ExcludeRecalls | []string | 否 | 需要排除多樣性排序的召回 id 列表 |
DiversityRules | json array | 是 | 打散規則,可以設定多條規則 |
| []string | 是 | 根據物品 item 的哪些屬性進行打散 |
| int | 是 | 控制相同維度物品出現的次數,上面描述的 k 值 |
| int | 否 | 視窗大小, 上面描述的 n 值 |
| int | 否 | 視窗內重複的次數, 上面描述的 m 值 |
| int | 否 | 多樣性規則所佔的權重 |
ExclusionRules | json array | 否 | 排除規則,把合格某些物品在相應的位置上排除 |
| []int | 是 | 物品的輸出位置,從1開始。如果介面裡請求size=10,位置就是1,2,3...10 |
| []FilterParamConfig | 是 | 規則條件。具體條件設定,可以參考條件匹配 Operator 樣本。主要針對物品的屬性設定。 |
ExploreItemSize | int | 否 | 預設情況下,如果候選集第一個物品不符合打散規則時,會繼續搜尋,直至全部搜尋完成。此參數控制搜尋的候選集數量,如果超過此值,不再搜尋 |
排除規則和搜尋深度的樣本參考如下
對於tag=t1合格item不應出現在1,2,3,4的輸出位置上,1,2,3,4出現的物品還是要符合打散規則,但不能是tag=t1。
{
"Name": "DiversityRuleSort",
"SortType": "DiversityRuleSort",
"DiversityRules": [
{
"Dimensions": [
"tag"
],
"WindowSize": 5,
"FrequencySize": 1
}
],
"ExclusionRules": [
{
"Positions": [
1,2,3,4
],
"Conditions": [
{
"Name": "tag",
"Domain": "item",
"Type": "string",
"Value": "t1",
"Operator": "equal"
}
]
}
],
"ExploreItemSize" : 200
}在搜尋物品滿足多樣性規則時,在預設情況下,只有當物品滿足所有規則時,才會輸出。如果任何一條多樣性規則不滿足時,就會搜尋下一個物品,直至找到滿足規則的物品。如果候選集中所有的物品都不滿足所有規則,那麼就會選取最開始的搜尋物品進行輸出。
目前還提供一種策略,就是給多樣性規則上增加權重,如果候選集中所有的物品都不滿足所有規則時,會選擇物品滿足規則權重之和最大的那個進行輸出(如果有多個物品滿足的話,選擇位置最靠前的物品)。
帶有權重的配置參考如下:
{
"Name": "DiversityRuleSort",
"SortType": "DiversityRuleSort",
"DiversityRules": [
{
"Dimensions": [
"tag"
],
"WindowSize": 5,
"FrequencySize": 1,
"Weight": 1
},
{
"Dimensions": [
"category"
],
"WindowSize": 3,
"FrequencySize": 1,
"Weight": 3
}
],
"ExclusionRules": [
{
"Positions": [
1
],
"Conditions": [
{
"Name": "tag",
"Domain": "item",
"Type": "string",
"Value": "t1",
"Operator": "equal"
}
]
}
]
}DPPSort
DPP多樣性打散演算法參考資料:《基於行列式點過程的推薦多樣性提升演算法的直觀理解》。
前提條件:使用DPP演算法的前提是已經有了item裡的embedding向量,而且這個embedding向量能夠表示 item 本身的內容,embedding的相似性能夠表示item內容層面的相似性,而不是其他層面(如行為)的相似性。舉例如下:
建議:item圖片embedding/文本描述資訊的embedding/類目、屬性等靜態item內容組合得到embedding
不建議:基於使用者行為資料訓練模型得到的embedding
本質上,想要打散的維度一定要能夠在embedding裡反映出來。比如,我們希望推薦列表在商品價格這個維度有一些多樣性,那麼在訓練模型得到embedding向量時就一定要有價格特徵,否則就無法達到我們預期的效果。
配置樣本:
{
"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
}
}
]
}DPPConf
欄位名 | 類型 | 是否必填 | 描述 |
Name | string | 是 | 自訂 sort 名稱 |
DaoConf | DaoConfig | 是 | 配置Hologres相關資訊 |
TableName | string | 否 | holo中 item的embedding向量表表名;當沒有配置EmbeddingHookNames時必填 |
TableSuffixParam | string | 否 | 不為空白時,表示需要去PAI-Rec |
TablePKey | string | 否 | embedding向量表的主鍵 |
EmbeddingColumn | string | 否 | embedding向量表的向量欄位名 |
EmbeddingSeparator | string | 否 | embedding向量的分隔字元,預設為英文逗號 |
Alpha | float | 是 | DPP演算法用來平衡相關性和多樣性的參數;值越大越偏向於相關性 |
CacheTimeInMinutes | int | 否 | embedding向量緩衝在記憶體的時間,預設值:360 |
EmbeddingHookNames | []string | 否 | 產生item embedding的函數名, 需要提前註冊好 |
NormalizeEmb | string | 否 | 是否需要對embedding向量做L2 normalize;如果產生embedding時已經做了L2 normalize則不需要再做,否則需要配置為true |
WindowSize | int | 否 | 多樣性演算法的翻滾視窗大小;只保證視窗內的item列表的多樣性;預設值為10 |
EmbMissedThreshold | float | 否 | 當缺失embedding的item佔比高於該值時報錯,預設值為0.5 |
FilterRetrieveIds | []string | 否 | 指定不需要調用DPP模組的item列表,如冷啟動item |
EnsurePositiveSim | string | 否 | 是否需要保證基於embedding計算的item相似性是正值,預設值:true |
CandidateCount | int | 否 | 打散候選集的大小,預設為所有進入重排階段的item數量,可以設定為一個更小的數量,限制候選集為原來Top N個item |
AbortRunCount | int | 否 | 若進入重排階段的item數量小於這個值,則當前請求不做打散,預設值:0 |
MinScorePercent | float | 否 | 只有在item的最大值歸一化後的排序分大於該值時,當前item才有資格被打散模組透出,預設值:0 |
SSDSort
SSD多樣性打散演算法參考資料:《提升推薦結果的多樣性:MMR/DPP/SSD原理剖析》。
前提條件:使用SSD演算法的前提是已經有了item裡的embedding向量,而且這個embedding向量能夠表示 item 本身的內容,embedding的相似性能夠表示item內容層面的相似性,而不是其他層面(如行為)的相似性。舉例如下:
建議:item圖片embedding/文本描述資訊的embedding/類目、屬性等靜態item內容組合得到embedding
不建議:基於使用者行為資料訓練模型得到的embedding
本質上,想要打散的維度一定要能夠在embedding裡反映出來。比如,我們希望推薦列表在商品價格這個維度有一些多樣性,那麼在訓練模型得到embedding向量時就一定要有價格特徵,否則就無法達到我們預期的效果。
配置樣本:
{
"SortConfs": [
{
"Name": "SSDSort",
"SortType": "SSDSort",
"SSDConf": {
"Name": "SSDSort",
"DaoConf": {
"AdapterType": "hologres",
"HologresName": "geeko_rec"
},
"TableName": "item_embedding_metric_learning",
"TablePKey": "item_id",
"EmbeddingColumn": "embedding",
"Gamma": 0.25,
"UseSSDStar": true,
"NormalizeEmb": "false",
"MinScorePercent": 0.1,
"CandidateCount": 200,
"WindowSize": 5
}
}
]
}SSDConf
欄位名 | 類型 | 是否必填 | 描述 |
Name | string | 是 | 自訂sort名稱 |
DaoConf | DaoConfig | 是 | 配置hologres相關資訊 |
TableName | string | 否 | holo中 item的embedding向量表表名;當沒有配置EmbeddingHookNames時必填 |
TableSuffixParam | string | 否 | 不為空白時,表示需要去PAI-Rec |
TablePKey | string | 否 | embedding向量表的主鍵 |
EmbeddingColumn | string | 否 | embedding向量表的向量欄位名 |
EmbeddingSeparator | string | 否 | embedding向量的分隔字元,預設為英文逗號 |
Gamma | float | 是 | SSD演算法用來平衡相關性和多樣性的參數;值越大越偏向於多樣性 |
UseSSDStar | bool | 否 | 是否開啟SSD論文中提到的最佳化演算法,預設值:false,建議開啟 |
CacheTimeInMinutes | int | 否 | embedding向量緩衝在記憶體的時間,預設值:360 |
EmbeddingHookNames | []string | 否 | 產生item embedding的函數名, 需要提前註冊好 |
NormalizeEmb | string | 否 | 是否需要對embedding向量做L2 normalize;如果產生embedding時已經做了L2 normalize則不需要再做,否則需要配置為true |
WindowSize | int | 否 | 多樣性演算法的滑動視窗大小;只保證視窗內的item列表的多樣性;預設值為5 |
EmbMissedThreshold | float | 否 | 當缺失embedding的item佔比高於該值時報錯,預設值為0.5 |
FilterRetrieveIds | []string | 否 | 指定不需要調用SSD模組的item列表,如冷啟動item |
EnsurePositiveSim | string | 否 | 是否需要保證基於embedding計算的item相似性是正值,預設值:true |
CandidateCount | int | 否 | 打散候選集的大小,預設為所有進入重排階段的item數量,可以設定為一個更小的數量,限制候選集為原來Top N個item |
AbortRunCount | int | 否 | 若進入重排階段的item數量小於這個值,則當前請求不做打散,預設值:0 |
MinScorePercent | float | 否 | 只有在item的最大值歸一化後的排序分大於該值時,當前item才有資格被打散模組透出,預設值:0 |
多路召回重排(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"
]
}
]
}
]
}除了使用召回名稱來匹配條目進行過濾,還可以使用條件過濾篩選出 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"
}
]
}
]
}
]
}欄位名 | 類型 | 是否必填 | 描述 |
Name | string | 是 | 自訂 sort 名稱 |
SortType | string | 是 | 重排類型,固定值: MultiRecallMixSort |
RemainItem | bool | 否 | 是否保留所有的item , 比如有 500 個 item 需要處理,但我們一次請求假設有 30 個, 當為 false 情況下, item 數量只會保留混排的結果, 當為 true 情況下, 剩餘的 item 也保留下來,不過在 30 item 結果的後面。 這樣後續還可以再對接 sort 進行進一步控制處理 |
MixSortRules | json array | 是 | 打散規則,可以設定多個 |
| string | 是 | 混排策略,枚舉值:random_position/fix_position
|
| []int | 否 | fix_position 的情況下,需要指定 Positions。 Positions 的位置從 1 開始 |
| string | 否 | fix_position 的情況下,通過 item 的屬性欄位擷取 Postion。Positions 和 PositionField 衝突,只能設定其中一項 |
| int | 否 | 數量的絕對值。 |
| float | 否 | 混排物品數量佔比,只有MixStrategy=random_position 時設定,有效值為 0 ~ 1, 具體數量通過 請求的Size * NumberRate 算出 |
| []string | 否 | 召回的名稱,可以設定多個,設定多個的情況下,共用配置,但是具體哪個召回,不固定,順序由進入到此 Sort 的位置決定 |
| []FilterParamConfig | 否 | 符合匹配條件的物品進行混排。具體條件設定,可以參考條件匹配 Operator 樣本。 |
如何使用
重排配置和召回配置類似,配置好後,提供一個分情境使用的SortNames,SortNames是一個 Map[string]object結構,其中key是情境,每個情境對應一組重排策略
{
"SortNames": {
"${scene_name}": [
"ItemRankScore"
]
}
}${scene_name} 為情境名,如果多個情境想使用同一份配置,則使用"default"。
ItemRankScore:此參數為在SortConfs中定義的重排的自訂名稱。