天下武功,唯快不破,论推荐系统的「 实时性」

天下武功,唯快不破,论推荐系统的「 实时性」

这里是「王喆的机器学习笔记」的第二十一篇文章。周星驰著名的电影《功夫》里面有一句著名的台词——“天下武功,无坚不摧,唯快不破”。如果说推荐系统的架构是那把“无坚不摧”的“玄铁重剑”,那么推荐系统的实时性就是“唯快不破”的“柳叶飞刀”。 我们这篇文章就从推荐系统“实时性”的角度,谈一谈影响推荐系统实时性的有哪些因素?如何提高推荐系统的实时性?

为什么说推荐系统的实时性是重要的?

在问为什么之前,要先问一下“是不是”。 为了证明推荐系统实时性和推荐系统效果的关系,Facebook曾利用GBDT+LR模型和单纯的树模型进行过实时性的实验。

图1 Facebook的模型实时性实验

图1中横轴代表的是模型训练结束到模型测试的时间间隔(天数),纵轴是损失函数Normalized Entropy。从图中可以看到,无论是GBDT+LR模型,还是单纯的树模型,损失函数都跟模型更新延迟有着正相关的关系。

直观一点,在用户使用个性化新闻应用时,用户的期望是更快找到与自己兴趣相符的文章;在使用短视频服务时,期待更快地“刷”到自己感兴趣的内容;在进行在线购物时,同样希望更快找到自己喜欢的商品。所有的推荐都突出一个“快”字,这就是推荐系统“实时性”作用的直观体现。

从专业的角度来说,推荐系统的实时性同样是至关重要的,主要体现在下面两个方面:

  1. 推荐系统的更新速度越快,越能够反应用户最近的用户习惯,越能够给用户进行越有时效性的推荐。
  2. 推荐系统更新的越快,模型更容易发现最新流行的数据pattern,越能够让模型反应找到最新的流行趋势。

这两个方面的原因也直接与影响推荐系统实时性的两大要素有关:

  1. 推荐系统「 特征」的实时性;
  2. 推荐系统「 模型」的实时性。

推荐系统“特征”的实时性

推荐系统特征的实时性指的是系统“实时”地收集推荐系统模型所需的输入特征,使推荐系统能够总是使用最新的特征进行预测和推荐。

举例来说,现在开发一个短视频推荐系统,某用户完整地看完了一个长度为10分钟的“羽毛球教学”视频上。那么毫无疑问该用户对于“羽毛球”这个主题是感兴趣的。系统希望在用户下次翻页的时候就继续推荐“羽毛球”相关的视频。但是由于系统特征的实时性不强,用户的观看历史无法实时反馈给推荐系统,导致推荐系统在得知该用户看过“羽毛球教学”这个视频的时候,已经半个小时之后了,此时用户已经离开该应用了。这就是一个推荐系统实时性差导致推荐失败的例子。

诚然,用户在下次开启该应用的时候,推荐系统可以利用上次的用户行为历史推荐“羽毛球”相关的视频,但该推荐系统毫无疑问丧失了最可能增加用户粘度的,增加用户留存度的时机。

那么如何增强“特征”的实时性呢?这里我简略画了一张推荐系统的主流技术架构图(图2),来说明影响“特征”实时性的三个主要阶段 。

图2 推荐系统数据流的技术架构图

客户端实时特征

客户端是最接近用户的环节,在经典的推荐系统中,经常利用客户端收集时间、地点、推荐场景等上下文特征,然后让这些特征随http请求一起到达服务器端,参与模型预测。但是客户端对于实时性的重要性,经常被忽视的一点是客户端还是能够实时收集session内用户行为的地方。

拿新闻类app来说,用户在同一session中,三分钟之内分别点击并阅读了三篇文章。这三篇文章对于用户的推荐结果来说是至关重要的,因为它们代表了用户的即时兴趣。如果采用传统的流计算平台,甚至分布式批处理计算平台,由于系统延迟问题,大概率无法在3分钟之内就把session内部的行为历史存储到特征数据库(比如redis)中,这就使这位用户的推荐结果不会马上受到session内部行为的影响。

如果客户端能够缓存session内部的行为,作为与上下文特征同样的实时特征传给推荐服务器,那么推荐模型就能够实时得到session内部行为特征,进行实时的推荐。这就是利用客户端实时特征进行实时推荐的优势所在。关于这个话题,感谢 @dragonfly 在讨论中分享的经验。

流处理平台的准实时特征处理

随着storm,spark streaming,特别是flink等一批非常优秀的流处理平台的日益成熟。利用流处理平台进行准实时的特征处理已经成为了当前推荐系统的标配。

所谓流处理平台,是将日志以流的形式进行mini batch处理的准实时计算平台。由于每次需要等待并处理一小批日志,流处理平台并非完全实时的平台,但优势是能够进行一些简单的统计类特征的计算,比如一个物品在该时间窗口内的曝光次数,点击次数,一个用户在该时间窗口内的点击话题分布等等。

流处理平台计算出的特征可以立马存入特征数据库供推荐系统模型使用,虽然无法实时的根据用户行为改变用户结果,但分钟级别的延迟基本可以保证用户的推荐结果准实时地受到之前行为的影响。

分布式批处理平台的全量特征处理

随着数据最终到达以HDFS为主的分布式存储系统。Spark等分布式计算平台终于能够进行全量特征的计算和抽取。在这个阶段着重进行的还有多个数据源的数据join和以及延迟信号的合并。

比如用户的曝光、点击、转化数据往往是在不同时间到达HDFS的,有些游戏类应用的转化数据的延迟甚至高达几个小时,因此也只有在这一阶段才能够进行全量特征以及相应label的抽取和合并。也只有在全量特征准备好之后,才能够进行更高阶的特征组合的工作。这往往是无法在客户端和流处理平台平台上进行的。

分布式批处理平台的计算结果的主要用处有两个:

  1. 模型训练和离线评估
  2. 特征保存入特征数据库,供推荐模型inference使用。

当然,由于数据从产生到完全进入HDFS,再加上spark的计算延迟,这一过程的总延迟往往达到小时级别,已经无法进行所谓的“实时”推荐。更多的是对用户下次登陆时进行更好的推荐。

再谈推荐系统特征实时性的重要性

在构建推荐系统时,推荐系统的实时性往往是容易被我们忽视的因素。我们一味聚焦在一些离线指标上,希望在离线指标中发现改进模型结构的线索,殊不知线上特征实时性的改动就会产生原强于模型结构的影响。

但特征实时性再强,影响的范围也仅限于当前用户,要想快速抓住系统级别的全局的数据变化和新产生的数据pattern,就必须加强“模型”的实时性,下篇文章我们就介绍一下增强推荐系统“模型”实时性的主要方法。

大家也可以关注我的微信公众号「 王喆的机器学习笔记」wangzhenotes),回复 “模型实时性”查看下一篇文章。


按惯例给大家出两个典型的应用场景,大家思考一下这两个场景是如何实现的?是不是特征实时性最直接的体现:

1、在使用抖音时,随着你划过不同的短视频,你的兴趣快速收敛,几乎是实时地被抖音的推荐引擎捕捉,这是如何做到的?

2、在刷知乎的timeline时,随着你点击不同的答案,知乎的推荐也是几乎实时的改变着推荐列表,比如你点击了我的这篇文章,在你下次更新知乎timeline时,立马会有更多推荐系统相关文章出现,这是如何做到的?

当然,如果有字节跳动和知乎的同学现身说法,那是再好不过的。

最后欢迎大家关注我的微信公众号:「 王喆的机器学习笔记」wangzhenotes),跟踪计算广告、推荐系统等机器学习领域前沿。

想进一步交流的同学也可以通过公众号加我的微信一同探讨技术问题,谢谢。


本文亦收录在我的新书「深度学习推荐系统」中,这本书系统性地整理、介绍了专栏中所有的重点内容,如果您曾在「王喆的机器学习笔记」中受益,欢迎订阅,谢谢知友们的支持!

编辑于 03-24

文章被以下专栏收录