召回配置
PAI-Rec 已经内置了几个召回模板,包括协同过滤(UserCollaborativeFilterRecall),向量召回(HologresVectorRecall),U2I 召回(UserCustomRecall)等等。召回配置在 RecallConfs 下面,是个列表,可以配置多个。
协同过滤
MySQL
CacheAdapter, CacheConfig,CachePrefix 是可选的,主要是用于缓存数据。如果要缓存数据,三个选项一定都要配置。目前支持两种形式的 cache , CacheAdapter 取值为 Redis
数据的获取支持多种数据源,通过 AdapterType 来标识。下面的配置是 MySQL 。
"RecallConfs" :[
{
"Name":"collaborative_filter",
"RecallType":"UserCollaborativeFilterRecall",
"RecallCount":1000,
"CacheAdapter":"redis",
"CacheConfig":"{\"host\":\"xxx.redis.rds.aliyuncs.com\", \"port\":6379,\"maxIdle\":10, \"password\":\"xxxx\"}",
"CachePrefix": "u_cf_",
"UserCollaborativeDaoConf": {
"Adapter":"UserCollaborativeMysqlDao",
"AdapterType":"mysql",
"MysqlName": "zqkd_article",
"User2ItemTable": "user_collaborative_list",
"Item2ItemTable": "item_collaborative_list"
}
}
]
Name 自定义的召回名称
RecallType 召回类型,固定值 UserCollaborativeFilterRecall
RecallCount 召回数量
CacheAdapter/CacheConfig/CachePrefix 缓存配置, 如果不需要缓存,可以不设置
UserCollaborativeDaoConf 协同过滤表的配置
MySQL 数据源的话,需要设置 Adapter = UserCollaborativeMysqlDao, AdapterType = MySQL
MysqlName 数据源名称,需要从 MysqlConfs 里找到
User2ItemTable U2I 表
Item2ItemTable I2I 表
hologres
{
"Name": "collaborative_filter",
"RecallType": "UserCollaborativeFilterRecall",
"RecallCount": 1000,
"CacheAdapter":"redis",
"CacheConfig":"{\"host\":\"xxx.redis.rds.aliyuncs.com\", \"port\":6379,\"maxIdle\":10, \"password\":\"xxxx\"}",
"CachePrefix": "u_cf_",
"UserCollaborativeDaoConf": {
"AdapterType": "hologres",
"HologresName": "holo-test",
"User2ItemTable": "user_collaborative_list",
"Item2ItemTable": "item_collaborative_list"
}
}
Name 自定义的召回名称
RecallType 召回类型,固定值 UserCollaborativeFilterRecall
RecallCount 召回数量
CacheAdapter/CacheConfig/CachePrefix 缓存配置。 如果不需要缓存,可以不设置
UserCollaborativeDaoConf 协同过滤表的配置
hologres 数据源的话,需要设置 AdapterType = hologres
HologresName数据源名称,需要从 HologresConfs 里找到
User2ItemTable U2I 表
Item2ItemTable I2I 表
这里目前需要两个表,表结构是固定的。
User2ItemTable 表
表字段 |
类型 |
字段说明 |
user_id |
string |
用户id, 保持唯一性 |
item_ids |
string |
用户浏览的 item id 列表。 支持形式: Itemid1,itemid2,itemid3 |
Item2ItemTable 表
表字段 |
类型 |
字段说明 |
item_id |
string |
item id , 保持唯一性 |
similar_item_ids |
string |
I2I 相似 item id 列表。 支持形式: Itemid1:score1,itemid2:score2,itemid3:score3 |
OTS(tablestore)
{
"Name": "collaborative_filter",
"RecallType": "UserCollaborativeFilterRecall",
"RecallCount": 1000,
"CacheAdapter":"redis",
"CacheConfig":"{\"host\":\"xxx.redis.rds.aliyuncs.com\", \"port\":6379,\"maxIdle\":10, \"password\":\"xxxx\"}",
"CachePrefix": "u_cf_",
"UserCollaborativeDaoConf": {
"AdapterType": "tablestore",
"TableStoreName": "",
"User2ItemTable": "user_collaborative_list",
"Item2ItemTable": "item_collaborative_list"
}
}
Name 自定义的召回名称
RecallType 召回类型,固定值 UserCollaborativeFilterRecall
RecallCount 召回数量
CacheAdapter/CacheConfig/CachePrefix 缓存配置。 如果不需要缓存,可以不设置
UserCollaborativeDaoConf 协同过滤表的配置
OTS 数据源的话,需要设置 AdapterType = tablestore
TableStoreName 数据源名称,需要从 TableStoreConfs 里找到
User2ItemTable U2I 表
Item2ItemTable I2I 表
也是需要两个表,表结构是固定的。
User2ItemTable 表
表字段 |
类型 |
字段说明 |
user_id |
string |
用户id, 保持唯一性, 主键 |
item_ids |
string |
用户浏览的 item id 列表。 支持形式: Itemid1,itemid2,itemid3 |
Item2ItemTable 表
表字段 |
类型 |
字段说明 |
item_id |
string |
item id , 保持唯一性, 主键 |
similar_item_ids |
string |
I2I 相似 item id 列表。 支持形式: Itemid1:score1,itemid2:score2,itemid3:score3 |
实时U2I2I 召回
获取数据的思路和协同过滤中的是一样的,只不过 U2I 的数据获取是通过 user 历史行为表实时算出来的。user 历史行为表实时是根据实时日志来同步更新的。这样的召回是实时的召回。
user 历史行为表格式如下
表字段 |
类型 |
字段说明 |
user_id |
string |
用户id, 保持唯一性, 主键 |
item_id |
string |
用户浏览的 item_id |
event |
string |
事件名称 |
play_time |
float |
事件发生时间长度,不存在的话,可以设置为0 |
timestamp |
int |
时间发生的时间戳,以秒为单位 |
I2I 表和协同过滤中的一样
Item2ItemTable 表
表字段 |
类型 |
字段说明 |
item_id |
string |
item id , 保持唯一性, 主键 |
similar_item_ids |
string |
I2I 相似 item id 列表。 支持形式: Itemid1:score1,itemid2:score2,itemid3:score3 |
hologres
user 历史行为表建表语句
BEGIN;
CREATE TABLE "sv_rec"."user_behavior_seq" (
"user_id" text NOT NULL,
"item_id" text NOT NULL,
"event" text NOT NULL,
"play_time" float8 NOT NULL,
"timestamp" int8 NOT NULL
);
CALL SET_TABLE_PROPERTY('"sv_rec"."user_behavior_seq"', 'orientation', 'column');
call set_table_property('table_name', 'distribution_key', '"user_id"');
CALL SET_TABLE_PROPERTY('"sv_rec"."user_behavior_seq"', 'clustering_key', '"user_id:asc","timestamp:desc"');
CALL SET_TABLE_PROPERTY('"sv_rec"."user_behavior_seq"', 'bitmap_columns', '"user_id","event"');
CALL SET_TABLE_PROPERTY('"sv_rec"."user_behavior_seq"', 'dictionary_encoding_columns', '"user_id:auto","item_id:auto","event"');
CALL SET_TABLE_PROPERTY('"sv_rec"."user_behavior_seq"', 'time_to_live_in_seconds', '2592000');
comment on table "sv_rec"."user_behavior_seq" is '用户实时行为序列';
comment on column "sv_rec"."user_behavior_seq"."user_id" is '用户id';
comment on column "sv_rec"."user_behavior_seq"."item_id" is 'item id';
comment on column "sv_rec"."user_behavior_seq"."event" is '事件类型';
comment on column "sv_rec"."user_behavior_seq"."play_time" is '阅读时长,播放时长';
comment on column "sv_rec"."user_behavior_seq"."timestamp" is '时间戳';
COMMIT;
召回配置如下:
{
"Name": "RealTimeEtrecRecall",
"RecallType": "RealTimeU2IRecall",
"RecallCount": 200,
"RealTimeUser2ItemDaoConf": {
"UserTriggerDaoConf": {
"AdapterType": "hologres",
"HologresName": "",
"HologresTableName": "sv_rec.user_behavior_seq",
"WhereClause": "from_page='p_personalzone' and refer='p_svhome'",
"Limit": 200,
"EventPlayTime": "e_sv_func_svplayback:5000;e_sv_func_svplayvslide:5000;e_sv_func_svplayend:5000",
"EventWeight": "e_sv_func_svplayback:1;e_sv_func_svplayvslide:2;e_sv_func_svplayend:3",
"WeightExpression": "(-0.2)*((currentTime-eventTime)/3600/24)"
},
"Item2ItemTable": "public.rec_sv_rebuild_etrec_i2i_result_holo"
}
}
Name 自定义召回名称
RecallType 召回类型, 固定值 RealTimeU2IRecall
Item2ItemTable I2I 表名称
UserTriggerDaoConf U2I 表的相关设置
AdapterType 数据源类型 hologres
HologresName 数据源名称
HologresTableName user 历史行为表名称
WhereClause 过滤条件, sql 中的 where 语句,没有的话,可以设置为空
Limit sql 中的 limit 大小
EventPlayTime 事件播放时间的过滤。可以针对每个事件,进行过滤。 e_sv_func_svplayback:5000 表示针对事件 e_sv_func_svplayback, play_time 的值必须大于 5000 , 不符合条件则被过滤掉。可以设置多个事件,以
;
分隔EventWeight 事件的权重, 可以定义每个事件的权重, 不设置的话,默认值为 1
WeightExpression 权重表达式。 以时间衰减来计算事件的权重。 currentTime 代码当前的时间戳, eventTime 代表行为表的里 timestamp。
向量召回
这里的向量召回是通过阿里云产品 hologres 来实现的。向量的数据都存在 hologres 表中,通过 sql 语句直接查询出来。
VectorDaoConf 记录了 user 向量从哪里获取
HologresVectorConf 记录了 item 向量从哪里获取
{
"Name": "graphsage_vector_recall",
"RecallType": "HologresVectorRecall",
"RecallCount": 100,
"VectorDaoConf" :{
"AdapterType": "hologres",
"HologresName": "pai-hologres",
"HologresTableName": "graphsage_user_embedding",
"KeyField": "user_id",
"EmbeddingField" :"emb"
},
"HologresVectorConf" :{
"VectorTable" :"graphsage_item_embedding",
"VectorEmbeddingField" :"emb",
"VectorKeyField" :"item_id"
}
}
U2I 召回
直接根据 user 中的uid 来找到对应的 item 列表。这里的表定义是约定好的。
{
"Name": "pai_user2item_newly",
"RecallType": "UserCustomRecall",
"RecallCount": 500,
"DaoConf" :{
"AdapterType": "hologres",
"HologresName": "pai-hologres",
"HologresTableName": "user_item_newly"
}
}
表定义
表字段 |
类型 |
字段说明 |
user_id |
string |
用户id, 保持唯一性 |
item_ids |
string |
item id 列表。 支持多种形式:1. Itemid1,itemid2,itemid3 2. Itemid1:recallid,itemid2:recallid 3. Itemid1:recallid:score,itemid2:recallid:score |
用户分组热门召回
按用户信息和context信息(例如设备类型)组合trigger
根据key的顺序用下滑线拼接成trigger_id
值为空对应"NULL"
包含Boundaries字段的Trigger需要进行离散化 --> (左开,右闭]区间,及边界以外区间
e.g. [20, 30, 40, 50] --> trigger对应 <=20, 20-30, 30-40,40-50, >50
用户年龄23,对应"20-30"
用户年龄空,对应"NULL"
用户年龄60,对应">50"
用户年龄19,对应"<=20"
表定义
表字段 |
类型 |
字段说明 |
trigger_id |
string |
trigger 信息, 需要动态组装 |
item_ids |
string |
item id 列表。 支持多种形式:1. Itemid1,itemid2,itemid3 2. Itemid1:recallid,itemid2:recallid 3. Itemid1:recallid:score,itemid2:recallid:score,举例:item_id1::score1,item_id2::score2,... |
holo表样例
trigger_id |
item_ids |
Male_<=20_IOS |
item_id1::score1,item_id2::score2,... |
Male_20-30_IOS |
item_id1::score1,item_id2::score2,... |
Male_20-30_IOS |
item_id1::score1,item_id2::score2,... |
Famale_30-40_Android |
item_id1::score1,item_id2::score2,... |
... |
... |
NULL_20-30_IOS |
item_id1::score1,item_id2::score2,... |
Male_NULL_IOS |
item_id1::score1,item_id2::score2,... |
NULL_NULL_IOS |
item_id1::score1,item_id2::score2,... |
RecallConf 配置举例
{
"Name":"UserGroupHotRecall",
"RecallType": "UserGroupHotRecall",
"RecallCount" :500,
"Triggers": [
{
"TriggerKey": "gender"
},
{
"TriggerKey": "age",
"Boundaries": [20,30,40,50]
},
{
"TriggerKey": "os"
}
],
"DaoConf":{
"AdapterType": "hologres",
"HologresName": "pai-holo",
"HologresTableName": "recall_group_hotness"
}
}
全局热门召回
Hologres
holo 表中只有一行数据,trigger_id=-1。
{
"Name":"UserGlobalHotRecall",
"RecallType": "UserGlobalHotRecall",
"RecallCount" :500,
"CacheAdapter": "localCache",
"CacheTime": 600,
"CacheConfig": "{\"defaultExpiration\":600, \"cleanupInterval\":600}",
"DaoConf":{
"AdapterType": "hologres",
"HologresName": "pai-holo",
"HologresTableName": "recall_global_hotness"
}
}
表定义
表字段 |
类型 |
字段说明 |
trigger_id |
string |
固定值为 -1 |
item_ids |
string |
item id 列表。 支持多种形式:1. Itemid1,itemid2,itemid3 2. Itemid1:recallid,itemid2:recallid 3. Itemid1:recallid:score,itemid2:recallid:score,举例:item_id1::score1,item_id2::score2,... |
场景召回配置
RecallConfs 定义了召回的配置。最终的目标是指定哪个场景需要哪些召回策略。场景用到的召回策略来源于两个方面,一个是 RecallConfs 的定义,再一个就是自定义召回,自定义召回通过 register 机制进行注册。
场景召回的配置在 SceneConfs 里。
{
"SceneConfs" :{
"home_feed": {
"default" : {
"RecallNames": ["HotRecall", "collaborative_filter", "article_wcf", "ColdRecall", "RevealBottomRecall"]
}
}
}
}
SceneConfs 下可以配置多个场景,场景下可以配置多个类目,RecallNames 包含了召回列表。