短版:
我有一个与StackOverflow类似的设置。用户获得成就。我有更多的成就,比如说在10公里左右,每个用户都有100多个成就。现在,您将如何推荐(推荐)用户要尝试的下一个成就?在
长版:
对象在django中是这样建模的(只显示重要部分):
class User(models.Model):
alias = models.ForeignKey(Alias)
class Alias(models.Model):
achievements = models.ManyToManyField('Achievement', through='Achiever')
class Achievement(models.Model):
points = models.IntegerField()
class Achiever(models.Model):
achievement = models.ForeignKey(Achievement)
alias = models.ForeignKey(Alias)
count = models.IntegerField(default=1)
我的算法就是找到与登录用户共享成果的所有其他用户,然后浏览他们的所有成果,并按出现次数排序:
^{pr2}$但是它需要运行一段时间,并且总是返回整个列表,这是不需要的。一个用户只需要前几项成就就可以了。在
所以,我欢迎您推荐其他算法和/或代码改进。我会在我的系统中给你一个推荐算法的成果:)
一种可以推荐哪些成就的方法是查看有多少用户已经拥有这些成就,并推荐那些流行的成就。当他们达到这些目标时,你就去列表中推荐一些不太受欢迎的。然而,这有一个天真的假设,即每个人都想追求大众化的成就。它可能会使受欢迎的成就变得更受欢迎而不那么受欢迎,嗯。。。令人欣慰的是,这不会占用太多资源,而且可能运行得非常快。(只需列出成就+成就次数)
另一种方法是使用一些机器学习算法(根据用户已有的成就猜测用户可能会追求哪些成就)。我认为k-nearest neighbor algorithm在这里会表现得很好。选择一个阈值,然后输出高于此阈值的所有内容。现在,我不知道这是否会比你已经拥有的更快,但是你应该在每次用户取得新成就时运行一次推荐引擎,存储前五个(比如说)并在需要推荐时将其输出给用户。在
我希望这有帮助。=)
我建议您将前三个步骤(成就、其他别名、计数)作为一个单独的SQL语句执行。现在,您正在使用Python发出大量查询并汇总数千行,这是一项应该委托给DB的任务。例如代码
执行数千个巨大的查询。在
相反,您可以使用SQL来实现这一点,方法是根据Alias id的不同和成就id的相同,在其自身上加入Achiever。然后按成就id分组并进行计数。在
在下面的查询中,表“B”是其他用户的成果,“Achiever”是我们的成果。如果任何其他用户共享一个成果,他们在“B”中为他们共享的每个成果显示一次。然后,我们根据alias_id对它们进行分组,并计算它们出现的次数,这样就可以得到一个很好的id,count table out。在
非常粗糙的代码(这里没有SQL)
^{pr2}$如果这是我认为的那样,你将得到一个其他用户别名的表,以及他们与当前用户共享的成果的数量。在
接下来要做的是一个SQL语句,它将上面的语句用作“内部选择”—称之为用户。将其与当前用户的成就表和成就表相关联。您可能希望忽略除前10个与当前用户相似的用户之外的所有用户。在
我现在没有时间写一个好的查询,但是看看你的数据库的JOIN语句,该语句连接指定的10个用户和当前用户之间的achievement_id-如果该id不存在,则将其设置为NULL。过滤器只对结果为空(未实现的成就)的行执行。在
相关问题 更多 >
编程相关推荐