基于物品的协同过滤算法(Item-Based Collaborative Filtering)原理与实现
基于物品的协同过滤是推荐系统中广泛应用的一种算法。它的核心思想是:如果许多用户同时喜欢物品A和物品B,那么物品A和B是相似的。当一个用户喜欢物品A时,系统就可以向他推荐与A最相似的物品B。与“基于用户”的方法(寻找相似用户)不同,它是通过分析物品之间的共现关系来进行推荐。
1. 算法核心思想与直观理解
想象一个电影评分网站,用户给电影打1-5分:
- 用户1:给《肖申克的救赎》5分,给《阿甘正传》4分
- 用户2:给《肖申克的救赎》4分,给《阿甘正传》5分,给《泰坦尼克号》1分
- 用户3:给《阿甘正传》5分,给《泰坦尼克号》1分
观察数据你会发现:
- 喜欢《肖申克的救赎》的用户(用户1,2)通常也喜欢《阿甘正传》。
- 喜欢《阿甘正传》的用户(用户1,2,3)对《泰坦尼克号》评价不高。
Item-CF的结论:《肖申克的救赎》和《阿甘正传》非常相似。因此,当有一个新用户4只给《肖申克的救赎》打了5分时,即使我们对他一无所知,也可以很有信心地向他推荐《阿甘正传》。
2. 算法详细步骤
假设我们有m个用户和n个物品,用户-物品评分矩阵为 R (大小为 m x n),R[u][i] 表示用户u对物品i的评分。如果用户u没有评价过物品i,则 R[u][i] 为空。
步骤1:构建物品-物品相似度矩阵
这是算法的核心。我们需要计算每一对物品(i, j)之间的相似度。最常用的方法是余弦相似度或改进的余弦相似度。
a) 余弦相似度 (Cosine Similarity)
将每个物品视为一个m维向量(每个维度是一个用户对该物品的评分)。物品i和物品j的相似度就是它们对应向量夹角的余弦值。
sim(i, j) = (sum_{u in U} R[u][i] * R[u][j]) / ( sqrt(sum_{u in U} R[u][i]^2) * sqrt(sum_{u in U} R[u][j]^2) )
-
U是同时评价过物品i和物品j的所有用户的集合。 -
分子是向量i和j的点积。
-
分母是向量i和j的模长乘积,用于归一化。
-
结果范围是[-1, 1],但在评分均为正的情况下,通常是[0, 1]。值越接近1,越相似。
-
缺点:没有考虑不同用户的评分尺度差异。一个用户习惯性打高分(4,5分),另一个习惯性打低分(1,2分),这种计算方法会放大他们的差异。
b) 改进的余弦相似度 (Adjusted Cosine Similarity) / 皮尔逊相关系数 (Pearson Correlation)
为了消除用户评分偏置,计算相似度时,从每个评分中减去该用户的平均评分。
sim(i, j) = (sum_{u in U} (R[u][i] - avg_u) * (R[u][j] - avg_u)) / ( sqrt(sum_{u in U} (R[u][i] - avg_u)^2) * sqrt(sum_{u in U} (R[u][j] - avg_u)^2) )
avg_u是用户u所有评分的平均值。- 这种方法更常用,效果通常更好。
最终结果:我们得到一个 n x n 的对称矩阵 W,W[i][j] 记录了物品i和物品j的相似度。
步骤2:为目标用户生成推荐
假设我们要为用户u(他有过一些评分记录)推荐N个物品。
-
找出用户u已经有过正反馈(如评分>阈值,或点击过)的物品集合,记为
I_u。 -
遍历所有物品。对于用户u没有评价过的每个候选物品
c:- 找出与物品
c最相似的K个物品(K是一个超参数),并且这K个物品必须属于I_u(即用户u喜欢过它们)。这个集合记为S(c, K)。 - 计算用户u对候选物品c的预测兴趣度/评分
P(u, c):P(u, c) = sum_{i in S(c, K)} sim(c, i) * R[u][i]sim(c, i)是物品c和i的相似度(来自步骤1计算的矩阵W)。R[u][i]是用户u对物品i的实际评分。如果只有隐式反馈(如点击),R[u][i]可以设为1。- 这个公式的本质是:用户u对物品c的兴趣,是他已有兴趣物品i的评分,以物品c与i的相似度为权重,进行加权求和。
- 找出与物品
-
对所有候选物品c计算出的
P(u, c)进行降序排序,取出Top-N个物品,就是给用户u的推荐列表。
3. 一个简化计算示例
假设有3个用户(U1, U2, U3)和4部电影(M1, M2, M3, M4),评分矩阵如下(0表示未评分):
| 用户\电影 | M1 | M2 | M3 | M4 |
|---|---|---|---|---|
| U1 | 5 | 3 | 4 | 4 |
| U2 | 3 | 1 | 2 | 3 |
| U3 | 4 | 3 | 4 | 3 |
目标:为用户U1推荐电影(假设U1没看过M2,要预测他对M2的评分)。
步骤1:计算物品相似度(以M2为中心,用改进余弦相似度)
首先计算每个用户的平均分:avg_U1=(5+3+4+4)/4=4, avg_U2=2.25, avg_U3=3.5。
-
计算 sim(M2, M1):
- 同时评价过M2和M1的用户:U1, U2, U3。
- 中心化评分:
- U1: (M2:3-4=-1), (M1:5-4=1)
- U2: (M2:1-2.25=-1.25), (M1:3-2.25=0.75)
- U3: (M2:3-3.5=-0.5), (M1:4-3.5=0.5)
- 分子 = (-11) + (-1.250.75) + (-0.5*0.5) = -1 -0.9375 -0.25 = -2.1875
- 分母 = sqrt((-1)^2+(-1.25)^2+(-0.5)^2) * sqrt(1^2+0.75^2+0.5^2) = sqrt(1+1.5625+0.25)sqrt(1+0.5625+0.25) = sqrt(2.8125)sqrt(1.8125) ≈ 1.677 * 1.346 ≈ 2.257
sim(M2, M1) ≈ -2.1875 / 2.257 ≈ -0.97(呈强负相关)
-
计算 sim(M2, M3) 和 sim(M2, M4) (过程略,假设结果):
sim(M2, M3) ≈ 0.80(强正相关)sim(M2, M4) ≈ 0.32(弱正相关)
步骤2:为用户U1预测对M2的评分
U1评价过的物品集合 I_u = {M1:5, M3:4, M4:4}。
我们取最相似的K=2个物品。与M2最相似的两个物品是 M3(0.80) 和 M4(0.32)。
预测评分:
P(U1, M2) = sim(M2, M3)*R[U1][M3] + sim(M2, M4)*R[U1][M4] = 0.80*4 + 0.32*4 = 3.2 + 1.28 = 4.48
因此,预测用户U1会给M2打约4.48分,高于他的一般评分(平均4分),所以系统可能会将M2推荐给U1。
4. 关键优化与工程实践
- 相似度矩阵计算优化:物品数量n可能极大(百万级),计算所有n^2对相似度不现实。通常只计算“共现”次数超过某个阈值的物品对,或利用稀疏矩阵、分布式计算(如MapReduce)来加速。
- 相似度归一化:对相似度矩阵W的每一行(每个物品),将其相似度向量进行归一化(如L2归一化),可以提升推荐结果的相关性。
- 加权预测公式:更常见的预测公式会除以相似度之和,以进行标准化。
P(u, c) = sum(sim(c, i) * R[u][i]) / sum(|sim(c, i)|) - 处理冷启动:对于新物品(没有被任何用户评价过),无法计算其相似度,这是Item-CF的弱点。通常需要引入内容信息(如Item-CF与内容过滤结合)或利用热门物品进行补足。
- 实时性:用户的新行为(如一个新评分)不会改变物品相似度矩阵(相对稳定),只需要重新执行步骤2即可生成新推荐,实时性较好。这是它比User-CF的一个优势。
总结
基于物品的协同过滤通过“物以类聚”的思想进行推荐。它的优势在于:物品相似度相对稳定,可离线预计算,推荐结果可解释性强(“推荐这个是因为你喜欢A”),在物品数远少于用户数的场景下更高效。其劣势在于对新物品(冷启动) 不友好,且依赖用户行为历史,在用户行为非常稀疏时效果会下降。
在实际系统中,如亚马逊、Netflix的早期推荐,Item-CF都扮演了核心角色,并常与其他算法(如矩阵分解、深度学习)结合,构成混合推荐系统。