本文是笔者阅读《推荐系统实战》后的一篇读书笔记,包括了笔者的一部分浅显思考。书质量非常不错,有问题欢迎指正!
什么是好的推荐系统
推荐系统一般有两种:一种是预测用户评分,另外是给出TopN,但后者会更频繁更有用。因为预测分数并不能怎么样。“重点是他看了,而不是评价”。下面都以TopN为主。
衡量推荐系统有四个基本指标:
- 准确率:
- 召回率:
- 覆盖率:对长尾物品的挖掘能力,所有用户的推荐总列表,占所有商品的比例,可以看出,K越大,覆盖率一定越高
- 流行度:
更高级别的:
- 新颖度: 这会让人眼前一亮,但很难通过离线计算获得,通常都用用户问卷。
现在主流推荐算法都有马太效应:强者越强,弱者越弱,会造成基尼系数的进一步提升。
距离和基于图的算法
基于距离的算法
用户购买的物品,可以记做矩阵。就有了ItemCF和UserCF,即常用的协同过滤。简单说,购买了相似物品的用户越相似,被用户同时购买的商品更相似。
对大部分东西的热度曲线,都呈现长尾效应:指数曲线。占20%的物品占据了80%的流量。越是重度用户,越会关心那些冷门的信息。
UserCF的推荐更社会化, 反映了用户在小型团体中兴趣的程度;和自己相似的人喜欢的,自己也喜欢。 ItemCF的推荐更个性化,反映了用户自己的兴趣:一定会喜欢购买类似的商品。
算法看似简单,但都有共同的问题,比如物品和物品是不同的,新华字典的信息量肯定没有《机器学习》来得大;人和人也是不同的,一个书商购书行为,也和普通的文艺青年有所区别。因此,需要特别去调整频繁用户/物品的权重,避免污染整个数据集。
另外,如果物品特别多或更新频繁,就去更新用户矩阵。而若用户特别多,则可用物品矩阵。简而言之,没有最合适的方法,都需要根据具体业务场景来定义规则。
K值越大,需要考虑的用户和商品就越多,显然,对UserCF,可以提升覆盖率,但不一定能提升召回。对ItemCF, K越大会降低覆盖率(为什么?)。
选择一个合适的K很重要。ItemCF的好处是其可解释性。
基于隐语义的算法
简单说,如果用户之前喜欢科技类书籍,那么就可以给他打标签,科技,之后即可推荐科技类书籍。
但问题是:
- 不是所有的书籍都有准确的分类,比如数学or计算机
- 分类很难提供准确的粗细粒度
- 甚至不一定有合适的分类标签
这就是隐语义,可以通过类似聚类的方法,将Item做分类,但标签不一定是可解释的,也就是所谓的“隐”,即LFM。
LFM通过如下公式计算用户对某个商品的兴趣:
$Preference= p_u^Tq_i = sum_(p_(u,k))^(i_(k,u)) $
分为两步, 其中(P_(u,k)) 度量了用户u的兴趣和k个隐变量的关系, (q_(i,k)) 度量了k个隐变量和商品i的关系。类似传导。很像SVD分解后的S矩阵和D矩阵。
这基本上把它当成了打分的问题(分类),但是负样本从哪里来?一些网站可通过“踩”表达负向,但很多时候只有正向。 负向可通过采样实现,比较好的实践方法:
- 从热门,但用户却没有反馈的样本中抽取负样本
- 对每个用户,保证正负样本的平衡
之后即可通过SGD最小化均方误差(SGD简直万能)。LFM比ItemCF和UserCF效果都好,但样本稀疏时,可能效果就不如了。另外,提升负样本的比率可有效提升系统的准确率和召回率。
基于图的算法
ItemCF和UserCF都只考虑了一层关系,但朋友的朋友如果也喜欢一样东西是不是我也会喜欢它呢?基于图的算法,比那几种考虑的更多。当然,计算量也更大。
方法是随机游走,将i和u都看成图上的点,有一定的概率转移和停顿,则经过多次迭代,每个节点被访问到的概率会逐渐趋于定值。称作PersonalRank算法。
但是,计算量太大,方法就是求逆矩阵。
3. 推荐系统的冷启动问题
当系统刚刚建立,数据并不完全,因此很多计算无法实施,尤其是ItemCF。
两种解决办法:
用户相关
注册时提交喜好信息,构建成最适合分类的二叉树,从而快速确定用户的基本兴趣。
注册时提供基本信息,系统可根据性别/年龄和国籍来进行初步推荐。
商品相关
对商品进行分类,利用商品特征,做出关键词向量,开发线性分类器。向量空间模型的特点是简单容易实现,但却丢失了一些信息。 相比于协同过滤,它的性能低很多。
但是这也不一定,比如GitHub,可能会fork同一个作者的多个项目,因此将作者作为特征,可以非常强地模拟协同过滤。
LDA也可以对话题做出分类,这种方法比向量空间模型更为高级,但是其内部的数学原理,还需挖掘(待学习)。
另外是专家系统,通过专家对不同维度进行打标,解决冷启动,这也有很多成功的案例。如果item较少,这种方式是很可行的。
冷启动代表了一系列问题,处理它需要一定的经验。
4. 用户标签
先理清UGC的概念,是User Generated Content的简称。标签是一种常用的方法,便于解释,用户能够方便地为商品打标,提升用户互动。
一般来说,标签可以由系统自动产生(NLP),也可以由用户手工添加,包括以下类型:作者,主题,时间,评价,是否喜爱等。
基线算法
统计用户最常用的标签,对每个标签,统计被打过这些标签的最多的商品,然后把这些商品推荐给用户。
标签会随着系统发展,变得越来越多。因此相似的标签需要合并,不合理的标签要去掉,太过普遍的标签会被降权。
如果用户给的标签太少,则可以在已有的标签上,给出更多新的标签。
标签相当于是个纽带。同样标签也能被推荐,方法也很简单。
5. 利用上下文信息
时间上下文
用户在不同场景下,心情是不同的。因此行为和音乐肯定也有所区别。实时性非常重要,此时,推荐系统变成了时变系统。
当用户对某个物品发生了点击时,就会触发一次推荐的更新,这种实时回流非常重要。是如何实现的呢?
- 如何判断一个系统的时变速度
显然维基百科和youtube的物品时变速率大大不同。新闻比电影的时变性更强。判断系统时变性有两种方法,T天之内,每天和前一天该物品的特征向量求相似度数值,可以扫出一条曲线。
- 如何提高时变性
最简单的,在推荐列表中,一部分是推荐的,一部分是随机的。
当用户看过某件商品,就会对其做降权。很多推荐系统无法得到更多的回流数据,导致重复推荐。
每次都使用不同的推荐算法来推荐。
- 对时间增加权重
最近的行为,对这次的相似度贡献要比更早的行为更多。
当然,推荐系统要首先保证精度,再考虑推荐的实时性。
地点上下文
一些场景对地点很敏感,例如餐馆商场等。本地新闻也会提升用户的粘性。这个问题比较复杂,有一些方法能解决这个问题:
设计多层分类器,例如江苏南京用户,先对整体用户做推荐,再对中国用户推荐,再对江苏,最后是南京,几种模型进行叠加,最终生成结果。但问题是到分类树的枝杈时,数据已经非常稀疏了。
6. 推荐系统实例
基础结构
包括三个部分:UI,日志系统和推荐系统。
三个级别: 用户,特征,商品。先从用户生成特征,再通过特征找到商品。
三个步骤: 推荐,过滤,排序。
多个推荐系统可以进行投票,最终可以做推荐系统的推荐系统,按照不同用户的需求生成推荐
7. 对于新闻推荐算法的思考
新闻有其独特的特点: 不断有新文章进来,之后又不断过期。实时性很高。ItemCF似乎不可行。
用户会喜欢多个类目,但一旦热门新闻过来,门类反而不重要了。甚至一些观点认为,每天最热门的物品已经吸引了绝大多数用户的眼球,长尾物品很少得到用户关注。
而新闻本身的质量非常重要。通常好文章的阅读数远大于其他文章(长尾效应,二八原则)
如果没有社交信息,UserCF就也变得不可靠了。
需要对文章的作者提供适当的保护,否则马太效应明显。
拥有众多埋点行为可供参考,例如该页面停留时间,用户滑动行为,点击/点赞/踩。
8. 其他
从整本书,我们能够分析一些通用的思路。
通过向量可以计算相似度,用共现可计算关系。但是,需要对热门u或i做惩罚,TF/IDF是个很好的思路。它不仅能用于词汇,还能用于各种离散化的,对顺序无要求的系统中。
计算一个网络中多个节点的关系,可以用PersonalRank来实现,即随机游走。随机游走需要定义启动概率,一般是相同的。这种算法的好处,是能够评估横跨多个节点的弱关系。虽然图距离较远,但因为路径权重较大,很有可能距离比直接节点还要近。
推荐系统是与人打交道的系统,如何提升交互的质量非常重要,例如可解释性。系统设计人员需要对业务有深入的了解,例如电商推荐,商品的降价信息可能会极大地影响推荐的效果。但这个特征似乎被忽视了。
太过复杂的算法,效果可能不一定好,因为可能无法满足实时性要求。或是在工程上成本太高,反而抵消了复杂算法实现的效果。
为什么推荐系统会发布那么多论文,因为这里可变的参数实在太多了,而使用的环境又千变万化,上下文也会改变,非常适合大量的水论文。