基于协同过滤的推荐算法
1. 基本思想
协同过滤推荐算法是最经典的推荐算法,它的算法思想为物以类聚,人以群分,基本的协同过滤算法基于以下的假设:
- User-based CF 基于用户的协同过滤推荐:“跟你爱好相似的人喜欢的东西你也可能会喜欢”
- Item-based CF 基于物品的协同过滤推荐:“跟你喜欢的东西相似的东西你也可能会喜欢”
实现协同过滤的步骤:
1). 找到相似的Top-N个人或者物品:计算两两的相似度并进行排序
2). 根据相似的人或物品产生推荐结果:利用Top-N生成初始推荐结果,然后过滤掉用户已经有过记录或者明确表示不喜欢的物品
那么,如何计算相似度呢?
2. 相似度计算
根据数据类型的不同,相似度的计算方式也不同,数据类型有:
- 实数型(物品评分情况)
- 布尔型(用户的行为:是否点击、是否收藏、是否点赞等)
一般的,相似度计算有杰卡德相似度、余弦相似度、皮尔逊相关系数
-
余弦相似度
-
度量的是两个向量之间的夹角,用夹角的余弦值来度量相似的情况
-
余弦相似度与向量长度无关,一般计算时都要对向量长度进行归一化,两个向量只要方向一致,无论程度强弱,都视为“相似”
n维空间点a()与b()间的余弦相似度(两个n维向量):
-
-
皮尔逊相关系数
- 实际上也是一种余弦相似度,不过先对向量做了中心化,向量a,b各自减去向量的均值后,再计算余弦相似度
- 度量的是两个变量的变化趋势是否一致,不适合计算布尔值向量之间的相关度
- 计算结果在[-1,1]之间,-1表示负相关,1表示正相关
n维空间点a()与b()间的皮尔逊相关系数(两个n维向量):
-
杰卡德相似度
- 两个集合的交集元素个数在并集中所占的比例,非常适用于布尔向量表示
余弦相似度和皮尔逊相关系数适合用户评分数据(实数值)
杰卡德相似度适用于隐式反馈数据(0,1 布尔值)
3. 关于用户-物品评分矩阵
在协同过滤推荐算法中,我们更多的是利用用户对物品的评分数据集,预测用户对没有评分过的物品的评分结果。
用户-物品的评分矩阵,根据评分矩阵的稀疏程度会有不同的解决方案。
-
稠密评分矩阵
用户/物品 物品A 物品B 物品C 物品D 物品E 用户1 5 3 4 4 ? 用户2 3 1 2 3 3 用户3 4 3 4 3 5 用户4 3 3 1 5 4 用户5 1 5 5 2 1 -
稀疏评分矩阵
用户/物品 物品A 物品B 物品C 物品D 物品E 用户1 5 3 4 ? ? 用户2 ? ? ? 3 3 用户3 4 3 4 ? 5 用户4 ? 3 ? 5 ? 用户5 1 ? 5 ? 1
使用协同过滤推荐算法预测评分-稠密评分矩阵
目的:预测用户1对于物品E的评分
步骤分析:
- 构架数据集
- 计算用户两两之间及物品两两之间相似度,对于评分数据这里我们采用皮尔逊相关系数
- 评分预测:
- User-based CF:取出与用户1正相关的用户,使用用户间相似度。公式如下,该方案考虑了用户本身的评分及近邻用户的加权评分相似度打分:
- Item-based CF:取出与物品E正相关的物品,使用物品间相似度。公式如下,该方案结合了预测物品与相似物品的加权评分相似度打分:
- User-based CF:取出与用户1正相关的用户,使用用户间相似度。公式如下,该方案考虑了用户本身的评分及近邻用户的加权评分相似度打分:
实现过程
- 构建数据集:注意构建评分矩阵时,对于缺失的部分需要保留为None,如果设置为0那么会被当做评分0
import pandas as pd
users = ["User1", "User2", "User3", "User4", "User5"]
items = ["Item A", "Item B", "Item C", "Item D", "Item E"]
# 用户购买记录数据集
datasets = [
[5,3,4,4,None],
[3,1,2,3,3],
[4,3,4,3,5],
[3,3,1,5,4],
[1,5,5,2,1],
]
- 计算用户两两之间及物品两两之间相似度,对于评分数据这里我们采用皮尔逊相关系数
pandas中corr方法可直接用于计算皮尔逊相关系数
df = pd.DataFrame(datasets,index=users,columns=items)
print("用户之间的两两相似度:")
# 直接计算皮尔逊相关系数
# 默认是按列进行计算,因此如果计算用户间的相似度,当前需要进行转置
user_similar = df.T.corr()
user_similar.round(4)
print("物品之间的两两相似度:")
item_similar = df.corr()
item_similar.round(4)
用户之间的两两相似度:
- | User1 | User2 | User3 | User4 | User5 |
---|---|---|---|---|---|
User1 | 1.0000 | 0.8528 | 0.7071 | 0.0000 | -0.7921 |
User2 | 0.8528 | 1.0000 | 0.4677 | 0.4900 | -0.9001 |
User3 | 0.7071 | 0.4677 | 1.0000 | -0.1612 | -0.4666 |
User4 | 0.0000 | 0.4900 | -0.1612 | 1.0000 | -0.6415 |
User5 | -0.7921 | -0.9001 | -0.4666 | -0.6415 | 1.0000 |
物品之间的两两相似度:
- | Item A | Item B | Item C | Item D | Item E |
---|---|---|---|---|---|
Item A | 1.0000 | -0.4767 | -0.1231 | 0.5322 | 0.9695 |
Item B | -0.4767 | 1.0000 | 0.6455 | -0.3101 | -0.4781 |
Item C | -0.1231 | 0.6455 | 1.0000 | -0.7206 | -0.4276 |
Item D | 0.5322 | -0.3101 | -0.7206 | 1.0000 | 0.5817 |
Item E | 0.9695 | -0.4781 | -0.4276 | 0.5817 | 1.0000 |
-
评分预测
基于用户相似度计算 用户1对于商品E的评分
1).根据user_similar获取用户1相似的两个用户为:User2,User3
2).User2,User3对商品E的评分分别为3.0和5.0
3).计算用户1对于商品E的评分:(0.85283.0+0.70715.0)/(0.8528+0.7071)=3.91基于物品相似度计算 用户1对于商品E的评分
1).根据item_similar获取商品E相似的两个商品为商品A和商品D
2).用户1对于商品A和商品D的评分分别为5和4
3).计算用户1对于商品E的评分:(0.96955+0.58174)/(0.9695+0.5817)=4.625
对比可见,User-based CF 和 Item-based CF 的结果是有差异的,因为严格意义上他们应该是属于两种不同的推荐算法,各自在不同的领域,会比另一种更佳,但是具体场景下哪种更合适,需要进行合理的评估,因此在实现推荐系统时,这两种算法往往都是需要实现的,然后根据推荐的效果分析选出更优方案。