Callback 回调接口

回调接口

PAI-Rec包含内置的回调接口。回调接口主要用来记录推荐请求时刻的实时特征日志,包括请求参数、用户和物品的实时特征,可以用于后续的数据分析、离线模型训练或在线学习。

背景

实时特征是推荐中很重要的一环,包括实时统计特征和实时序列特征,尤其是用户实时序列特征。一般来说,增加实时特征能明显的提升推荐系统的指标效果。然而实时特征对准确性的要求很高,如通过离线卡时间窗口关联的方式(指通过离线日志反推在推荐时刻用户和物品的实时特征),由于很难估计系统各链路间的延时,很容易就出现特征不准确、特征穿越的问题,在召回和排序模型中加上这些不准确的特征得到适得其反的效果。

如何定义准确性?一个训练样本S_i(对应推荐请求R_i)中的实时特征,需要是推荐请求R_i时刻的user和item特征,因此最佳记录实时特征是在推荐请求打到推荐服务的时候,在算法计算推荐结果的同时,把requestId(请求标识)+user的实时特征+item的实时特征落入日志中(如datahub/kafka等),然后再同步到 MaxCompute(ODPS) 中。

image.png

接口定义

接口名称

/api/callback

请求参数

参数名称

参数类型

是否必须

参数说明

用例

scene_id

string

首页推荐

homepage

uid

string

用户注册ID

85578510

request_id

string

请求的唯一标识

d9cb1c8d***

features

json string

用户特征

{"age":25, "city":"beijing"}

item_list

json list

推荐的uid列表

[{"item_id":"99886867"}, {"item_id":"99888623"}]

request_info

json string

请求信息

{"recom_id":"12334234"}

请求样例

curl 'http://host/api/callback' -d '{"uid":"84603208","request_id":"d9cb1c8d-4d3f-491b-9ea3-380481dabde3","scene_id":"homepage","features":{"age":25, "city":"beijing"}, "item_list":[{"item_id":"113939841"},{"item_id":"113764910"}],"request_info":{"recom_id":"1111111"}}'

返回数据

{
 "code":200,
 "msg":"success",
}

字段

类型

描述

示例

code

integer

返回码标识

接口状态码,200成功

msg

string

提示信息

成功为success

回调配置

Callback 流程主要分两部分

  • 加载 user/item 特征,

  • 很多情况下如果使用 EasyRec 模型, item 特征是与模型绑定到一起的。 需要请求 easyrec 模型,拿到模型生成的 FG 特征

把上面的特征数据写入到消息队列(datahub) 中。

"CallBackConfs": {
  "home_feed": {
    "DataSource": {
      "Name": "pairec_callback_dh",
      "Type": "datahub"
    },
    "RankConf": {
      "RankAlgoList": [
        "ali_rnk_v2_woid_callback_public_v2"
      ],
      "ContextFeatures": [
        "none"
      ],
      "Processor": "EasyRec"
    }
  }
}
  • home_feed 是场景名称,针对哪个场景落日志

  • DataSource

    • Type 消息队列类型,目前支持 datahub

    • pairec_callback_dh datahub 的数据源名称, 在 DatahubConfs 能找到

  • RankConf 配置的模型信息,和正常的引擎服务的模型配置一样,如果没有模型产生的特征信息,可以不配置

数据源配置

  "DatahubConfs": {
    "pairec_callback_dh": {
      "Endpoint": "http://dh-cn-hangzhou-int-vpc.aliyuncs.com",
      "AccessId": "${AccessId}",
      "AccessKey": "${AccessKey}",
      "ProjectName": "<ProjectName>",
      "TopicName": "pairec_callback_log",
      "Schemas": [
        {
          "Field": "request_id",
          "Type": "string"
        },
        {
          "Field": "module",
          "Type": "string"
        },
        {
          "Field": "scene",
          "Type": "string"
        },
        {
          "Field": "request_time",
          "Type": "integer"
        },
        {
          "Field": "user_features",
          "Type": "string"
        },
        {
          "Field": "item_features",
          "Type": "string"
        },
        {
          "Field": "request_info",
          "Type": "string"
        },
        {
          "Field": "user_id",
          "Type": "string"
        },
        {
          "Field": "item_id",
          "Type": "string"
        },
        {
          "Field": "raw_features",
          "Type": "string"
        },
        {
          "Field": "generate_features",
          "Type": "string"
        },
        {
          "Field": "context_features",
          "Type": "string"
        }
      ]
    }
    }
重要

注:如果使用 PAI-Rec 控制台进行配置,为了保持安全性,${AccessId}与${AccessKey} 可以不用替换,引擎会自动替换。

在上面的配置中, topic name 可以不用手动创建, PAI-Rec 可以根据 topic name 及 schema 自动创建。

特征加载配置

配置参考 特征配置。这里不同一点就是场景名称 + _callback 作为特征加载的场景别名。

home_feed_callback  的场景名称是 home_feed + _callback 来的。

"FeatureConfs": {
  "home_feed_callback": {
    "AsynLoadFeature": true,
    "FeatureLoadConfs": [
      {
        "FeatureDaoConf": {
          "AdapterType": "hologres",
          "HologresName": "pairec-holo",
          "FeatureKey": "user:uid",
          "UserFeatureKeyName": "client_str",
          "HologresTableName": "dwd_ali_user_all_feature_v2_holo",
          "UserSelectFields": "*",
          "FeatureStore": "user"
        },
        "Features": [
          {
            "FeatureType": "new_feature",
            "FeatureName": "day_h",
            "Normalizer": "hour_in_day",
            "FeatureStore": "user"
          },
          {
            "FeatureType": "new_feature",
            "FeatureName": "week_day",
            "Normalizer": "weekday",
            "FeatureStore": "user"
          },
          {
            "FeatureType": "new_feature",
            "FeatureName": "rand_int_v",
            "Normalizer": "random",
            "FeatureStore": "user"
          }
        ]
      },
      {
        "FeatureDaoConf": {
          "AdapterType": "hologres",
          "HologresName": "pairec-holo",
          "FeatureKey": "user:uid",
          "UserFeatureKeyName": "client_str",
          "HologresTableName": "dwd_ali_user_table_v3_expo_static_feature_v2_holo",
          "UserSelectFields": "*",
          "FeatureStore": "user"
        }
      }
    ]
  }
}

日志格式

callback 请求数据包含一个 uid + item 列表。 很多请求下, user 的特征比较大,为了省空间,我们会把 user 特征和 item 特征分开落下来。

user 特征日志,包含下面数据

  • request_id 请求ID, callback 请求里获得

  • scene 场景名称,callback 请求里获得

  • request_time 请求时间

  • user_features user 特征, json string

  • user_id 用户ID标识

  • request_info 额外的请求信息, callback 请求里获得

  • module   固定值 user , 表明是 user 特征

item 特征日志,包含下面数据

  • request_id 请求ID, callback 请求里获得

  • scene 场景名称,callback 请求里获得

  • request_time 请求时间

  • module   固定值 item , 表明是 item 特征

  • item_id item ID 标识

  • user_id 用户ID标识

  • raw_features easyrec 模型返回raw features

  • generate_features easyrec 模型返回的 FG 之后的特征信息

  • context_features easyrec 模型返回的上下文特征

  • item_features item 特征, json string

若有收获,就点个赞吧