0%

推荐系统基础3:协同过滤基础


任务3:协同过滤基础

代码地址: https://github.com/Guadzilla/Basics-of-Recsys

协同过滤算法

协同过滤(Collaborative Filtering)推荐算法是最经典、最常用的推荐算法。

所谓协同过滤, 基本思想是根据用户之前的喜好以及其他兴趣相近的用户的选择来给用户推荐物品(基于对用户历史行为数据的挖掘发现用户的喜好偏向, 并预测用户可能喜好的产品进行推荐),一般是仅仅基于用户的行为数据(评价、购买、下载等), 而不依赖于项的任何附加信息(物品自身特征)或者用户的任何附加信息(年龄, 性别等)。目前应用比较广泛的协同过滤算法是基于邻域的方法, 而这种方法主要有下面两种算法:

  • 基于用户的协同过滤算法(UserCF): 给用户推荐和他兴趣相似的其他用户喜欢的产品
  • 基于物品的协同过滤算法(ItemCF): 给用户推荐和他之前喜欢的物品相似的物品

不管是UserCF还是ItemCF算法, 非常重要的步骤之一就是计算用户和用户或者物品和物品之间的相似度, 所以下面先整理常用的相似性度量方法, 然后再对每个算法的具体细节进行展开。

相似性度量方法

杰卡德相似系数

杰卡德(Jaccard)相似系数是衡量两个集合的相似度一种指标。两个用户$u$和$v$交互商品交集的数量占这两个用户交互商品并集的数量的比例,称为两个集合的杰卡德相似系数,用符号$sim_{uv}$表示,其中$N(u),N(v)$分别表示用户$u$和用户$v$交互商品的集合。 由于杰卡德相似系数一般无法反映具体用户的评分喜好信息, 所以常用来评估用户是否会对某商品进行打分, 而不是预估用户会对某商品打多少分。

余弦相似度

余弦相似度(cosine similarity) 衡量了两个向量的夹角,夹角越小越相似。首先从集合的角度描述余弦相似度,相比于Jaccard公式来说就是分母有差异,不是两个用户交互商品的并集的数量,而是两个用户分别交互的商品数量的乘积,公式如下:

从向量的角度进行描述,令矩阵$A$为用户-商品交互矩阵(因为是TopN推荐并不需要用户对物品的评分,只需要知道用户对商品是否有交互就行),即矩阵的每一行表示一个用户对所有商品的交互情况,有交互的商品值为1没有交互的商品值为0,矩阵的列表示所有商品。若用户和商品数量分别为$m,n$的话,交互矩阵$A$就是一个$m$行$n$列的矩阵。此时用户的相似度可以表示为(其中$u\cdot v$指的是向量点积):

上述用户-商品交互矩阵在现实情况下是非常的稀疏了,为了避免存储这么大的稀疏矩阵,在计算用户相似度的时候一般会采用集合的方式进行计算。理论上向量之间的相似度计算公式都可以用来计算用户之间的相似度,但是会根据实际的情况选择不同的用户相似度度量方法。

这个在具体实现的时候, 可以使用cosine_similarity进行实现:

1
2
3
4
from sklearn.metrics.pairwise import cosine_similarity
i = [1, 0, 0, 0]
j = [1, 0.5, 0.5, 0]
cosine_similarity([i, j])

皮尔逊相关系数

皮尔逊相关系数的公式与余弦相似度的计算公式非常的类似,首先对于上述的余弦相似度的计算公式写成求和的形式 :

其中$r_{ui},r_{vi}$分别表示用户$u$和用户$v$对商品$i$是否有交互(或者具体的评分值)。

如下是皮尔逊相关系数计算公式:

其中$r_{ui},r_{vi}$分别表示用户$u$和用户$v$对商品$i$是否有交互(或者具体的评分值),$\bar r_u, \bar r_v$分别表示用户$u$和用户$v$交互的所有商品交互数量或者具体评分的平均值。所以相比余弦相似度,皮尔逊相关系数通过使用用户的平均分对各独立评分进行修正,减小了用户评分偏置的影响。具体实现, 我们也是可以调包, 这个计算方式很多, 下面是其中的一种:

1
2
3
4
5
from scipy.stats import pearsonr

i = [1, 0, 0, 0]
j = [1, 0.5, 0.5, 0]
pearsonr(i, j)

皮尔逊相关系数 scipy官方文档

编写代码计算两个用户、物品的相似度

详见notebook