推荐算法
推荐系统作为现在众多电商系统,内容分发系统等网站的必要子系统,越来越受到运营者的重视。推荐系统核心要解决的问题是提高转化率,也就是经过分析,要猜测某一个用户更喜欢什么商品,更可能购买什么商品,或者更喜欢哪些歌曲,文章,在系统中要进行适当形式的推荐,如页面飘窗,营销邮件,短信息等。
注:[本文中用到的Python及其模块安装教程参见]
(https://blog.csdn.net/qq_39384184/article/details/80050598)
推荐思路
目前协同过滤公认的有两种思路,第一种是邻居方法,它有两种视角:
- 第一种,基于用户。也就是说,系统通过分析一个用户和哪些用户的特征比较像,然后看看这些用户喜欢买哪类的商品,再从这些商品里挑出一些推荐给该用户。
- 第二种,基于商品。也就是说,系统通过分析用户的购买行为来判断用户喜欢的商品类型,然后从那些用户喜欢的商品类型里挑出一些推荐给用户。
前者称为User-based CF(User-based Collaborative Filtering),或者叫基于用户的协同过滤;后者称为Item-based CF(User-based Collaboration Filtering),或者叫基于商品的协同过滤。
除了邻居方法外,还有一种思路——基于模型的推荐算法。本文只介绍第一种思路,关于第二种思路,可以参考Matrix factorization techniques for recommender systems这篇论文。
User-based CF
当一个用户进入一个网店时,作为网店系统找到那些和该用户兴趣喜好类似的人,然后看看他们喜欢什么,就给该用户推荐什么也许是一种不错的选择。
首先建立一个用户与商品偏好表。
- 表1:用户与商品偏好
用户ID | 白酒 | 红酒 | 女装 | 男装 | 运动鞋 |
---|---|---|---|---|---|
00001 | 10 | 7 | 2 | 4 | |
00002 | 8 | 7 | 8 | 5 | 8 |
00003 | 8 | 6 | 4 | 5 | |
00004 | 3 | 8 | 8 | 3 | |
00005 | 2 | 5 | 4 | 4 | |
00006 | 0 | 2 | 9 | 7 | 3 |
用户的商品偏好是这个用户对该商品“兴趣程度”的一个量化值,0为没兴趣,10为非常有兴趣。量化的方法有很多种,例如,可以设置这样的算法:当一个用户购买了一类商品,这个商品的兴趣程度就+1,当他浏览一次这个商品,兴趣程度就+0.1,当他给商品反馈打一次五星好评,这个商品的兴趣程度就对应加这个分数的20%,加到10后则不再累加。
计算用户的余弦相似性。
余弦相似性的计算方式与余弦公式相同,由余弦公式:
cos(a,b)=a⋅b|a|⋅|b| cos ( a , b ) = a · b | a | · | b |
在这个公式了,a和b都是向量,这两个向量在空间上只要方向一致,大小不论是否相同,都会得到cos(a,b)=1,而方向相反,则cos(a,b)=-1。
那么计算出来最相似就是1,最不相似是-1。示例计算用户00001和用户00002的爱好相似程度:
cos(00001,00002) cos ( 00001 , 00002 )
=10×8+7×7+2×8+4×5102+72+22+42−−−−−−−−−−−−√×82+72+82+52−−−−−−−−−−−√ = 10 × 8 + 7 × 7 + 2 × 8 + 4 × 5 10 2 + 7 2 + 2 2 + 4 2 × 8 2 + 7 2 + 8 2 + 5 2
=80+49+16+20169−−−√×202−−−√≈0.89 = 80 + 49 + 16 + 20 169 × 202 ≈ 0.89
最后设置一个相似的阈值。
如0.8,0.85……或者其他任何一个值,看看相似度超过这个阈值的用户都有什么购物喜好,把他们喜好购买的东西推荐给该用户作为推荐方案即可,这就是一种思路最为朴素的基于用户的协同过滤算法思路。
Item-based CF
这种算法给用户推荐和他们之前喜欢的商品相似的商品。但是这种算法和前面的基于用户的协同过滤算法不一样——它并不是要建立一个商品属性的矩阵来计算物品之间的相似度。这个算法的核心思路是:“有很多人喜欢商品A,同时他们喜欢商品B,所以A和B应该是比较类似的商品。”
计算起来可以分成以下两个步骤:
- 计算商品之间的相似度。
- 根据物品的相似度和用户的偏好来给用户生成推荐列表。
这里同样用到了余弦相似度的概念,但是公式略有不同:
cos(A,B)=N(A∩B)N(A)⋅N(B)−−−−−−−−−√ cos ( A , B ) = N ( A ∩ B ) N ( A ) · N ( B )
分子是同时喜欢A和B两个商品的用户数量,分母是喜欢A的用户数量和喜欢B的用户数量的乘积的平方根。
如果要得到产品和用户喜好数量的关系,计算过程如下:
例如,给出一个文娱用品商店的销售记录,这里只用5个用户来做一个演示。
用户00001:象棋,扑克牌,篮球。
用户00002:扑克牌,乒乓球,乒乓球拍。
用户00003:乒乓球,乒乓球拍。
用户00004:围棋,扑克牌。
用户00005:象棋,围棋,足球,扑克牌。
首先得到每个用户购买物品的邻接矩阵。
- 表2:用户00001购物邻接矩阵
|商品名称|象棋|扑克牌|篮球|乒乓球|乒乓球拍|围棋|足球|
商品名称 | 象棋 | 扑克牌 | 篮球 | 乒乓球 | 乒乓球拍 | 围棋 | 足球 |
---|---|---|---|---|---|---|---|
象棋 | 1 | 1 | |||||
扑克牌 | 1 | 1 | |||||
篮球 | 1 | 1 | |||||
乒乓球 | |||||||
乒乓球拍 | |||||||
围棋 | |||||||
足球 |
- 表3:用户00002购物邻接矩阵
商品名称 | 象棋 | 扑克牌 | 篮球 | 乒乓球 | 乒乓球拍 | 围棋 | 足球 |
---|---|---|---|---|---|---|---|
象棋 | |||||||
扑克牌 | 1 | 1 | |||||
篮球 | |||||||
乒乓球 | 1 | 1 | |||||
乒乓球拍 | 1 | 1 | |||||
围棋 | |||||||
足球 |
- 表4:用户00003购物邻接矩阵
商品名称 | 象棋 | 扑克牌 | 篮球 | 乒乓球 | 乒乓球拍 | 围棋 | 足球 |
---|---|---|---|---|---|---|---|
象棋 | |||||||
扑克牌 | |||||||
篮球 | |||||||
乒乓球 | 1 | ||||||
乒乓球拍 | 1 | ||||||
围棋 | |||||||
足球 |
– 表5:用户00004购物邻接矩阵
商品名称 | 象棋 | 扑克牌 | 篮球 | 乒乓球 | 乒乓球拍 | 围棋 | 足球 |
---|---|---|---|---|---|---|---|
象棋 | |||||||
扑克牌 | 1 | ||||||
篮球 | |||||||
乒乓球 | |||||||
乒乓球拍 | |||||||
围棋 | 1 | ||||||
足球 |
- 表6:用户00005购物邻接矩阵
商品名称 | 象棋 | 扑克牌 | 篮球 | 乒乓球 | 乒乓球拍 | 围棋 | 足球 |
---|---|---|---|---|---|---|---|
象棋 | 1 | 1 | 1 | ||||
扑克牌 | 1 | 1 | 1 | ||||
篮球 | |||||||
乒乓球 | |||||||
乒乓球拍 | |||||||
围棋 | 1 | 1 | 1 | ||||
足球 | 1 | 1 | 1 |
下一步把这些矩阵加在一起,得到如下表所示的中间矩阵C。
- 表7:中间矩阵C
商品名称 | 象棋 | 扑克牌 | 篮球 | 乒乓球 | 乒乓球拍 | 围棋 | 足球 |
---|---|---|---|---|---|---|---|
象棋 | 2 | 1 | 1 | 1 | |||
扑克牌 | 2 | 1 | 1 | 1 | 2 | 1 | |
篮球 | 1 | 1 | |||||
乒乓球 | 1 | 2 | |||||
乒乓球拍 | 1 | 2 | |||||
围棋 | 1 | 2 | 1 | ||||
足球 | 1 | 1 | 1 |
计算商品相似度。
这时如果对任意两个商品的相似度做评估,如计算象棋和围棋的相似程度,运用公式,从中间矩阵C得,同时喜欢围棋和象棋的有1人,从之前每个用户的购物邻接矩阵中可得,喜欢围棋的有2人,喜欢象棋的有1人,所以象棋和围棋的相似度为:
cos(A,B)=12×2−−−−√≈0.5 cos ( A , B ) = 1 2 × 2 ≈ 0.5
在计算一下乒乓球拍和乒乓球的相似度:
cos(A,B)=22×2−−−−√≈1 cos ( A , B ) = 2 2 × 2 ≈ 1
计算出来所有商品的相似程度如下表。
- 表8:商品相似度
商品名称 | 象棋 | 扑克牌 | 篮球 | 乒乓球 | 乒乓球拍 | 围棋 | 足球 |
---|---|---|---|---|---|---|---|
象棋 | 0.82 | 0.71 | 0.5 | 0.71 | |||
扑克牌 | 0.82 | 0.5 | 0.35 | 0.35 | 0.71 | 0.5 | |
篮球 | 0.71 | 0.5 | |||||
乒乓球 | 0.35 | 1 | |||||
乒乓球拍 | 0.35 | 1 | |||||
围棋 | 0.5 | 0.71 | 0.71 | ||||
足球 | 0.71 | 0.5 | 0.71 |
当要对一个用户做推荐时,先把这个用户的历史购买记录都列出来,假设有n个购买记录。然后对这个列表里每一个商品都用查表的方法查一次相似度,这样会得到n个列表,每个列表里都是一个商品和其对应的相似度关系。把这个n个列表做一个排序,相似度高的在前,相似度低的在后。如果要推荐3个商品的话,就取列表的前3个做推荐。
归一化处理。
在Item-based CF算法中存在一些问题,那就是关于覆盖率和多样性的问题。
例如,有一个用户购买了3本不同的书,3件不同的衣服,和3盒不同品牌的乒乓球。进行相似度计算的时候,由于乒乓球和乒乓球拍的相似度接近1,所以每次推荐给用户的商品都是乒乓球拍,这显然不是我们想要的结果。
这里就涉及到过拟的问题,我们期望的不是一个高度收敛的算法,我们要的是商品的种类要丰富,也就是商品的覆盖率要高,也要保证它的多样性。这里需要用到一个物品相似度的归一化算法。
所谓归一化就是把商品相似度矩阵做如下变化:
w‘ij=wijmaxjwij w i j ‘ = w i j m a x j w i j
也就是对每一行的相似度和当前行的最大值计算一个比值,把这个比值当作新的结果放在矩阵里,变换之后的商品相似度矩阵如下表所示。
- 表9:归一化商品相似度矩阵
商品名称 | 象棋 | 扑克牌 | 篮球 | 乒乓球 | 乒乓球拍 | 围棋 | 足球 |
---|---|---|---|---|---|---|---|
象棋 | 0.00 | 1.00 | 0.87 | 0.00 | 0.00 | 0.61 | 0.87 |
扑克牌 | 1.00 | 0.00 | 0.61 | 0.43 | 0.43 | 0.87 | 0.61 |
篮球 | 1.00 | 0.70 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 |
乒乓球 | 0.00 | 0.35 | 0.00 | 0.00 | 1.00 | 0.00 | 0.00 |
乒乓球拍 | 0.00 | 0.35 | 0.00 | 1.00 | 0.00 | 0.00 | 0.00 |
围棋 | 0.70 | 1.00 | 0.00 | 0.00 | 0.00 | 0.00 | 1.00 |
足球 | 1.00 | 0.70 | 0.00 | 0.00 | 0.00 | 1.00 | 0.00 |
这样直观的感觉就是所有原来相似度看上去比较低的值都被拉高了,缩小了差距,这其实是对刚刚的忧虑在算法上做出了一些补偿。
这样的好处就是把原来分布很窄的一个分数区间拉开了,让分数和分数之间的距离感更好,便于进一步遴选和分类。