推荐系统Part2:协同过滤Collaborative Filtering
1. 基本思想与算法核心
协同过滤推荐算法是诞生最早,并且较为著名的推荐算法。
算法主要功能是:预测和推荐。预测过程是预测用户对没有购买过的物品的可能打分值,推荐是根据预测阶段的结果推荐用户最可能喜欢的一个或Top-N个物品。
基本思想:是根据用户之前的喜好以及其他兴趣相近的用户的选择来给用户推荐物品(基于对用户历史行为数据的挖掘发现用户的喜好偏向, 并预测用户可能喜好的产品进行推荐),一般是仅仅基于用户的行为数据(评价、购买、下载等), 而不依赖于项的任何附加信息(物品自身特征)或者用户的任何附加信息(年龄, 性别等)。
算法重要步骤:是计算人与人之间或物与物之间的相似度。
2. 算法种类
CF算法分为两大类,一类为基于memory的(Memory-based),另一类为基于Model的(Model-based)。
目前应用比较广泛的协同过滤算法是基于memory的方法, 而这种方法主要有下面两种算法:
-
基于用户的协同过滤算法(user-based collaboratIve filtering): 给用户推荐和他兴趣相似的其他用户喜欢的产品。
算法基本思路(个人理解):1.计算目标用户与其他用户的相似度,进行排序得到相关度最高的前n名用户;2.根据用户的相似度和用户对商品的喜好程度(对商品的打分或页面访问指标评估等)进行加权排序,取出k个目标用户还没有浏览或购买过的商品(预测);3.将这k个商品推荐给目标用户(推荐)。 -
基于物品的协同过滤算法(item-based collaborative filtering): 给用户推荐和他之前喜欢的物品相似的物品
算法基本思路:与基于用户的协同过滤算法很像,将商品和用户互换。通过不同用户对不同物品的评分,计算物品间的相关性。基于物品间的关系对用户进行相似物品的推荐。
3. 相似度的相关计算方法
3.1 杰卡德(Jaccard)相似系数
这个是衡量两个集合的相似度一种指标。两个用户
u
u
u和
v
v
v交互商品交集的数量占这两个用户交互商品并集的数量的比例,称为两个集合的杰卡德相似系数,用符号
s
i
m
u
v
sim_{uv}
simuv表示,其中
N
(
u
)
,
N
(
v
)
N(u),N(v)
N(u),N(v)分别表示用户
u
u
u和用户
v
v
v交互商品的集合。
s
i
m
u
v
=
∣
N
(
u
)
∩
N
(
v
)
∣
∣
N
(
u
)
∣
∪
∣
N
(
v
)
∣
sim_{uv}=\frac{|N(u) \cap N(v)|}{\sqrt{|N(u)| \cup|N(v)|}}
simuv=∣N(u)∣∪∣N(v)∣∣N(u)∩N(v)∣
由于杰卡德相似系数一般无法反映具体用户的评分喜好信息, 所以常用来评估用户是否会对某商品进行打分, 而不是预估用户会对某商品打多少分。
3.2 欧式距离
欧几里得距离(Euclidean Distance)又叫欧式距离(向量间的距离),是一种简单、常见的用来衡量向量的相似度的方式。通过不同用户对不同商品的评分(或其他维度),计算商品之间的欧式距离作为商品之间或用户之间的相关度。类似聚类K-Means和分类K-Nearest Neighbor(KNN)的思想。
在协同过滤中,使用欧式距离计算相似性进行用户或商品归类的方法叫K近邻方法(K-neighborhoods,或Fix-size neighborhoods),计算原理上和KNN是一样的,在叫法上也是相近的。
这里引用知乎问答上的一个关于协同过滤和聚类的关系中的一个解答:
严格来说,协同过滤不是一种算法,而是一种算法的应用。协同过滤会用到以下基础的ML算法:(各种版本的)KNN、聚类(最简单的k均值聚类,中等复杂的高斯混合聚类,比较复杂的LDA等)、矩阵分解、因子分解等。理论上支持向量机也可以,实际应用未知。大公司数据量比较大,深度学习用得相对多一点。总体来说协同过滤这块还是非dl的传统机器学习用得更多。
欧式距离公式如下:
d
(
x
,
y
)
=
∑
i
=
1
n
(
x
i
−
y
i
)
2
d(x,y)=\sqrt{\sum_{i=1}^{n}{(x_i-y_i)^2}}
d(x,y)=i=1∑n(xi−yi)2
可以看出,当 n=2 时,欧几里德距离就是平面上两个点的距离。当用欧几里德距离表示相似度,一般采用以下公式进行转换:距离越小,相似度越大(同时,避免除数为0):
s
i
m
(
x
,
y
)
=
1
1
+
d
(
x
,
y
)
sim(x,y)=\frac{1}{1+d(x,y)}
sim(x,y)=1+d(x,y)1
参考资料:https://blog.csdn.net/willduan1/article/details/84773468
3.3 余弦距离(余弦相似度)
余弦相似度衡量了两个向量的夹角,夹角越小越相似。
首先从集合的角度描述余弦相似度,相比于Jaccard公式来说就是分母有差异,不是两个用户交互商品的并集的数量,而是两个用户分别交互的商品数量的乘积,公式如下:
s
i
m
u
v
=
∣
N
(
u
)
∣
∩
∣
N
(
v
)
∣
∣
N
(
u
)
∣
⋅
∣
N
(
v
)
∣
sim_{uv}=\frac{|N(u)| \cap |N(v)|}{\sqrt{|N(u)|\cdot|N(v)|}}
simuv=∣N(u)∣⋅∣N(v)∣∣N(u)∣∩∣N(v)∣
从向量的角度进行描述,令矩阵
A
A
A为用户-商品交互矩阵(因为是TopN推荐并不需要用户对物品的评分,只需要知道用户对商品是否有交互就行),即矩阵的每一行表示一个用户对所有商品的交互情况,有交互的商品值为1没有交互的商品值为0,矩阵的列表示所有商品。若用户和商品数量分别为
m
,
n
m,n
m,n的话,交互矩阵
A
A
A就是一个
m
m
m行
n
n
n列的矩阵。此时用户的相似度可以表示为(其中
u
⋅
v
u\cdot v
u⋅v指的是向量点积):
s
i
m
u
v
=
c
o
s
(
u
,
v
)
=
u
⋅
v
∣
u
∣
⋅
∣
v
∣
sim_{uv} = cos(u,v) =\frac{u\cdot v}{|u|\cdot |v|}
simuv=cos(u,v)=∣u∣⋅∣v∣u⋅v
上述用户-商品交互矩阵在现实情况下是非常的稀疏了,为了避免存储这么大的稀疏矩阵,在计算用户相似度的时候一般会采用集合的方式进行计算。理论上向量之间的相似度计算公式都可以用来计算用户之间的相似度,但是会根据实际的情况选择不同的用户相似度度量方法。
调用sklearn的API实现方式:
from sklearn.metrics.pairwise import cosine_similarity
i = [1, 0, 0, 0]
j = [1, 0.5, 0.5, 0]
consine_similarity([i, j])
3.4 皮尔逊相似度
皮尔逊相关系数的公式与余弦相似度的计算公式非常的类似,皮尔逊相关系数是余弦相似度在维度值缺失情况下的一种改进。
首先对于上述的余弦相似度的计算公式写成求和的形式,其中
r
u
i
,
r
v
i
r_{ui},r_{vi}
rui,rvi分别表示用户
u
u
u和用户
v
v
v对商品
i
i
i是否有交互(或者具体的评分值):
s
i
m
u
v
=
∑
i
r
u
i
∗
r
v
i
∑
i
r
u
i
2
∑
i
r
v
i
2
sim_{uv} = \frac{\sum_i r_{ui}*r_{vi}}{\sqrt{\sum_i r_{ui}^2}\sqrt{\sum_i r_{vi}^2}}
simuv=∑irui2∑irvi2∑irui∗rvi
如下是皮尔逊相关系数计算公式,其中
r
u
i
,
r
v
i
r_{ui},r_{vi}
rui,rvi分别表示用户
u
u
u和用户
v
v
v对商品
i
i
i是否有交互(或者具体的评分值),
r
ˉ
u
,
r
ˉ
v
\bar r_u, \bar r_v
rˉu,rˉv分别表示用户
u
u
u和用户
v
v
v交互的所有商品交互数量或者具体评分的平均值。
s
i
m
(
u
,
v
)
=
∑
i
∈
I
(
r
u
i
−
r
ˉ
u
)
(
r
v
i
−
r
ˉ
v
)
∑
i
∈
I
(
r
u
i
−
r
ˉ
u
)
2
∑
i
∈
I
(
r
v
i
−
r
ˉ
v
)
2
sim(u,v)=\frac{\sum_{i\in I}(r_{ui}-\bar r_u)(r_{vi}-\bar r_v)}{\sqrt{\sum_{i\in I }(r_{ui}-\bar r_u)^2}\sqrt{\sum_{i\in I }(r_{vi}-\bar r_v)^2}}
sim(u,v)=∑i∈I(rui−rˉu)2∑i∈I(rvi−rˉv)2∑i∈I(rui−rˉu)(rvi−rˉv)
通过上下两个公式的对比可以看出,其实皮尔逊系数就是余弦相似度在计算之前,对两个向量都先进行中心化(centered)。
而中心化的意思是说, 对每个向量, 先计算所有元素的 μ \mu μ,然后向量中每个维度的值都减去这个 μ \mu μ, 得到的这个向量叫做被中心化的向量。机器学习, 数据挖掘要计算向量余弦相似度的时候, 由于向量经常在某个维度上有数据的缺失,预处理阶段都要对所有维度的数值进行中心化处理。
所以相比余弦相似度,皮尔逊相关系数通过使用用户的平均分对各独立评分进行修正,减小了用户评分偏置的影响。具体实现, 我们也是可以调包, 这个计算方式很多, 下面是其中的一种:
from scipy.stats import pearsonr
i = [1, 0, 0, 0]
j = [1, 0.5, 0.5, 0]
pearsonr(i, j)
4. 算法的优劣和改进,以及编程实现
推荐算法仅仅利用户与商品交互信息(如访问、评价、收藏等)就可以实现推荐,比较简单高效。但也因为没有利用到用户和商品本身的属性(如用户地理位置、年龄、性别和商品描述、类别、适用范围等)造成有效信息的遗漏,不能充分利用其他特征数据。
为了解决这个问题, 在推荐模型中引用更多的特征,推荐系统慢慢的从以协同过滤为核心到了以逻辑回归模型为核心, 提出了能够综合不同类型特征的机器学习模型。
演化时间线: