4.3.2 为用户生成推荐
有了4.3.1节中计算出的topN最相似的标的物,下面来说明一下怎么为用户生成个性化推荐。生成个性化推荐有两种工程实现策略,一种是看成矩阵的乘积,另外一种是根据4.2.2节中的公式来计算,这两种方法本质上是一样的,只是工程实现上不一样。下面分别讲解这两种实现方案。
1.通过矩阵相乘为用户生成推荐
在用户行为矩阵中,第i行第j列的元素代表了用户i对标的物j的偏好/评分,我们将该矩阵记为An×m,其中n是用户数,m是标的物数。图4-5中的矩阵是标的物之间的相似度矩阵,我们将它记为Sm×m,这是一个方阵。An×m和Sm×m其实都是稀疏矩阵,我们通过计算这两个矩阵的乘积(Spark上是可以直接计算两个稀疏矩阵的乘积的),最终的结果矩阵就可以方便用来为用户推荐了:Rn×m=An×m*Sm×m。其中的第i行(ri1,ri2,ri3,…,rim)代表的是用户i对每个标的物的偏好得分,我们从这个列表中过滤掉用户操作过的标的物,然后按照得分从高到低降序排列取topN就是最终给用户的推荐。
2.通过计算公式为用户生成推荐
标的物相似度矩阵Sm×m是稀疏矩阵,最多有m×N个非零元素(因为每个标的物只保留N个最相似的标的物),一般N取几十或者上百规模的数值,m如果是十万或者百万量级,存储空间在1GB左右(例如,如果m=106,N=100,相似度为双精度浮点数,那么Sm×m中非零元素占用的空间为106×100×8Byte≈763MB),那么完全可以通过广播的形式将Sm×m广播到每个Spark计算节点中。先将相似矩阵转化为如图4-6的Map结构,再广播出去,方便利用公式计算相似度。
图4-6 标的物的topN相似列表利用Map数据结构来存储
图4-7 为每个用户计算topN推荐
有了标的物之间的相似度Map,为用户计算推荐的过程就可以基于用户行为RDD来实现,在每个Partition中,针对每个用户u计算u与每个标的物之间的偏好度(利用4.2.2节中基于标的物的协同过滤公式),再取topN就可得到该用户的推荐结果。由于用户行为采用了RDD来表示,所以整个计算过程可以分布式进行,每个Partition分布在一台服务器上进行计算。具体的计算逻辑可以用如图4-7所示的代码片段来实现。
到这里,基于Spark平台处理离线协同过滤算法的工程实现方案就讲完了。该实现方案强依赖于Spark的数据结构及分布式计算函数,可能在不同的计算平台上(比如Flink、TensorFlow等)具体的实现方式会不一样,但是基本思路和原理是一样的,有兴趣并且平时使用这些平台的读者可以在这些计算平台上独自实现一下,算是对自己的一个挑战。