PAI-Rec 引擎已經內建了多個過濾模板,包括曝光過濾、狀態過濾、數量調整過濾等。
如何配置
過濾的配置對應配置總覽中的 FilterConfs,FilterConfs 是一個[]object 結構,可以定義多個過濾策略。
過濾公用配置一覽
每種召回配置,都會用到公用配置中的一部分,在此統一解釋,單獨的召回配置中則不再贅述。
配置樣本:
"FilterConfs":[
{
"Name":"",
"FilterType":"",
"Dimension":"",
"DaoConf":{},
"AdjustCountConfs":[{}],
"ItemStateDaoConf":{},
"FilterParams":[{}],
"DiversityDaoConf":{},
"FilterVal":{}
}
]欄位 | 類型 | 是否必填 | 描述 |
Name | string | 是 | 過濾的自訂名稱,可以在 FilterNames 中引用 |
FilterType | string | 是 | 引擎內建過濾類型,枚舉值,目前支援:
|
Dimension | string | 否 | item 的維度欄位 |
DaoConf | DaoConfig | 否 | 資料來源表的一些資訊 |
AdjustCountConfs | 否 | 優先順序數量調整過濾的配置 | |
ItemStateDaoConf | 否 | 狀態過濾的配置 | |
FilterParams | 否 | 上下文條件的配置 |
曝光過濾(User2ItemExposureFilter)
很多業務情境都需要曝光過濾來避免重複推薦,這裡的曝光過濾其實是偽曝光
偽曝光:因為即時日誌有延時等原因,我們並不能立刻知道哪些 item 被曝光,所以我們把Recommendation Engine返回的 item 列表作為偽曝光列表
目前常用的做法是 PAI-Rec 引擎進行偽曝光的讀寫,真實曝光需要客戶的即時日誌,通過 flink 這種Realtime Compute引擎寫入資料庫,然後被PAI-Rec 引擎消費。
不同資料來源的曝光過濾有以下幾個公用參數配置
欄位名 | 類型 | 是否必填 | 描述 |
Name | string | 是 | 自訂過濾名稱 |
FilterType | string | 是 | 過濾類型,固定值 User2ItemExposureFilter |
MaxItems | int | 是 | 擷取最近的條目批次數量,相當於 limit ${MaxItems}, MaxItems 這裡不是指的具體的 item 數量, 而是批次的概念,也就是說一次推薦請求算作是一次,和一次請求裡有多個具體的物料 item 無關 |
TimeInterval | int | 是 | 按照時間戳記取最近多長時間內的條目,單位秒 |
WriteLog | bool | 是 | 是否寫入曝光日誌 |
ClearLogIfNotEnoughScene | string | 否 | 對某個情境下曝光表中的資料進行刪除 |
GenerateItemDataFuncName | string | 否 | 構造寫入曝光表item資料的函數,為空白時,會使用 PAI-Rec內建的函數,內建函數只返回 item_id |
WriteLogExcludeScenes | []string | 否 | 哪些情境不進行曝光日誌的寫入 |
hologres
"FilterConfs" :[
{
"Name": "holo_exposure_filter",
"FilterType": "User2ItemExposureFilter",
"MaxItems": 100,
"TimeInterval": 172800,
"WriteLog": true,
"DaoConf":{
"AdapterType": "hologres",
"HologresName": "holo_info",
"HologresTableName": "exposure_history"
}
}
]DaoConf 配置說明
欄位 | 類型 | 是否必填 | 描述 |
AdapterType | string | 是 | 資料來源的類型,取值 hologres |
HologresName | string | 是 | 在資料來源配置(HologresConfs)中配置好的 holo 的自訂名稱,如資料來源配置中的 holo_info |
HologresTableName | string | 是 | 曝光表名稱 |
曝光表定義注意這裡可以 按照實際的情況設定 time_to_live_in_seconds 。
BEGIN;
CREATE TABLE "exposure_history" (
"uid" text NOT NULL,
"item" text NOT NULL,
"create_time" int4 NOT NULL,
PRIMARY KEY ("uid","create_time")
);
CALL SET_TABLE_PROPERTY('"exposure_history"', 'orientation', 'column');
CALL SET_TABLE_PROPERTY('"exposure_history"', 'clustering_key', '"uid","create_time"');
CALL SET_TABLE_PROPERTY('"exposure_history"', 'segment_key', '"create_time"');
CALL SET_TABLE_PROPERTY('"exposure_history"', 'bitmap_columns', '"uid","item"');
CALL SET_TABLE_PROPERTY('"exposure_history"', 'dictionary_encoding_columns', '"uid","item"');
CALL SET_TABLE_PROPERTY('"exposure_history"', 'time_to_live_in_seconds', '172800');
comment on table "exposure_history" is '曝光記錄表';
COMMIT;redis
"FilterConfs" :[
{
"Name": "redis_exposure_filter",
"FilterType": "User2ItemExposureFilter",
"MaxItems": 100,
"TimeInterval": 172800,
"WriteLog": true,
"DaoConf":{
"AdapterType": "redis",
"RedisName": "redis_info",
"RedisPrefix": "exposure_"
}
}
]DaoConf 配置說明
欄位 | 類型 | 是否必填 | 描述 |
AdapterType | string | 是 | 資料來源的類型,取值 redis |
RedisName | string | 是 | 在資料來源配置(RedisConfs)中配置好的 Redis 的自訂名稱,如資料來源配置中的 redis_info |
RedisPrefix | string | 否 | 曝光資料的 key 首碼,key = RedisPrefix + uid |
tablestore
"FilterConfs" :[
{
"Name": "ots_exposure_filter",
"FilterType": "User2ItemExposureFilter",
"MaxItems": 100,
"TimeInterval": 172800,
"WriteLog": true,
"DaoConf":{
"AdapterType": "tablestore",
"TableStoreName": "tablestore_info",
"TableStoreTableName": "exposure_history"
}
}
]DaoConf 配置說明
欄位 | 類型 | 是否必填 | 描述 |
AdapterType | string | 是 | 資料來源的類型,枚舉值,如 hologres、mysql、tablestore 等 |
TableStoreName | string | 是 | 在資料來源配置(TableStoreConfs)中配置好的 tablestore 的自訂名稱,如資料來源配置中的 tablestore_info |
TableStoreTableName | string | 是 | 曝光表名稱 |
曝光表定義如下:
生命週期:(使用者需要自訂,必須有一個明確的周期)
maxVersion: 1
欄位 | 類別 | 類型 | 說明 | 樣本 |
user_id | 主鍵 | string | 使用者唯一id | 10944750 |
auto_id | 主鍵 | integer | 自增列 | |
item_ids | 屬性 | string | item 唯一id 列表,多個以 ',' 分隔, 如果一次曝光可以包含多個 item_id 的話,可以插入一行資料即可 | 17019277,17019278 |
User2ItemCustomFilter
Hologres
使用者需要提供一個自訂的 user2item 的過濾表,進行資料過濾。過濾表一般是離線產出,例如每天淩晨匯總每個使用者過去15天看過的物品(即有曝光行為的物品),按照逗號分隔放在一個欄位item_ids中。
"FilterConfs" :[
{
"Name": "u2i_custom_filter",
"FilterType": "User2ItemCustomFilter",
"DaoConf": {
"AdapterType": "hologres",
"HologresName": "holo_info",
"HologresTableName": "u2i_custom_filter"
},
"ItemStateCacheSize": 10000,
"ItemStateCacheTime": 3600
}
]DaoConf 配置說明
欄位 | 類型 | 是否必填 | 描述 |
AdapterType | string | 是 | 資料來源的類型,固定值 hologres 。 |
HologresName | string | 是 | 在資料來源配置(HologresConfs)中配置好的 hologres 的自訂名稱,如資料來源配置中的 holo_info。 |
HologresTableName | string | 是 | 自訂曝光表名稱。 |
ItemStateCacheSize | int | 否 | 開啟緩衝的情況下,可以緩衝的條目數量。如果此值大於0, 預設會開啟緩衝。 |
ItemStateCacheTime | int | 否 | 開啟緩衝的情況下,緩衝條目的生命週期。預設值為 3600, 單位:秒。 |
表定義如下:
欄位 | 類別 | 類型 | 說明 | 樣本 |
user_id | 主鍵 | string | 使用者唯一id | 10944750 |
item_ids | 屬性 | string | item 唯一id 列表,多個以 ',' 分隔 | 17019277,17019278 |
TableStore(OTS)
使用者需要提供一個自訂的 user2item 的過濾表,進行資料過濾。
"FilterConfs" :[
{
"Name": "u2i_custom_filter",
"FilterType": "User2ItemCustomFilter",
"DaoConf":{
"AdapterType": "tablestore",
"TableStoreName": "tablestore_info",
"TableStoreTableName": "u2i_table"
}
}
]DaoConf 配置說明
欄位 | 類型 | 是否必填 | 描述 |
AdapterType | string | 是 | 資料來源的類型,固定值 tablestore |
TableStoreName | string | 是 | 在資料來源配置(TableStoreConfs)中配置好的 tablestore 的自訂名稱,如資料來源配置中的 tablestore_info |
TableStoreTableName | string | 是 | 自訂曝光表名稱 |
表定義如下:
欄位 | 類別 | 類型 | 說明 | 樣本 |
user_id | 主鍵 | string | 使用者唯一id | 10944750 |
item_ids | 屬性 | string | item 唯一id 列表,多個以 ',' 分隔 | 17019277,17019278 |
數量調整過濾(AdjustCountFilter)
簡單的調整數量,把召回數量隨機打散,然後保留需要控制的數量。
配置樣本:
"FilterConfs" :[
{
"Name": "adjust_count_filter",
"FilterType": "AdjustCountFilter",
"ShuffleItem": true,
"RetainNum": 500
}
]欄位名 | 類型 | 是否必填 | 描述 |
ShuffleItem | string | 是 | 是否打散 |
RetainNum | string | 是 | 打散之後保留的數量 |
優先順序數量調整過濾(PriorityAdjustCountFilter)
優先順序過濾可以對各路召回進行數量控制,每路召回都會根據召回的 score 進行排序
配置樣本:
"FilterConfs" :[
{
"Name": "priority_adjust_count_filter",
"FilterType": "PriorityAdjustCountFilter",
"AdjustCountConfs" :[
{
"RecallName" :"recall_1",
"Count" :125,
"Type" : "accumulator"
},
{
"RecallName" :"recall_2",
"Count" :250,
"Type" : "accumulator"
},
{
"RecallName" :"recall_3",
"Count" :400,
"Type" : "accumulator"
}
]
}
]欄位名 | 類型 | 是否必填 | 描述 |
Name | string | 是 | 自訂的過濾名稱 |
FilterType | string | 是 | 過濾類型,固定值 PriorityAdjustCountFilter |
RecallName | string | 是 | 召回源名稱 |
AdjustCountConfs | json array | 是 | 優先順序配置 |
| int | 是 | 此路召回限制的數量 |
| string | 否 | Type 限制類型,枚舉值:accumulator 或 fix。 accumulator 為累加限制。
fix 為固定限制:
|
狀態過濾(ItemStateFilter)
我們經常需要對於召回的資料,進行狀態過濾。item 的狀態有可能會即時變動的,一般會有專有的表格儲存體 item 狀態。 此過濾流程需要即時擷取 item 狀態資訊,然後進行過濾。
hologres
"FilterConfs" :[
{
"Name": "ItemStateFilter",
"FilterType": "ItemStateFilter",
"ItemStateDaoConf":{
"AdapterType": "hologres",
"HologresName": "",
"HologresTableName": "",
"ItemFieldName" : "",
"WhereClause": "",
"SelectFields" :""
},
"ItemStateCacheSize": 50000,
"ItemStateCacheTime": 3600,
"FilterParams" :[]
}
]如果item的狀態不經常變化,可以配置緩衝選項。
欄位名 | 類型 | 是否必填 | 描述 |
ItemStateCacheSize | int | 否 | 要緩衝數量。 |
ItemStateCacheTime | int | 否 | 緩衝的時間,單位:秒。 |
ItemStateDaoConfig 定義如下:
欄位名 | 類型 | 是否必填 | 描述 |
AdapterType | string | 是 | 資料來源的類型,枚舉值,如 hologres、mysql、tablestore 等 |
HologresName | string | 是 | 在資料來源配置(HologresConfs)中配置好的 holo 的自訂名稱,如資料來源配置中的 holo_info |
HologresTableName | string | 是 | holo 中 item 狀態表的表名 |
ItemFieldName | string | 是 | item 狀態表的主鍵 |
WhereClause | string | 否 | 條件過濾語句 |
SelectFields | string | 是 | 需要擷取的欄位 |
FilterParams 定義如下:
"FilterParams" :[
{
"Name" : "publicStatus",
"Type" : "int",
"Operator" : "equal",
"Value" : 0
},
{
"Name" : "state",
"Type" : "int",
"Operator" : "equal",
"Value" : 1
},
{
"Name" : "checkStatus",
"Type" : "int",
"Operator" : "not_equal",
"Value" : 2
},
{
"Name" : "norec",
"Type" : "int",
"Operator" : "not_equal",
"Value" : 1
}
]欄位名 | 類型 | 是否必填 | 描述 |
Name | string | 是 | 特徵名 |
Domain | string | 否 | 特徵所屬,枚舉值:user/item |
Operator | string | 是 | 操作符,支援 equal、not_equal、in, greater , greaterThan , less, lessThan |
Type | string | 是 | 特徵的類型 |
Value | object | 是 | 條件值 |
註:WhereClause 和 FilterParams都可以過濾,WhereClause 是在查詢的時候過濾,FilterParams是在本地過濾。
具體的 Operator 的使用,可以參考附錄。
CompletelyFairFilter
根據召回條目的 score 進行排序,然後公平的從每一路召回擷取資料
"FilterConfs" :[
{
"Name": "CompletelyFairFilter",
"FilterType": "CompletelyFairFilter",
"RetainNum": 500
}
]DimensionFieldUniqueFilter
和 UniqueFilter 不同, 根據 item 的某個欄位進行去重過濾
"FilterConfs" :[
{
"Name": "DimensionFieldUniqueFilter",
"FilterType": "DimensionFieldUniqueFilter",
"Dimension":""
}
]欄位名 | 類型 | 是否必填 | 描述 |
Name | string | 是 | 自訂的過濾名稱。 |
FilterType | string | 是 | 過濾類型,固定值DimensionFieldUniqueFilter。 |
Dimension | string | 是 | item屬性欄位,根據這個欄位進行去重。如果 item 的這個屬性欄位為空白,則會保留這個item 。 |
UniqueFilter
唯一性過濾,保證 item id 是唯一的,如果兩路召回包含同一個 item id,哪路召回先返回,取哪一路的 item id。
無需配置,可直接在 FilterNames 中引用。
如何使用
過濾配置和召回配置類似,配置好之後,提供一個分情境使用的 FilterNames,FilterNames 是一個 Map[string]object 結構,其中 key 是情境,每個情境對應一組過濾策略
"FilterNames": {
"default": [
"UniqueFilter"
]
}default 為情境名,如果情境沒有顯式的配置,則使用 "default" 的配置。
UniqueFilter: 此參數為在 FilterConfis 中定義的過濾的自訂名稱。
附錄
條件匹配 Operator 樣本
equal (相等 ==)
{
"Name" : "publicStatus",
"Type" : "int",
"Operator" : "equal",
"Value" : 0
}not_equal (不等於 !=)
{
"Name" : "checkStatus",
"Type" : "int",
"Operator" : "not_equal",
"Value" : 2
}greater (大於 >)
{
"Name" : "checkStatus",
"Type" : "int",
"Operator" : "greater",
"Value" : 2
}greaterThan (大於等於 >=)
{
"Name" : "checkStatus",
"Type" : "int",
"Operator" : "greaterThan",
"Value" : 2
}less (小於 <)
{
"Name" : "checkStatus",
"Type" : "int",
"Operator" : "less",
"Value" : 2
}lessThan (小於等於 <=)
{
"Name" : "checkStatus",
"Type" : "int",
"Operator" : "lessThan",
"Value" : 2
}in (與數組中的某個條目匹配)
{
"Name" : "state",
"Type" : "int",
"Operator" : "in",
"Value" : [2, 4, 6]
}string 類型
{
"Name" : "state",
"Type" : "string",
"Operator" : "in",
"Value" : ["success", "ok"]
}