看过视频网站的小伙伴们有好奇过每次打开app出现的内容究竟是怎么来的呢,为啥自己的和别人的会不一样呢,接下来就开始我们的解密之旅。
当我们注册一个网站会员的时候多半会让我们挑选自己感兴趣的频道,这样系统会根据我们的选择为我们推荐相关的内容了。不过不注册会员好像每次也能看见和自己看过内容相关的推送呢,这就是根据观看历史来推荐了,后台根据ip或相关范围也可以推荐到你相关的内容,最明显的例子就是可能在华南地区打开app和在华北地区打开app你看到的内容会有一些差异了。
我们暂且将推荐系统后端分为实时推荐、离线推荐、统计推荐和相似性推荐。
要推荐,首先得有数据才能计算出推荐啥,所以我们可以最起码的有基础的电影信息表,用户评分表和电影标签表。
统计推荐
当新用户进来时,如果没有选择任何喜好可以直接推荐基于统计推荐的。
统计推荐包括历史热门电影统计、近期热门电影统计、电影平均评分统计和各类别TopN统计推荐。这一部分内容直接根据已有数据写计算任务交给ariflow等定时执行即可。
离线推荐
既然收集了用户对电影的评分,那我们就可以用用户评分表来计算用户推荐矩阵了,这里可以用ALS训练推荐模型。然后用模型得到给每个用户推荐哪些电影,得到形式如
uid | recs |
---|---|
001 | [(mid,score) ( mid, score )…] |
的结果,将其写道DB中,业务服务读取,在这里可以去重,过滤掉用户已经看过的。至于为什么ALS就能训练出来这个结果,可以参看文章最后。
在ALS训练出来的模型,会有一个prodcutfeatures ,将这两个productFeatures做笛卡尔积后两两取预选相似度,然后再
过滤掉不怎么相似的,比如小于0.5的,就可以得到电影的相似度矩阵了。
实时推荐
与离线推荐相比,实时推荐重点在于快,而不是结果准确,最基本的思想就是用户最近k次的喜好可能都是类似的,那么可以将用户最近k次评分存在redis中,然后利用离线推荐中得到的电影相似度矩阵,取这k个评分的电影的相似度,再分乘以用户的评分就可以得到用户这次评分后的新的实时推荐电影了,再与之前的实时推荐结果合并后更新,放在DB供业务数据读取就可以了。
基于内容的推荐
其实最容易想到的就是基于内容的推荐了,既然有了电影标签,也有了标签表,就可以用特征提取,比如TF-IDF来获取每个电影的特征了,然后选择与指定电影特征相似的电影即可,也就是常见的item-CF 。
附 什么是隐语义模型,这玩意儿为什么可以用来做推荐
什么是协同过滤,顾名思义,协同就是找相似,过滤就是筛选出符合要求的。
协同过滤可以分为
- User-CF ,找到与用户A的特征相似的用户B,C… 把这些用户的喜欢的推荐给A
- iterm-CF, 与User-CF类似,不同的是根据相似商品来找用户
- modles-based,有矩阵分解、关联算法、神经网络等。
models-based 中的矩阵分解就是将形如
mid1 | mid2 | mid3 | |
---|---|---|---|
uid | 12 | 10 | |
udi2 | 23 | ||
uid3 | 12 |
这样的表分解成两个矩阵 U 和 I 相乘,并用RMSE作为损失函数用交替最小二乘法求解损失函数最小时得到的U和I,将这U 和 I相乘得到一个将上图填充完成的矩阵,这样对每个用户推荐哪些电影就很容易选择了。至于其中的数学推导这里就不劝退式的展开了。 具体可以参考
《Large-scale Parallel Collaborative Filtering for the Netflix Prize》(als-wr原论文)
Spark mlib也有对应的实现。