6.5.2 工程实现
上面讲完了实时训练矩阵分解算法的原理,下面讲讲怎样为用户做推荐,以及在工程上怎样实现为用户做实时推荐。
首先,我们简单描述一下怎样为用户进行推荐。具体为用户生成推荐的流程如图6-4,一共包含5个步骤。下面分别对每个步骤的作用加以说明。
图6-4 为用户实时生成推荐的流程
步骤1:获取种子视频集
种子视频是用户最近偏好(有过隐式反馈的)的视频,或者用户历史上有偏好的视频,分别代表了用户的短期和长期兴趣,这些行为直接从用户的隐式反馈行为中获取,只要前端对用户的操作行为进行了埋点,通过实时日志收集就可以获取。
步骤2:获取候选推荐视频集
一般来说,全量视频是非常巨大的,为用户实时推荐时不可能对全部视频分别计算用户对每个视频的偏好预测,因此我们会选择一个较小的子集作为候选集(这就是召回的过程),我们需要确保该子集很大概率上是用户可能喜欢的,先计算出用户对该子集中每个视频的偏好评分,再将预测评分最高的topN最终推荐给用户。
该论文通过选取步骤1中种子视频集的相似视频作为候选集,因为种子视频是用户喜欢的,对于它的相似视频,用户喜欢的概率也相对较大,所以这种方式的召回是有理论依据的。视频相似度会在后面介绍。
步骤3:获取特征向量
从分布式存储中获取用户和候选集视频的特征向量,该向量会用于计算用户对候选集中视频的偏好得分。特征向量的计算会在后面介绍。
步骤4:视频偏好预测
有了步骤3中的用户和视频特征向量,就可以用公式来计算该用户对每个候选集中视频的偏好度。
步骤5:候选集排序
步骤4计算出了用户对候选集中每个视频的偏好度,那么按照偏好度降序排列,就可以将topN的视频推荐给用户了。
当用户在前端进行隐式反馈操作时,用户的行为通过实时日志流到达实时推荐系统,该系统根据上面5个步骤为每个用户生成推荐结果。用户最近及历史行为、视频相似度、用户特征向量、视频特征向量都存储在高效的分布式存储中(如Redis、HBase、CouchBase等分布式NoSQL),这5个步骤都是非常简单的计算,因此可以在几十毫秒之内为用户生成个性化推荐。最终的推荐结果可以插入(更新到)分布式存储引擎中,当用户在前端请求推荐结果时,推荐Web服务器从分布式存储引擎中将该用户的推荐结果取出,并组装成合适的数据格式,返回到前端展示给用户。
用户最近及历史行为、视频相似度、用户特征向量、视频特征向量这些数据(为了方便后面指代,这些数据我们统称为支撑数据)是通过另外一个后台实时程序来计算及训练的,此过程跟推荐过程解耦,互不影响。在腾讯的文章中,支撑数据是利用Storm来实现的,除了用Storm外,用Spark Streaming或者Flink等流式计算引擎都是可以的,只是具体的实现细节不一样。为了不拘泥于一种计算平台,下面结合笔者个人的经验及理解,讲解怎样生成这些在推荐过程中依赖的数据。这里抽象出实现的一般逻辑,具体生成数据的流程见图6-5,这里通过4个算子来完成数据生成过程,下面分别对这4个算子的功能加以说明。
图6-5 计算个性化推荐依赖的用户播放历史、视频相似度、用户 & 视频特征向量
算子1:提取用户隐式反馈行为
基于用户在前端对视频的隐式反馈,通过收集用户行为日志做ETL,将四元组(用户id、视频id、隐式操作、操作时间)插入消息队列(如Kafka),供后面的算子使用。第15章会专门介绍怎么样收集用户行为数据,想提前了解的读者可以查阅。
算子2:生成用户反馈历史并存于分布式key-value存储中
基于消息队列中的用户行为四元组,将用户隐式反馈行为存于分布式存储中。注意,这里可以保留用户最近的操作行为及过去的操作行为,并且也可以给不同时间点的行为不同的权重,以体现用户的兴趣是随着时间衰减的。
算子3:计算视频之间的相似度
这里先说一下计算两个视频相似度的计算公式,腾讯的这篇文章是通过如下3类因子的融合来计算两个视频最终的相似性的。
1)基于视频特征向量的相似性:。
2)基于视频类型的相似性,其中type(i)是视频i的标签类型(如搞笑、时政等)。
如果两个视频类型一样,类型相似性为1,否则为0。
3)时间衰减因子,其中Δt是sim(i,j)最近一次更新时间与当前时间之差,ξ是控制衰减速率的超参数。
有了上面3类因子,可通过如下融合公式最终得到i和j的相似度:
当新事件发生(即有新用户行为产生)时,基于该事件中的视频i,在分布式存储中就可以根据计算两个视频相似度的公式,结合用户行为历史更新该视频与其他视频构成的视频对的相似度(i:<i#j:sim>),同时更新与视频i相似的topN的视频,具体计算实时topN相似度的方法可以参考第4章的方案,在腾讯的这篇论文中没有细讲具体实现细节。
算子4:生成用户和视频的特性向量
这一步是整个算法的核心,它利用上面的腾讯矩阵分解算法中的实时更新逻辑来训练用户和视频的特性向量。具体训练过程是,当用户有新的操作行为从管道中流过来时,从分布式存储中将该用户和对应的视频的特征向量取出来,采用算法中的公式更新特征向量,更新完成后再插入分布式存储中。如果该用户是新用户或者操作的视频是新入库的视频,那么就可以随机初始化用户或视频特征向量,并插入分布式存储中,待后续该用户或者包含该视频的新操作流进来时继续更新。
通过上面的介绍,我们大致知道怎么样利用流式计算引擎来做实时的矩阵分解并给用户做个性化推荐了。到此,矩阵分解的离线及实时算法实现方案都讲完了,下面我们梳理一下矩阵分解算法可行的应用场景。