我真的很想知道人们如何处理协同过滤和推荐引擎等。我的意思是脚本的性能比什么都重要。我已经说过阅读编程集体智能,这真的很有趣,但往往更多地关注事物的算法方面。
我目前只有 2k 用户,但事实证明我目前的系统完全不是未来的证明,并且已经对服务器造成了很大的负担。整个系统基于向用户推荐帖子。我的应用程序是 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_ids,然后使用它们从 MongoDB 中获取类似的帖子。该脚本采用最相似且尚未推荐给用户的帖子。
- 如果为 2,该脚本会从 MySQL 中抓取用户评论或喜欢的所有帖子,并使用他们的 id 来执行上述 1 中的相同操作。
不幸的是,每小时推荐脚本变得非常耗费资源,并且慢慢地需要越来越长的时间才能完成......目前需要 10-15 分钟。我担心在某些时候我将无法再提供每小时建议。
我只是想知道是否有人觉得我可以更好地解决这个问题?