【发布时间】:2012-02-11 08:55:11
【问题描述】:
我真的很想知道人们是如何处理协同过滤和推荐引擎等的。我的意思是脚本的性能比什么都重要。我已经说过阅读编程集体智能,这真的很有趣,但往往更多地关注事物的算法方面。
我目前只有 2000 个用户,但事实证明,我目前的系统完全不能满足未来的需求,并且已经对服务器造成了很大的负担。整个系统基于向用户推荐帖子。我的应用程序是 PHP/MySQL,但我使用一些 MongoDB 来进行协作过滤——我在一个大型 Amazon EC2 实例上。我的设置实际上是一个两步过程。首先我计算项目之间的相似性,然后我使用这些信息提出建议。以下是它的工作原理:
首先,我的系统会计算用户帖子之间的相似度。该脚本运行一个算法,该算法返回每对的相似度分数。该算法检查诸如常见标签、常见评论者和常见喜欢者之类的信息,并能够返回相似度分数。流程如下:
- 每次添加帖子、添加标签、评论或点赞时,我都会将其添加到队列中。
- 我通过 cron(每天一次)处理这个队列,找出每个帖子的相关信息,例如评论者和喜欢者的 user_id 和 tag_id。我以这种结构将此信息保存到 MongoDB: {"post_id":1,"tag_ids":[12,44,67],"commenter_user_ids":[6,18,22],"liker_user_ids":[87, 6]}。这使我最终能够建立一个 MongoDB 集合,当我尝试计算相似度时,它可以让我轻松快速地访问所有相关信息
- 然后我运行另一个 cron 脚本(也每天一次,但在前一个之后)再次通过队列。这一次,对于队列中的每个帖子,我从 MongoDB 集合中获取它们的条目并将其与所有其他条目进行比较。当 2 个条目有一些匹配信息时,我在相似性方面给它们 +1。最后,我对每对帖子都有一个总分。我将分数保存到具有以下结构的不同 MongoDB 集合中: {"post_id":1,"similar":{"23":2,"2":5,"7":2}} ('similar' 是一个 key=>value 数组,以 post_id 为 key,相似度得分为 value。如果是 0,我不保存分数。
我有 5k 个帖子。因此,以上所有内容在服务器上都相当困难。有大量的读取和写入需要执行。现在,这只是问题的一半。然后,我使用这些信息来确定特定用户会感兴趣的帖子。因此,我每小时运行一次 cron 脚本,该脚本运行一个脚本,为网站上的每个用户计算 1 个推荐帖子。流程是这样的:
- 脚本首先决定用户将获得哪种类型的推荐。这是 50-50 的变化 - 1. 与您的某个帖子相似的帖子或 2. 与您互动过的帖子相似的帖子。
- 如果为 1,则脚本从 MySQL 中获取用户 post_id,然后使用它们从 MongoDB 中获取相似的帖子。该脚本采用最相似且尚未向用户推荐的帖子。
- 如果为 2,则该脚本会抓取用户在 MySQL 中评论或喜欢的所有帖子,并使用他们的 ID 执行上述 1 中的相同操作。
不幸的是,每小时的推荐脚本会占用大量资源,而且完成的时间越来越长……目前需要 10 到 15 分钟。我担心在某些时候我将无法再提供每小时建议。
我只是想知道是否有人觉得我可以更好地解决这个问题?
【问题讨论】:
-
这是一个相当复杂的问题,可能超出了 SO 提供的 Q&A 范围。无论如何,我不确定直接的职位关系是否完全可行。帖子相似总是有原因的(在您的情况下,例如共享标签)。例如,加权 tag->post(W) 集合将允许您在给定特定输入帖子的情况下快速找到最相关的相似帖子。这也映射了 A 与 B 相似的情况,B 与 C 相似,因此 A 很可能与 C 相似。在标签库聚合 A 中,B 和 C 都将通过共享标签相关联。跨度>
标签: php mysql mongodb filtering collaborative