PAI-Rec使用示例

PAI-Rec是一款基于Go的在线推荐服务引擎的框架,您可以基于此框架快速搭建在线推荐服务,也可以定制化进行二次开发。本文为您介绍如何在DataScience集群上使用PAI-Rec搭建一个简单的在线推荐服务,实现U2I召回和特征加载。

背景信息

PAI-Rec框架内容如下:

  • 集成Go http Server,提供路由注册功能,方便开发Restful API。

  • 包含推荐引擎的Pipeline流程,里面预定义了多种召回、过滤、排序策略,内置访问阿里云EAS服务。

  • 包含多种数据源的加载,支持Hologres、MySQL、Redis、Tablestore(OTS)和Kafka等。

  • 基于灵活的配置描述推荐流程。

  • 集成轻量级A/B Test实验平台。

  • 支持简单易用的扩展点,方便自定义操作。

更多框架信息,请参见PAI-Rec文档

前提条件

  • 已创建DataScience集群,并且选择了PairecEngine和PostgreSQL服务,详情请参见创建集群

  • 通过SSH方式连接集群,详情请参见登录集群

操作流程

  1. 步骤一:数据准备

  2. 步骤二:加载配置

  3. 步骤三:推荐测试

步骤一:数据准备

因为要实现U2I召回和特征加载,所以需要准备相应的召回表和特征表。

  1. 单击preparedata_mysql.sql,下载示例文件。

    该文件会帮您创建db_pairecdemo数据库及以下数据表:

    • 召回表:t_recall,包含字段user_id,表示用户ID,字段item_ids表示对应要召回的物品ID。

    • user特征表:t_userfeature,包含字段user_id和若干特征字段。

    • item特征表:t_itemfeature,包含字段item_id和若干特征字段。

    重要

    示例中的库、表和字段信息会在之后的推荐引擎配置中用到。其中召回表的结构定义是约定好的,不能随意更改配置。更多配置详情请参见配置总览

  2. 执行以下命令,获取MySQL服务的IP地址和端口。

    kubectl -n bitnami get svc mysql
  3. 使用MySQL客户端连接服务,执行preparedata_mysql.sql文件。

    说明

    数据库root账号的默认密码为emr-datascience。

步骤二:加载配置

PAI-Rec推荐引擎的具体Pipeline流程由配置定义,目前配置支持启动时加载config配置文件和通过配置中心热加载两种方式,本示例为通过配置中心热加载的方式。

配置中心也一同部署在DataScience上。

  1. 执行以下命令,获取端口。

    kubectl -n pairec get svc pairec-experiment -o jsonpath='{.spec.ports[0].nodePort}'
  2. 访问http://<header1节点的IP地址>:<端口>链接,登录配置中心。

    默认用户名和密码均为admin。

    说明

    <端口>为步骤1获取到的。

  3. 新增配置。

    1. 在左侧导航栏,选择服务配置 > 推荐引擎配置

    2. 推荐引擎配置页面,单击新增

    3. 新增配置对话框中,填写配置名称和配置内容,选择运行环境。

      add_config

      参数

      描述

      配置名称

      填写为pairec_config

      DataScience上部署的PAI-Rec推荐引擎,默认使用日常环境下名称为pairec_config的配置。因此这里的配置名称设为pairec_config,运行环境设为日常环境。

      运行环境

      选择日常环境

      配置内容分为以下几部分:

      • 数据源配置

        {
          // ...
          "MysqlConfs": {  // mysql 配置
              "pairec-mysql": { // 自定义名称
                "DSN": "root:emr-datascience@tcp(mysql.bitnami)/db_pairecdemo?parseTime=true&loc=Asia%2FShanghai"
              }
            },
          // ...
        }

        如果默认配置中没有MysqlConfs,新增即可。名称您可以自定义,会在之后用到。数据库设为之前数据准备中创建的db_pairecdemo。

      • 召回配置

        {
          // ...
            "RecallConfs": [
                {
                    "Name": "user2item_recall",
                    "RecallType": "UserCustomRecall",
                    "ItemType": "video",
                    "RecallCount": 500,
                    "DaoConf": {
                        "AdapterType": "mysql",
                        "MysqlName": "pairec-mysql",
                        "MysqlTable": "t_recall"
                    }
                }
            ],
          // ...
          "SceneConfs": {
            "default_scene": {
              "default": {
                "RecallNames": [
                  "user2item_recall"
                ]
              }
            }
          },
          // ...
        }

        需要在场景配置中启用配置好的user2item_recall。其中,涉及的参数如下表所示。

        参数

        描述

        RecallType

        填写为UserCustomRecall ,表示使用U2I的召回方式。

        RecallCount

        填写为500,表示最多召回500个item。

        AdapterType

        填写为mysql,表示使用MySQL数据源。

        MysqlName

        填写为pairec-mysql,表示使用上文中配置的数据源- pairec-mysql。

        MysqlTable

        填写为t_recall,表示召回表名称为t_recall。

      • 特征配置

        {
          // ...
          "FeatureConfs": {
            "default_scene": {
              "AsynLoadFeature": true,
              "FeatureLoadConfs": [
                {
                  "FeatureDaoConf": {
                    "AdapterType": "mysql",
                    "MysqlName": "pairec-mysql",
                    "FeatureKey": "user:uid",
                    "UserFeatureKeyName": "user_id",
                    "MysqlTable": "t_userfeature",
                    "UserSelectFields": "c1,c14,c15,c16,c17,c18,c19,c20,c21",
                    "FeatureStore": "user"
                  },
                  "Features": [
                  ]
                },
                {
                  "FeatureDaoConf": {
                    "AdapterType": "mysql",
                    "MysqlName": "pairec-mysql",
                    "ItemFeatureKeyName": "item_id",
                    "FeatureKey": "item:id",
                    "MysqlTable": "t_itemfeature",
                    "ItemSelectFields": "item_id,app_category,app_domain,app_id,banner_pos,device_conn_type,device_id,device_ip,device_model,device_type,hour,site_category,site_domain,site_id",
                    "FeatureStore": "item"
                  },
                  "Features": [
                  ]
                }
              ]
            }
          }
          // ...
        }

        其中,涉及的参数如下表所示。

        参数

        描述

        AdapterType

        填写为mysql,表示使用MySQL数据源。

        MysqlName

        填写为pairec-mysql,表示使用上文中配置的数据源。

        MysqlTable

        填写为t_recall,表示召回表名称为 t_recall。

        UserFeatureKeyName

        用于指定特征表查询条件中的字段名。

        ItemFeatureKeyName

        FeatureKey

        用于指定从哪里获取特征表查询条件中的字段值。

        UserSelectFields

        用于指定查询哪些特征。

        ItemSelectFields

        FeatureStore

        用于指定将查询得到的特征存到哪里。

  4. 完成配置后,单击确定

  5. 保存配置后,单击配置操作列的发布

    发布配置,引擎会自动加载设置好的配置。release

步骤三:推荐测试

PAI-Rec引擎推荐接口为/api/rec/feed,访问此接口即可进行推荐测试(需要获取引擎服务地址)。

参数

描述

类型

是否必选

示例

uid

用户ID。

String

10****

size

获取item数量。

Integer

10

scene_id

场景ID。

String

feed

category

类目。

String

features

上下文特征。

JSON Map

{"age":20,"sex":"male"}

debug

打印更多的日志。

BOOL

true

您可以通过以下命令获取引擎端口,然后http://<header1节点的IP地址>:<端口>即为服务地址。

kubectl -n pairec get svc pairec-engine -o jsonpath='{.spec.ports[0].nodePort}'

假设服务地址为http://127.0.0.1:32204,则可以使用curl工具进行访问和测试。

curl http://127.0.0.1:32204/api/rec/feed -d '{"uid":"10****", "size":2, "debug":true}'
说明

因为召回和特征都配置在default_scene,即默认场景下,所以此处无需指定scene_id。

当返回如下信息时,表示流程执行成功。如果推荐结果有问题或有其他需求,可以通过日志分析排查推荐流程,详情信息请参见日志分析

{
  "code": 200,
  "msg": "success",
  "request_id": "16dda535-9d7f-4bbb-aaa9-dc7199f9f6e8",
  "size": 2,
  "items": [
    {
      "item_id": "200001",
      "score": 0,
      "retrieve_id": "user2item_recall"
    },
    {
      "item_id": "200002",
      "score": 0,
      "retrieve_id": "user2item_recall"
    }
  ]
}

日志分析

如果推荐结果有问题或有其他需求,可以通过日志分析排查推荐流程。

  1. 执行以下命令,获取部署的PAI-Rec引擎的pod名称。

    kubectl get po -n pairec

    返回信息如下所示。

    # NAME                                        READY   STATUS    RESTARTS   AGE
    # pairec-engine-9669c98fd-w9828               1/1     Running   0          2d4h
  2. 执行以下命令,打印pod日志。

    kubectl logs pairec-engine-9669c98fd-w9828 -n pairec

    一次推荐流程的日志示例如下所示。

    I1230 08:36:04.103712       6 log.go:13] [INFO] requestId=16dda535-9d7f-4bbb-aaa9-dc7199f9f6e8  event=begin     uri=/api/rec/feed       address=10.244.0.0:39088        body={"uid":"10****", "size":2, "debug":true}
    I1230 08:36:04.103814       6 logger.go:18] [ERROR]     scene:default_scene, not found the scene info
    I1230 08:36:04.103828       6 log.go:13] [INFO] requestId=16dda535-9d7f-4bbb-aaa9-dc7199f9f6e8,uid=100001,scene_name=default_scene,exp_id=
    I1230 08:36:04.106789       6 log.go:13] [INFO] requestId=16dda535-9d7f-4bbb-aaa9-dc7199f9f6e8  module=UserCustomRecall name=user2item_recall   count=3 cost=2
    I1230 08:36:04.106805       6 log.go:13] [INFO] requestId=16dda535-9d7f-4bbb-aaa9-dc7199f9f6e8  module=recall   cost=2
    I1230 08:36:04.106815       6 log.go:13] [INFO] requestId=16dda535-9d7f-4bbb-aaa9-dc7199f9f6e8  module=Filter   cost=0
    I1230 08:36:04.109738       6 log.go:13] [INFO] requestId=16dda535-9d7f-4bbb-aaa9-dc7199f9f6e8  module=LoadFeatures     cost=2
    &{100001  map[c1:1005 c14:2035 c15:30 c16:25 c17:234 c18:2 c19:4 c20:1002 c21:3 uid:10****] {{0 0} 0 0 0 0}}
    I1230 08:36:04.109810       6 log.go:13] [INFO] requestId=16dda535-9d7f-4bbb-aaa9-dc7199f9f6e8  module=rank     cost=0
    &{200001  0 user2item_recall video [] {{0 0} 0 0 0 0} map[app_category:07d7df22 app_domain:7801e8d9 app_id:ecad2386 banner_pos:0 device_conn_type:0 device_id:a99f214a device_ip:9d046c7f device_model:9a45a8e8 device_type:1 hour:21 recall_name:user2item_recall recall_score:0 site_category:3e814130 site_domain:7687a86e site_id:5b08c53b user2item_recall:0] map[]}
    &{200002  0 user2item_recall video [] {{0 0} 0 0 0 0} map[app_category:07d7df22 app_domain:7801e8d9 app_id:ecad2386 banner_pos:0 device_conn_type:66 device_id:a99f214a device_ip:9d046c7f device_model:9a45a8e8 device_type:23 hour:21 recall_name:user2item_recall recall_score:0 site_category:3e814130 site_domain:7687a86e site_id:5b08c53b user2item_recall:0] map[]}
    I1230 08:36:04.109973       6 log.go:13] [INFO] requestId=16dda535-9d7f-4bbb-aaa9-dc7199f9f6e8  event=end       uri=/api/rec/feed       cost=6

    展示了Pipeline各个模块的执行情况。其中,count代表结果数量, cost代表花费时间。加载的特征也会打印出来。