一、协同过滤算法简介
所谓协同过滤算法,其基本思想就是根据用户之前的喜好及其他兴趣相近的用户的选择来给用户推荐物品(基于对用户历史行为数据的挖掘发现用户的喜好偏向, 并预测用户可能喜好的产品进行推荐)。
目前应用广泛的协同过滤算法是基于邻域的方法,而这种方法主要有下面两种算法:
- 基于用户的协同过滤算法(UserCF): 给用户推荐和他兴趣相似的其他用户喜欢的产品
- 基于物品的协同过滤算法(ItemCF): 给用户推荐和他之前喜欢的物品相似的物品
二、基于用户的协同过滤
基于用户的协同过滤算法主要包括两个步骤:
- 找到和目标用户相似的用户
- 找到这个集合中用户喜欢的,且目标用户没有听说过的物品推荐给用户。
一个例子:
对用户推荐商品的过程可以形象化未一个猜测用户对商品打分的任务。上图就是5个用户对5个商品的打分情况,可以理解未用户对商品的喜欢程度(可以通过用户的购买,收藏,浏览时间来判断)。
根据上图,我们现在的任务变成了判断应不应该将商品5推荐给Alice,也就是推测Alice对商品5的打分情况。
基于用户的协同过滤算法:
- 首先根据前面的这些打分情况(或者说已有的用户向量)计算一下Alice和用户1, 2, 3, 4的相似程度, 找出与Alice最相似的n个用户
- 根据这n个用户对物品5的评分情况和与Alice的相似程度会猜测出Alice对物品5的评分, 如果评分比较高的话, 就把物品5推荐给用户Alice, 否则不推荐
这就需要解决两个问题:
- 用户之间的相似度如何计算
- 选出与Alice最相似的n个用户后如何根据他们的习惯进行推荐。
2.1 计算两个向量的相似度
- 杰卡德相似系数
这个是衡量两个集合的相似度一种指标。 两个集合A和B的交集元素在A,B的并集中所占的比例,称为两个集合的杰卡德相似系数,用符号J(A,B)表示。
J ( A , B ) = ∣ A ∩ B ∣ ∣ A ∪ B ∣ J (A,B) = \frac{|A \cap B|}{|A \cup B|} J(A,B)=∣A∪B∣∣A∩B∣
-
余弦相似度
它衡量了用户向量i ii和j jj之间的向量夹角的大小, 夹角越小, 说明相似度越大, 两个用户越相似
s i m ( i , j ) = cos ( i , j ) = i ⋅ j ∣ ∣ i ∣ ∣ ⋅ ∣ ∣ j ∣ ∣ sim (i,j) = \cos (i,j) = \frac{i \cdot j}{||i|| \cdot ||j||} sim(i,j)=cos(i,j)=∣∣i∣∣⋅∣∣j∣∣i⋅j -
皮尔逊相关系数
这个也是非常常用的一种计算相似度的一种方式, 相比余弦相似度, 皮尔逊相关系数通过使用用户平均分对个人独立评分进行修正, 减少了用户评分偏置的影响。
简单的说, 其实pearson做的就是把两个向量都减去他们的均值, 然后再计算consine值。 用pearson来计算用户相似进行推荐的话, 效果还是好于consine的。公式如下:
s
i
m
(
i
,
j
)
=
∑
p
∈
P
(
R
i
,
p
−
R
‾
j
)
(
R
j
p
−
R
‾
j
)
∑
p
∈
P
(
R
i
,
p
−
R
‾
i
)
2
∑
p
∈
P
(
R
i
,
p
−
R
j
‾
)
2
sim (i,j) = \frac{\sum_{p \in P}(R_{i,p}-\overline{\text{R}}_{j})(R_{jp} -\overline{\text{R}}_j )}{\sqrt{\sum_{p \in P}(R_{i,p}-\overline{R}_{i})^2}\sqrt{\sum_{p \in P}(R_{i,p}-\overline{R_{j}})^2}}
sim(i,j)=∑p∈P(Ri,p−Ri)2∑p∈P(Ri,p−Rj)2∑p∈P(Ri,p−Rj)(Rjp−Rj)
这个式子里面其实就是每个向量先减去了它的平均值, 然后在计算余弦相似度.
from scipy.stats import pearsonr
i = [1, 0, 0, 0]
j = [1, 0.5, 0.5, 0]
pearsonr(i, j)
2.2 最终预测结果
通过以上几种方法,可以计算出用户之间的相似度,也就可以计算出与Alice最相似的几个用户。
然后我们可以利用用户相似度和相似用户的评价加权平均获得用户的评价预测, 用下面式子表示:
R
u
,
p
=
∑
s
∈
S
(
w
u
,
s
⋅
R
s
,
p
)
∑
s
∈
S
w
u
,
s
R_{u,p} = \frac{\sum_{s \in S}(w_{u,s}\cdot R_{s,p})}{\sum_{s\in S}{w_{u,s}}}
Ru,p=∑s∈Swu,s∑s∈S(wu,s⋅Rs,p)
其中 w u , s w_u,s wu,s是用户u与用户s的相似度, R s , p R_{s,p} Rs,p是用户s对物品p的评分,这种方式没有考虑有的用户喜欢打高分,有的用户喜欢打低分的情况。
因此我们采用下面这种公式进行计算:
P i , j = R ‾ i + ∑ k = 1 n ( S i , k ( R k , j − R ‾ k ) ) ∑ k = 1 n S i , k P_{i,j} = \overline{R}_i+\frac{\sum_{k=1}^{n}(S_{i,k}(R_{k,j} - \overline{R}_k))}{\sum_{k=1}^{n}S_{i,k}} Pi,j=Ri+∑k=1nSi,k∑k=1n(Si,k(Rk,j−Rk))
这种方式考虑的更全面,虽然依然是用户相似度作为权值,但后面不单纯的是其他用户对物品的评分, 而是该物品的评分与此用户的所有评分的差值进行加权平均, 这时候考虑到了有的用户内心的评分标准不一的情况, 即有的用户喜欢打高分, 有的用户喜欢打低分的情况。
2.3 一个例子
还是这个例子,计算Alice对物品5的打分:
这里我们使用,皮尔森相关系数。使用同样的方式,计算其他用户之间的相似度,从而可以构造一个所有用户之间的相似度矩阵:
从这里看出, Alice用户和用户2, 用户3, 用户4的相似度是0.7, 0, -0.79。 所以如果n=2, 找到与Alice最相近的两个用户是用户1, 和Alice的相似度是0.85, 用户2, 和Alice相似度是0.7。
然后我们就可以根据相似度矩阵,来计算Alice对各物品的推荐:
P
A
l
i
c
e
,
物
品
5
=
R
‾
A
l
i
c
e
+
∑
k
=
1
2
(
S
A
l
i
c
e
,
u
s
e
r
k
(
R
u
s
e
r
k
,
物
品
5
−
R
‾
k
)
)
∑
k
=
1
2
S
A
l
i
c
e
,
u
s
e
r
k
=
4
+
0.85
∗
(
3
−
2.4
)
+
0.7
∗
(
5
−
3.8
)
0.85
+
0.7
=
4.87
P_{Alice,物品5} = \overline{R}_{Alice}+\frac{\sum_{k=1}^{2}(S_{Alice,userk}(R_{userk,物品5} - \overline{R}_k))}{\sum_{k=1}^{2}S_{Alice,userk}} = 4+\frac{0.85*(3-2.4)+0.7*(5-3.8)}{0.85+0.7} = 4.87
PAlice,物品5=RAlice+∑k=12SAlice,userk∑k=12(SAlice,userk(Ruserk,物品5−Rk))=4+0.85+0.70.85∗(3−2.4)+0.7∗(5−3.8)=4.87
之后有了得分情况,对物品的推荐就可以随便推了。
三、基于物品的协同过滤
基于物品的协同过滤(ItemCF)的基本思想是预先根据所有用户的历史偏好数据计算物品之间的相似性,然后把与用户喜欢的物品相类似的物品推荐给用户。比如物品a和c非常相似,因为喜欢a的用户同时也喜欢c,而用户A喜欢a,所以把c推荐给用户A。ItemCF算法并不利用物品的内容属性计算物品之间的相似度, 主要通过分析用户的行为记录计算物品之间的相似度, 该算法认为, 物品a和物品c具有很大的相似度是因为喜欢物品a的用户大都喜欢物品c。
基于物品的协同过滤算法主要分为两步:
- 计算物品之间的相似度
- 根据物品的相似度和用户的历史行为给用户生成推荐列表(购买了该商品的用户也经常购买B商品)
如果要想知道Alice给物品5打多少分,基于物品的协同过滤算法会这样做:
- 计算各商品的相似性,可以采用余弦相似性或者皮尔森系数
- 找出与物品5最相似的n个物品
- 根据Alice对最相近的n个物品的打分去计算出物品5的打分情况
下面我们就可以具体计算一下, 首先是步骤1:
P
A
l
i
c
e
,
物
品
5
=
R
‾
物
品
5
+
∑
k
=
1
2
(
S
物
品
5
,
物
品
k
(
R
A
l
i
c
e
,
物
品
k
−
R
‾
物
品
k
)
)
∑
k
=
1
2
S
物
品
5
,
物
品
k
=
13
4
+
0.97
∗
(
5
−
3.2
)
+
0.58
∗
(
4
−
3.4
)
0.97
+
0.58
=
4.6
P_{Alice,物品5} = \overline{R}_{物品5}+\frac{\sum_{k=1}^{2}(S_{物品5,物品k}(R_{Alice,物品k} - \overline{R}_{物品k}))}{\sum_{k=1}^{2}S_{物品5,物品k}} = \frac{13}{4}+\frac{0.97*(5-3.2)+0.58*(4-3.4)}{0.97+0.58} = 4.6
PAlice,物品5=R物品5+∑k=12S物品5,物品k∑k=12(S物品5,物品k(RAlice,物品k−R物品k))=413+0.97+0.580.97∗(5−3.2)+0.58∗(4−3.4)=4.6