【问题标题】:Generating 'neighbours' for users based on rating根据评分为用户生成“邻居”
【发布时间】:2010-09-14 02:31:39
【问题描述】:

我正在寻找为我正在开发的网站上的用户生成“邻居”(具有相似品味的人)的技术;类似于 last.fm 的工作方式。

目前,我有一个可以发挥作用的用户兼容功能。它根据 1) 对相似项目的评分 2) 对项目的相似评分对用户进行排名。该函数的权重为第 2 点,如果在生成“邻居”时只需要使用其中一个因素,这将是最重要的。

我的一个想法是只计算每个用户组合的兼容性,然后选择评分最高的用户作为用户的邻居。这样做的缺点是随着用户数量的增加,这个过程可能需要很长时间。对于 1000 个用户,它需要 1000C2 (0.5 * 1000 * 999 = = 499 500) 次调用兼容性函数,这对服务器来说也可能非常繁重。

所以我正在寻找有关如何最好地实现这样的系统的任何建议、文章链接等。

【问题讨论】:

  • 刚刚修复了邻居(或美国的邻居?)标签上的错字...
  • 如果您想出一些出色的作品,您就有可能赢得 Netflix 奖 - netflixprize.com

标签: theory cluster-analysis neighbours


【解决方案1】:

您需要的是一种聚类算法,该算法会自动将相似的用户分组在一起。您面临的第一个困难是大多数聚类算法期望它们聚类的项目被表示为欧几里得空间中的点。在您的情况下,您没有点的坐标。相反,您可以计算它们之间的“相似性”函数的值。

这里的一个很好的可能性是使用spectral clustering,这正是你所拥有的:相似矩阵。缺点是您仍然需要为每对点计算兼容性函数,即。 e.算法是 O(n^2)。

如果您绝对需要比 O(n^2) 更快的算法,那么您可以尝试一种称为 dissimilarity spaces 的方法。这个想法很简单。您反转您的兼容性函数(例如,通过取其倒数)将其转换为差异或距离的度量。然后,您将每个项目(在您的情况下为用户)与一组原型项目进行比较,并将结果距离视为空间中的坐标。例如,如果您有 100 个原型,那么每个用户将由 100 个元素的向量表示,即。 e. 100 维空间中的一个点。然后你可以使用任何标准的聚类算法,比如K-means

现在的问题是如何选择原型,需要多少个。已经尝试了各种启发式方法,但是,这里有一个dissertation,它认为随机选择原型可能就足够了。它显示了使用 100 或 200 个随机选择的原型的实验产生了良好的结果。在您的情况下,如果您有 1000 个用户,并且您选择其中 200 个作为原型,那么您将需要评估您的兼容性函数 200,000 次,这比比较每一对用户提高了 2.5 倍。不过,真正的优势在于,对于 1,000,000 个用户,200 个原型仍然足够,并且您需要进行 200,000,000 次比较,而不是 500,000,000,000 次改进 2500 倍。您得到的是 O(n) 算法,即优于 O(n^2),尽管常数因子可能很大。

【讨论】:

    【解决方案2】:

    请务必查看Collaborative Filtering。许多推荐系统使用协同过滤来向用户推荐项目。他们通过寻找“邻居”然后推荐你的邻居评价很高但你没有评价的项目来做到这一点。你可以去寻找邻居,谁知道呢,也许你将来会想要推荐。

    GroupLens 是明尼苏达大学的一个研究实验室,研究协同过滤技术。他们有大量已发表的研究以及一些示例数据集。

    Netflix Prize 是一项竞赛,旨在确定谁能最有效地解决此类问题。按照他们的LeaderBoard 链接。一些竞争对手分享了他们的解决方案。

    就计算成本低廉的解决方案而言,您可以试试这个:

    • 为您的项目创建类别。如果我们谈论音乐,它们可能是古典、摇滚、爵士、嘻哈……或者更进一步:Grindcore, Math Rock, Riot Grrrl...
    • 现在,每次用户对项目进行评分时,都会在类别级别汇总他们的评分。所以你知道“用户 A”喜欢 Honky Tonk 和 Acid House,因为他们经常给这些项目高评价。频率和强度可能对您的类别总分很重要。
    • 当需要查找邻居时,无需浏览所有评分,只需在类别中查找相似分数即可。

    这种方法不会那么准确,但速度很快。

    干杯。

    【讨论】:

      【解决方案3】:

      如果您将其视为构建/批处理问题而不是实时查询,则可以大大减轻对性能的担忧。

      图形可以静态计算,然后进行潜在更新,例如每小时、每天等,然后生成针对运行时查询优化的边和存储,例如每个用户的前 10 个相似用户。

      +1 也适用于集体智能编程 - 它提供了非常丰富的信息 - 希望它不是(或者我曾经是!)面向 Python,但仍然很好。

      【讨论】:

        【解决方案4】:

        看来您需要阅读有关 clustering algorithms 的信息。一般的想法是,每次将它们分成相似点的集群时,不要将每个点与每个其他点进行比较。那么邻域可能是同一个簇中的所有点。聚类的数量/大小通常是聚类算法的一个参数。

        你可以在 Google 关于cluster computing and mapreduce 的系列中找到video about clustering

        【讨论】:

          【解决方案5】:

          你听说过kohonen networks吗?

          它是一种自组织学习算法,将相似的变量聚集到相似的槽中。尽管大多数网站(如我链接到的网站)都将网络显示为二维,但很少涉及将算法扩展到多维超立方体。

          使用这样的数据结构,查找和存储具有相似品味的邻居是微不足道的,因为相似的用户应该被存储到相似的位置(几乎就像一个反向哈希码)。

          这将您的问题简化为找到定义相似性的变量并确定可能的枚举值之间的距离之一,例如古典音乐和声学接近,而死亡金属和雷鬼音乐相距甚远(至少在我看来)

          顺便说一句,为了找到好的划分变量,最好的算法是decision tree。离根更近的节点将是建立“紧密度”的最重要变量。

          【讨论】:

          • 我个人发现 Kohonen 网络(自组织图 -SOM)很难直观地理解。您对解释所涉及的数学的实现和解释有很好的建议吗?
          【解决方案6】:

          在《编程集体智能》一书中
          http://oreilly.com/catalog/9780596529321

          第 2 章“提出建议”很好地概述了根据用户之间的相似性向人们推荐项目的方法。您可以使用相似度算法找到您正在寻找的“邻居”。该章节可在此处通过 Google 图书搜索找到:
          http://books.google.com/books?id=fEsZ3Ey-Hq4C&printsec=frontcover

          【讨论】:

          • 我强烈推荐这本书。你会在那里找到你需要的东西。
          • 另外,对于计算过程的持续时间,对于大量用户来说,运行时间会很长。您需要批量处理并让站点显示最近运行的结果。
          【解决方案7】:

          问题似乎是“分类问题”。是的,有很多解决方案和方法。

          要开始探索,请检查: http://en.wikipedia.org/wiki/Statistical_classification

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-10-31
            • 2016-12-04
            • 1970-01-01
            • 2019-05-10
            • 2014-01-04
            相关资源
            最近更新 更多