协同过滤:非个性化的物品间相似性

6 投票
4 回答
4753 浏览
提问于 2025-04-15 20:04

我正在尝试计算物品之间的相似度,类似于亚马逊的推荐方式:“查看/购买了X的顾客也查看/购买了Y和Z”。我看到的例子和参考资料大多是关于计算排名物品的相似度、寻找用户之间的相似度,或者根据当前用户的历史记录来推荐物品。我想先从一种不针对特定用户的方法开始,然后再考虑当前用户的偏好。

在查看了亚马逊推荐的白皮书后,他们在离线计算物品相似度时使用了以下逻辑:

For each item in product catalog, I1 
  For each customer C who purchased I1
    For each item I2 purchased by customer C
       Record that a customer purchased I1 and I2
  For each item I2 
    Compute the similarity between I1 and I2

如果我理解得没错,当我们到达“计算I1和I2之间的相似度”时,我已经有了一份与单个值I1(外层循环)一起购买的物品列表(I2)。

这个计算是怎么进行的呢?

还有一个想法是,我可能想得太复杂了,其实没必要那么麻烦——只要对与I1一起购买的I2的数量做个前n名查询就够了吗?

我也希望能得到一些建议,看看这种方法是否正确。我的产品数据库里大约有15万个物品。由于我看到的大部分阅读材料都是关于用户-物品相似度或者用户-用户相似度的,我是否应该考虑走那条路呢?

我之前也用过相似度算法,但它们总是涉及到排名或评分。我觉得唯一可行的方法是建立一个顾客-产品矩阵,用0和1来表示未购买和已购买。考虑到购买历史和物品数量,这个矩阵可能会变得非常庞大。

补充:虽然我把python列为标签,但我更希望将逻辑放在数据库中,最好使用Oracle PL/SQL。

4 个回答

4

@Neil 或者将来看到这个问题的朋友:

选择相似度的计算方法是你自己的决定,你可能希望这个选择在未来可以灵活调整。可以先看看维基百科上关于弗罗贝尼乌斯范数的文章。或者你可以参考你提交的链接中的杰卡德系数 cos(I1,I2)

用户-物品、用户-用户、物品-物品之间的选择,或者其他组合,不能简单地给出一个标准答案。这取决于你能从用户那里获取什么样的数据,用户界面是如何提取这些信息的,你认为哪些数据是可靠的,以及你自己的时间限制(尤其是涉及混合方法时)。

因为很多人都在这些问题上写过硕士论文,所以你可能想从最简单的可实现方案开始,同时留出空间让算法在复杂性上逐步提升。

6

让我们来理解一下物品之间的协同过滤。假设我们有一个购买矩阵。

        Item1  Item2 ... ItemN
 User1  0        1   ...  0
 User2  1        1   ...  0 
  .
  .
  .
 UserM  1        0   ...  0

然后我们可以通过列向量来计算物品之间的相似度,比如使用余弦相似度。我们会得到一个物品相似度的对称矩阵,如下所示。

        Item1  Item2 ... ItemN
 Item1  1       1/M  ...  0
 Item2  1/M     1    ...  0 
  .
  .
  .
 ItemN  0       0    ...  1

这可以理解为“查看或购买了X的顾客,也查看或购买了Y、Z……”(协同过滤)。因为物品的向量化是基于用户的购买记录。

亚马逊的逻辑和上面说的一样,目标是提高效率。正如他们所说:

我们可以通过遍历所有物品对,计算每对之间的相似度,来构建一个物品与物品之间的矩阵。然而,很多物品对没有共同的顾客,因此这种方法在处理时间和内存使用上都不够高效。迭代算法提供了一种更好的方法,通过计算一个单一产品与所有相关产品之间的相似度。

5

这方面有一本很不错的O'Reilly的书。虽然白皮书可能用伪代码的方式来展示逻辑,但我觉得这种方法不太适合大规模使用。这里的计算都是概率计算,所以像贝叶斯定理这样的东西就会被用来问:“如果A这个人买了X,那么他买Z的可能性有多大?”简单地遍历数据会让工作变得很繁琐,因为你得为每个人都处理一遍所有数据。

撰写回答