Gorse推荐系统指南:收集用户反馈

1,836 阅读6分钟

Github: Gorse推荐引擎

在推荐系统中,数据是一切推荐结果的支撑,本文将简单介绍如何收集用户数据投递给Gorse推荐系统。推荐系统主要依赖用户和物品之间的行为反馈作为训练数据,训练数据的质量决定了推荐的质量。

用户、物品、反馈

推荐系统其实是一个比较复杂系统,但是为了最大化复用性,Gorse将推荐系统中的数据源归纳为三种实体的集合:用户、物品和反馈。

  • 用户: 用户由用户ID和描述该用户的标签构成,用户标签可以为空,但是标签信息有助于提升推荐系统推荐准确度。
type User struct {
    UserId    string
    Labels    []string
}
  • 物品: 物品由物品ID、物品时间戳和描述该物品的标签构成,时间戳和标签可以为空,同样标签信息有助于提升推荐系统推荐准确度,而时间戳用于判断物品新鲜程度。
type Item struct {
    ItemId    string
    Timestamp time.Time
    Labels    []string
}
  • 反馈: 一条反馈信息由用户ID、物品ID、反馈类型和反馈时间戳组成,用户ID、物品ID、反馈类型三元组要求在数据库中唯一。

反馈就是用户和物品之间产生的一些事件,可以是正向的或者负向的,例如分享、点赞等等都属于用户对物品的正向反馈,如果用户阅读之后没有进一步的正向反馈,那么认为用户对该物品的反馈是负向的,为了方便记录,Gorse并没有直接提供负向反馈的概念而提供了已读反馈的概念。如果用户查看了物品,那么记录一个已读反馈。接着,如果用户给了物品正反馈,那么已读反馈被正反馈覆盖。反之,如果用户没有给出正反馈,那么已读反馈视为负反馈。

type Feedback struct {
    FeedbackType string
    UserId       string
    ItemId       string
    Timestamp    time.Time
}

Gorse的服务节点提供了插入用户、物品和反馈的API,以及通过API获取给用户的推荐内容,详细的API介绍请参考RESTful API文档。

方法URL说明
POST/api/item插入物品
POST/api/user插入用户
POST/api/feedback插入反馈,保留原有反馈
PUT/api/feedback插入反馈,覆盖原有反馈

确定正反馈和已读反馈

在向Gorse推荐系统投递反馈之前,需要确定用户的哪些行为是正反馈,另外哪些行为是已读反馈。已读反馈比较容易确定,当用户看到了推荐的物品,即可记录为已读反馈。然而,正向反馈的确定更多取决于具体业务场景。对于抖音来说,用户如果点赞或者分享则可以认为是正反馈;对于哔哩哔哩来说,用户观看视频到达一定的完成度或者点赞、分享、收藏则认为是正反馈。总结以下,正反馈和已读反馈的确定遵循以下规则:

  • 已读反馈: 用户看到了物品。
  • 正向反馈: 希望用户去做的动作。

举个例子,如果Gabe Newell要基于Gorse搭建一个Steam游戏推荐系统,那么可以将点击进入游戏介绍页面作为已读反馈(游戏列表页面信息过少,不能判断用户已读),然后将加入愿望单、加入购物车等动作作为正反馈,在配置文件中设置如下。

# 加入愿望单或者购物车
positive_feedback_types = ["wish_list","cart"]

# 阅读了游戏介绍页面
read_feedback_types = ["read"]

插入正向反馈

对于正反馈,在用户进行相关操作的时候,即可插入正反馈,其中时间戳就是当前的时间点。

curl -X POST "http://127.0.0.1:8088/api/feedback" \
    -H "accept: application/json" \
    -H "Content-Type: application/json" \
    -d '[ { "FeedbackType": "read", "ItemId": "10086", "Timestamp": "2021-10-24T06:42:20.207Z", "UserId": "jack" }]'

插入已读反馈

对于已读反馈,时间戳除了可以记录已读时间之外,还可以用来设置推荐结果的生命周期。

主动插入

正向反馈能够在用户采取行为的时候插入到推荐系统中,而已读反馈则需要应用去探测用户的“已读”行为。各类应用展示推荐结果的方法各不相同,但是可以总体归为两类:

  • 全屏幕视图: 最典型的应用就是抖音,当唯一一项内容展示给用户之后,即可认为用户“已读”。也就是应用可以在将推荐内容展示给用户的时候就能向推荐系统写入一条“已读”反馈,已读内容将不再对用户展示。 image.png
  • 信息流视图: 最典型的应用就是淘宝,当用户看了列表中的多项物品后,并不能认为“已读”。当推荐内容比较多的时候,用户的注意力并不能浏览完全部内容。并且,如果将信息流视图中将已读内容快速丢弃,会导致推荐内容消耗过快。因此,最好的解决方法就是当物品以信息流的形式展示给用户的时候,向推荐系统写入一个未来时间戳的已读反馈,当时间到达时间戳后,已读反馈才生效,已读的内容不再展示给用户。 image.png

自动插入

主动向推荐系统插入已读反馈要求应用能够准确捕捉用户浏览行为,这项任务对于移动端应用比较容易,但是对于简单的Web应用来说,捕捉用户的浏览是比较困难的。为了解决这个问题,Gorse获取推荐结果的API提供了writebacktypewrite-back-typewritebackdelaywrite-back-delay这两个参数。

  • 全屏幕视图: 获取一条推荐内容,并且写入“read”反馈,推荐内容之后不会再出现。
curl -X GET "http://172.18.0.3:8087/api/recommend/zhenghaoz?write-back-type=read&n=1" \
    -H "accept: application/json" \
    -H "X-API-Key: 19260817"
  • 信息流视图: 获取十条推荐内容,并且写入“read”反馈,时间戳为10分钟之后。在10分钟之后,这十条推荐内容才会被丢弃。
curl -X GET "http://172.18.0.3:8087/api/recommend/zhenghaoz?write-back-type=read&write-back-delay=10&n=10" \
    -H "accept: application/json" \
    -H "X-API-Key: 19260817"

推荐结果API的writebacktypewrite-back-typewritebackdelaywrite-back-delay这两个参数提供了非常方便的已读记录功能,当然如果希望已读反馈更加准确,应当由应用侧写入到推荐系统中。