6

假设我有一组用户、一组歌曲和每首歌曲的一组投票:

=========== =========== =======
User        Song        Vote
=========== =========== =======
user1       song1       [score]
user1       song2       [score]
user1       song3       [score]
user2       song1       [score]
user2       song2       [score]
user2       song3       [score]
user3       song1       [score]
user3       song2       [score]
user3       song3       [score]
user-n      song-n      [score]
=========== =========== =======

根据歌曲投票计算用户相似度的最有效方法是什么?有没有比遍历每个用户和对每首歌的每次投票更好的方法?

4

7 回答 7

11

有两个常用指标可用于查找用户之间的相似性:

  1. 欧几里得距离,这正是您的想法:想象一个 n 维图,每个轴都有一首歌曲,由两个相关用户(u1和 *u2)评论,其轴上的值是分数。您可以使用以下公式轻松计算相似度:

    对于 u1 和 u2 评论的每首歌曲,计算pow(u1.song.score - u2.song.score, 2)并加在一起sum_of_powers。相似系数由 给出1 / 1 + (sqrt(sum_of_powers))

  2. Pearson Correlation(或相关系数):这是一种更好的方法,可以找出两个数据集彼此相关的程度。这种方法使用更复杂的公式和一些统计背景,请在此处查看:wiki。您将为每两个用户绘制一个图表,然后根据分数绘制点数。例如,如果已从 u1 和u2aSong投票,它将绘制该点(假设 user1 是 x 轴,u2 是 y 轴)。24(2,4)

为了澄清起见,您使用线性回归来找到两个系数AB,它们描述了使与图的所有点的距离最小的线。这条线有这个公式:y = Ax + B。如果两组相似的点应该靠近主对角线,所以A应该趋向于 1 而趋向于B0。不要认为这个解释是完整的或作为参考,因为它缺乏可靠性和典型的数学形式主义,它只是为了给你一个想法.

编辑: 就像其他人写的一样,存在更复杂的聚类数据算法,例如 k-means,但我建议您从简单的算法开始(实际上,当您意识到结果还不够时,您应该需要更困难的东西)。

于 2009-12-02T22:49:31.733 回答
5

我推荐Toby Segaran的《 Programming Collective Intelligence 》一书。第 3 章描述了不同的聚类方法,如层次聚类K-means 聚类

示例的源代码可在此处获得

于 2009-12-02T22:47:55.043 回答
3

如果您想要最准确的结果,那么不,您必须遍历所有内容。

如果您的数据库足够大,您可以只进行统计抽样,例如抽取 1,000 -10,000 个用户并与之匹配。

您最好向数据库中添加更多表,存储结果,并且只每隔一段时间更新一次,而不是即时计算。

于 2009-12-02T22:51:12.060 回答
1

Ilya Grigorik 撰写了一系列关于推荐算法的文章,尽管他专注于 Ruby。它似乎在他档案中的机器学习部分下,但没有直接的部分链接。

于 2009-12-02T22:57:04.570 回答
1

我认为这里的很多人都忽略了问题的简单性。他没有说任何关于创建评级预测系统的事情。他只想计算每个用户的歌曲评分行为与其他用户的歌曲评分行为之间的相似度。皮尔逊相关系数正好给出了这一点。是的,您必须遍历每个用户/用户对。

编辑:

在考虑了更多之后:

如果您想要两个用户的品味之间的相似性,而不是他们的“固执”水平,Pearson 就很棒……一个给一系列歌曲评分为 4、5 和 6 的用户将与另一个给相同歌曲评分的用户完美关联3、6 和 9。换句话说,他们有相同的“品味”(他们会按照相同的顺序对歌曲进行排名),但第二个用户更加固执己见。换句话说,相关系数将任何两个具有线性关系的评级向量视为相等。

但是,如果您想要用户对每首歌曲的实际评分之间的相似性,您应该使用两个评分向量之间的均方根误差。这是一个纯粹基于距离的度量(线性关系不会影响相似度得分),因此 4,5,6 和 3,6,9 用户不会有完美的相似度得分。

决定归结为您所说的“相似”...

就这些。

于 2009-12-02T23:14:54.957 回答
1

如果您想在不访问所有记录的情况下以近似方式执行此操作,则可以使用 Jaccard 系数。如果您想考虑分数,可能需要一些调整。但是我想如果您的系统太大并且您没有时间检查所有记录,这是最好的解决方案。

于 2009-12-03T00:55:20.153 回答
0

你应该可以在这本书中找到一个好的算法: Steven Skiena的算法设计手册

这本书有一大堆用于各种目的的算法。我想你想要一个图聚类算法。我手边没有这本书,所以不能帮你查。

快速谷歌搜索发现了一个维基百科页面:http ://en.wikipedia.org/wiki/Cluster_analysis 也许这会有所帮助,但我认为这本书更清楚地解释了算法。

于 2009-12-02T22:41:39.517 回答