什么是推荐系统
推荐系统的目的是在所有物品(商品、内容等)中寻找用户最可能感兴趣的部分物品,并推荐给他们。像在线零售的网站,他们会用花大力气构建推荐系统从而做到更精准的推荐,以提升物品的销量。
从数据来源上说,一般是通过用户的反馈得到,例如,用户观看电影后的评分、搜索的内容、购买的历史等,或者从其他地方得到一些关于用户和商品的好恶信息。
为什么我们需要推荐系统
推荐系统最终的目的是为了提升销量(电商)、用户体验(内容推荐等),他们一方面能方便用户更快的找到自己感兴趣的东西,另一方面也能给用户一些体验上的惊喜。
另一方面他们也能根据推荐内容留住用户,例如在邮件中列举一些用户感兴趣的内容以让他们回到自己的网站上进行浏览。
从用户角度上来说,用户可以感到自己被系统理解,系统知道自己想要什么,从而会在系统中有更多的行为,而这些行为又能反馈给推荐系统优化对用户的理解,形成正反馈,从而增加了用户的粘性。
推荐系统是怎么工作的
推荐系统工作需要两种信息:
- 特征信息,例如物品的关键词、分类,用户的属性、简介等
- 用户和物品的交互信息,例如用户对物品的打分,物品的购买,收藏等
我们可以基于这两种信息,得到三种不同的推荐算法
- 基于内容的推荐系统(Content-based),他利用的是特征信息
- 协同过滤的推荐系统(Collaborative filtering),他利用的是交互信息
- 混合推荐系统,他利用了两种信息
那么他们都是怎么工作的,他们之间又有什么区别呢?
基于内容的推荐系统
基于内容的推荐系统使用的是用户和商品的特征信息,他的假设是如果一个用户之前喜欢某个商品,那么他以后也会喜欢这个商品。在这里,用户的兴趣是通过历史交互的信息和用户资料填写收集到的,而对于物品端来说,物品会根据其特征进行归类。从而根据物品的类别和用户的兴趣关系进行推荐。
那么这会带来一个问题,就是用户的推荐内容过于狭窄,例如,从已知数据上看,用户A只对类别B、C、D的物品感兴趣,此时推荐不会推这些类别之外的内容,尽管其他内容用户也有可能会感兴趣。(exploit-explore问题)
另一个问题就是,虽然物品端很好做分类,我们只要根据物品的属性将其分到某一个类目下即可,但是用户端,如果我们不让他在注册时填写足够的信息,我们很难快速获取他的兴趣。(cold-start问题)
协同过滤系统
协同过滤是现今用得比较多的推荐算法,一般效果要优于基于内容的推荐。

这类推荐系统是通过用户与物品的交互来筛选用户兴趣的商品,我们可以用可视化的方式来理解。我们可以把用户和物品的交互关系看成一个矩阵,每个元素(i, j)表示用户i和物品j的交互关系,我们可以把它看成是一个广义上的分类模型或者回归模型(上图),说它是广义的是因为他并没有训练集和测试集之分,也没有特征和预测目标之分。他的预测目标可以是任意一个元素,而
应用的“特征”则是除开这个元素的其他元素。
协同过滤的假设是如果一个用户喜欢物品A,另一个用户也喜欢物品A,并且还喜欢物品B,则第一个用户也很有可能喜欢物品A。所以总而言之,协同过滤是基于历史互动行为来预测新的互动行为的算法。从实现上说,可以分为两种:基于记忆的(Memory-based)和基于模型的(Model-based)
基于记忆的实现方法(Memory-based)
有两种思路,第一种思路是将用户分组,然后根据某个用户的交互行为去预测其他相似用户的交互,另一种是将物品分组,然后根据用户对物品A的交互结果去预测和物品A类似的物品B的交互。这种方法会面临一个主要的问题是这个矩阵过于稀疏,因为用户和商品的交互量比起总量来说实在太少了,这导致对用户/商品做分组的效果可能不会很理想
基于模型的实现方法(Model-based)
这个方法采用的是机器学习和数据挖掘的技术,他的主要思想是训练一个模型来做预测。例如,我们可以用已知的用户-商品交互信息去训练一个模型,来预测某个用户最喜欢的Top-5商品。这种方法的优点在于可以方便的给大量的用户推荐大量的商品,通过这种方式我们即使在矩阵很稀疏的情况下也能做出较好的推荐效果。
协同过滤的问题
协同过滤有两个比较大的问题
-
冷启动:我们需要有足够的信息(用户-商品的交互信息)来使这个系统开始工作,例如我们刚建立一个电商网站,我们没有办法在没有足够交互信息的情况下用该方法做推荐
-
加入新的用户/商品信息时,我们没有关于它们的历史交互信息,所以不好进行推荐
这些问题可以通过收集用户的相关信息(例如注册时填写资料),以及物品的属性特征来与数据库中原有的数据进行关联来缓解。
做推荐系统都会用到什么技术
有两种技术都可以用来实现协同过滤系统:全连接神经网络和Item2vec
全连接神经网络
一个典型的方法就是矩阵分解,他可以自动填入未知的交互数据。这里假设我们之前提到的交互矩阵为R。如果我们有两个矩阵U和I,他们乘积中的元素与R中已知的对应元素尽量接近,那么我们只要将U和I相乘,就可以得到那些R中未知的数据了,如下图所示

我们可以通过神经网络的方式进行矩阵分解
首先,我们可以将用户和物品分别映射到M维和N维的向量中,所以这意味着我们需要学习用户和商品的向量化表示,(或者称为embedding),因为我们并不知道他们的向量化表示,所以刚开始我们先随机生成初始值。
然后,对于每个已知的用户-商品行为(u, x),我们将他们对应的向量合并成一个新的向量,由于我们已经知道了他们的交互关系,我们可以使这个交互关系作为神经网络的输出。然后用bp去调整网络的权重,最后得到我们想要的结果。这样,网络会学习到用户和商品的最优向量化表示,我们就可以用它来计算那些未知的用户-商品行为了
例如,还是前面那张图,这里的用户矩阵和物品矩阵是随机初始化的,对于行为(A, X),我们将[1.2, 0.8, 1.2, 0.6]喂给神经网络,让他输出等于4.5。在这个例子中,我们可以用MSE作为损失函数,如果交互矩阵是0-1矩阵的话,我们可以用分类问题下常见的损失函数,例如交叉熵来解决。
这种方法得到的向量通常包含了用户和商品的语义信息,我们不仅仅可以拿它来预测用户-商品的交互行为,还可以拿来做更多的事情,例如相似的用户向量化后距离会更近,这样对后续用户行为的其他学习很有帮助
Item2vec
顾名思义,Item2vec的目的是用类似于word2vec的方式将物品进行向量化,它将用户的购买订单数据作为上下文的信息,这意味着在类似上下文环境中购买的商品是有可比性的,因此在向量化后他们也会距离更近一些。
这种方法在训练时不引入任何跟用户相关的信息,但是在给用户推荐备选项这种情况下非常有用(例如推荐说:你买了这个电视,你很可能也会需要这些东西)
这个方法最主要的问题是我们需要巨大的数据量去做物品的向量化。在Item2vec的论文中,用了两份数据:一份是有9百万购买数据,73万用户,4万9千个商品的数据,另一份是37万购买数据,1706个商品,没有用户的数据。
什么阶段才需要实现一个推荐系统
现在我们对推荐系统有了一个大概的认识了,需要考虑什么阶段才值得去实现一个推荐系统。
如果你有一个很成功的业务,你可能不需要推荐系统也能活得很好,但是如果你想发挥数据的力量,去营造一个更好的用户体验,增加收入,你可以考虑去实现一个。
做推荐系统的前提是啥
数据是最重要的。本质上说,你需要对你的用户和物品有所了解。如果你有了用户和物品的特征,你可以用基于内容(content-based)的方法,而如果你有大量的用户行为,那就可以开始考虑协同过滤了。你拥有的数据越多,你的系统效果就越好。当然,也需要对数据和业务有所了解才行。
一些关于交互行为需要注意的点:
- 需要定义交互行为在业务中指的是啥,这样才能够有针对性的获取数据。例如如果做一个电商网站,那么交互数据包含了点击、搜索、浏览、收藏、购买、评分、加入购物车、甚至不感兴趣,等等。
- 交互行为可能是显性的也可能是隐性的。显性指的是他们明确的对某个物品感兴趣,例如打分、写评价。隐性指的是他们的行为表现出对某个物品感兴趣,例如搜索、点击等
- 会有少部分的物品受到广大用户的喜爱,而大部分的物品只有少部分人喜爱,也就是我们所说的长尾。推荐系统一般会对广大用户喜爱的商品有很好的推荐效果,但是一般说来,长尾的物品对用户的帮助会更大。
当产品刚上线时,实现一个推荐系统通常来说都比较难。当开始收集到用户信息时,可以考虑采用基于内容(content-based)的方法,或者让用户主动填写一些信息来帮助推荐系统进行冷启动。当用户的交互数据开始增加时,就可以开始考虑协同过滤的方法了。
最后,我们需要考虑如何去衡量推荐系统的好坏。
如何去衡量推荐系统的好坏
有很多种指标来衡量推荐系统好坏,主要看推荐系统的目的是啥。比如如果你只给用户推荐top-5感兴趣的物品,那么在衡量时就没必要考虑剩余的商品对用户的感兴趣程度了。当然,如果你还需要考虑这top-5的推荐顺序,那自然顺序也是需要考虑的一个点。
一般来说,评估推荐系统的效果通常有在线和离线两种方法
在线评估
通过A/B测试的方式,根据用户对不同算法的反应来衡量。例如,你可以根据推荐物品的点击率来衡量不同算法的好坏。这种方法挺好,但是必须上线实验才能知道。一次失败的尝试带来的后果就是用户体验甚至利润上的损失,而且,在线评估需要开发上线收集数据,因此得到结果会更慢一些。
离线评估
我们将数据分为训练集和测试集,训练集用于搭建推荐系统算法,并且用测试集进行评估。好处在于离线评估的方法用户不会直接的参与,而且也不用上线,但是要注意有一些影响因素并不能在数据上体现出来。例如,时间的因素会很大程度上影响推荐(例如季节、天气等,或者是一些在收集的数据特征上没有体现的)
网友评论