过滤配置¶
过滤的配置与召回的配置是类似的。具体的过滤配置定义放在 FilterConfs 。FilterNames 提供分场景(scene) 的配置,每个 scene 对应一组过滤名称。如果场景没有显式的配置,则走 default 场景配置。
FilterConfs 支持曝光过滤(User2ItemExposureFilter), 状态过滤(ItemStateFilter),数量调整(PriorityAdjustCountFilter, AdjustCountFilter)。
{
"FilterConfs" :[
{
"Name": "UserExposureFilter",
"FilterType": "User2ItemExposureFilter",
"MaxItems": 100,
"TimeInterval": 172800,
"WriteLog": true,
"DaoConf":{
"AdapterType": "hologres",
"HologresName": "pai-holo",
"HologresTableName": "exposure_history"
}
},
{
"Name": "AdjustCountFilter",
"FilterType": "AdjustCountFilter",
"RetainNum": 400
}
],
"FilterNames":{
"default": ["UniqueFilter", "UserExposureFilter", "AdjustCountFilter", "FeedStatusFilter"],
"home_feed": ["UniqueFilter", "UserExposureBloomFilter", "AdjustCountFilter", "FeedStatusFilter"]
}
}
曝光过滤¶
Hologres¶
在召回之后,大部分场景需要有曝光过滤的需求。对于同一个用户,当推荐服务返回推荐条目后,这些条目需要记录下来,再次请求推荐时,会过滤掉之前的推荐条目。我们这里会单独用表来记录请求过的数据。
holo 表定义, 注意这里可以 按照实际的情况设置 time_to_live_in_seconds 。
BEGIN;
CREATE TABLE "exposure_history" (
"uid" text NOT NULL,
"item" text NOT NULL,
"create_time" int4 NOT NULL
);
CALL SET_TABLE_PROPERTY('"exposure_history"', 'orientation', 'column');
CALL SET_TABLE_PROPERTY('"exposure_history"', 'distribution_key', '"uid"');
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;
FilterConf 配置
{
"Name": "UserExposureFilter",
"FilterType": "User2ItemExposureFilter",
"MaxItems": 100,
"TimeInterval": 172800,
"WriteLog": true,
"DaoConf":{
"AdapterType": "hologres",
"HologresName": "pai-holo",
"HologresTableName": "exposure_history"
}
}
Name 是自定义的名称
FilterType 过滤类型,固定值 User2ItemExposureFilter
MaxItems 获取最近的条目批次数量,相当于 limit ${MaxItems}, MaxItems 这里不是指的具体的 item 数量, 而是批次的概念,也就是说一次推荐请求算作是一次,和一次请求里有多个具体的物料 item 无关
TimeInterval 按照时间戳取最近的过滤条目。 create_time >= ${current_time - TimeInterval }
WriteLog 是否写入曝光日志。
DaoConf 曝光表的定义
状态过滤¶
很多时候,对于召回的数据,需要进行过滤状态。item 的状态有可能会实时变动的,一般会有专有的表存储 item 状态。 此过滤流程需要实时获取 item 状态信息,然后进行过滤。过滤可以有两种方式去做,一个是拼装好 sql 直接去数据库查,另一个就是只是把需要过滤的字段从数据库中取出来,然后在本地进行过滤。对于召回量数据比较大的情况,第二种反而会有更好的性能,并且能降低数据库的压力。
通用配置如下:
{
"Name": "ItemStateFilter",
"FilterType": "ItemStateFilter",
"ItemStateDaoConf":{
"AdapterType": "hologres",
"HologresName": "",
"HologresTableName": "",
"ItemFieldName" : "",
"WhereClause": "",
"SelectFields" :""
},
"FilterParams" :[]
}
Name 是自定义的名称
FilterType 过滤类型,固定值 ItemStateFilter
ItemStateDaoConf 是状态表的配置
AdapterType 数据源类型,比如 hologres, redis, tablestore
HologresName 数据源名称,当数据源是 hologres 时设置
HologresTableName 数据表名称
ItemFieldName 表中,对应 item id 的 字段名称,一般是主键
WhereClause 过滤条件语句,设置,会采用第一种查询方式,不设置,可以设置 FilterParams 本地的过滤条件进行过滤
SelectFields 需要获取哪些字段
FilterParams 本地的过滤条件,支持多种op
一个具体的例子参考如下:
{
"Name": "ItemStateFilter",
"FilterType": "ItemStateFilter",
"ItemStateDaoConf":{
"AdapterType": "hologres",
"HologresName": "holo-test",
"HologresTableName": "vvarticle.smart_video_status",
"ItemFieldName" : "\"smartVideoId\"",
"SelectFields" :"\"publicStatus\", state, \"checkStatus\", norec"
},
"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
}
]
}
FilterParams 中的 Operator 还支持 in, greater , greaterThan , less, lessThan 操作符。
状态过滤也支持TableStore(ots) 存储,通用配置如下:
{
"Name": "ItemStateFilter",
"FilterType": "ItemStateFilter",
"ItemStateDaoConf":{
"AdapterType": "tablestore",
"TableStoreName": "",
"TableStoreTableName": "",
"ItemFieldName" : "",
"SelectFields" :""
},
"FilterParams" :[]
}
数量调整过滤¶
在召回阶段,一般的数量在 千级别以上,但是在排序(Rank)阶段,会由于性能的因素,会把数量控制在 百级别。那么就需要数量调整,数量调整也包含在过滤阶段,目前提供如下形式的数量调整。
AdjustCountFilter¶
简单的调整数量,把召回数量随机打散,然后保留需要控制的数量。配置如下
{
"Name": "AdjustCountFilter",
"FilterType": "AdjustCountFilter",
"ShuffleItem": true,
"RetainNum": 500
}
Name 是自定义的名称
FilterType 过滤类型,固定值 AdjustCountFilter
RetainNum 需要保留的召回数量
ShuffleItem 是否对 item 进行随机排序后再返回, 默认 true。 如果不想改变 item 位置,设置为 false
PriorityAdjustCountFilter¶
优先级过滤可以对各路召回进行数量控制,每路召回都会根据召回的 score 进行排序。
{
"Name": "PriorityAdjustCountFilterV5",
"FilterType": "PriorityAdjustCountFilter",
"AdjustCountConfs" :[
{
"RecallName" :"U2IRecallV3V10",
"Count" :125,
"Type" : "accumulator"
},
{
"RecallName" :"SwingU2IRecallV3V10",
"Count" :250,
"Type" : "accumulator"
},
{
"RecallName" :"VideoVectorRecallV10",
"Count" :400,
"Type" : "accumulator"
},
{
"RecallName" :"UserGroupHotRecallV10",
"Count" :450,
"Type" : "accumulator"
},
{
"RecallName" :"UserGlobalHotRecallV10",
"Count" :500,
"Type" : "accumulator"
}
]
}
Name 是自定义的名称
FilterType 过滤类型,固定值 PriorityAdjustCountFilter
AdjustCountConfs 具体的数量控制配置
RecallName 召回源名称
Count 限制的数量
Type 限制类型, accumulator 为累加限制。比如 U2IRecallV3V10 数量最多控制在 125, SwingU2IRecallV3V10 最多控制在 250, SwingU2IRecallV3V10 召回数量就是 250 - 125, 当 U2IRecallV3V10 不足 125 时, SwingU2IRecallV3V10 也会尽量补齐到 250 ,依次类推。