Pau*_*jan 5 python django optimization achievements
精简版:
我有类似StackOverflow的设置.用户获得成就.我有比SO更多的成就,让我们说10k的顺序,每个用户都有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)
Run Code Online (Sandbox Code Playgroud)
我的算法只是找到与登录用户共享成就的每个其他用户,然后完成所有成就并按出现次数排序:
def recommended(request) :
user = request.user.get_profile()
// The final response
r = {}
// Get all the achievements the user's aliases have received
// in a set so they aren't double counted
achievements = set()
for alias in user.alias_set.select_related('achievements').all() :
achievements.update(alias.achievements.all())
// Find all other aliases that have gotten at least one of the same
// same achievements as the user
otherAliases = set()
for ach in achievements :
otherAliases.update(ach.alias_set.all())
// Find other achievements the other users have gotten in addition to
// the shared ones.
// And count the number of times each achievement appears
for otherAlias in otherAliases :
for otherAch in otherAlias.achievements.all() :
r[otherAch] = r.get(otherAch, 0) + 1
// Remove all the achievements that the user has already gotten
for ach in achievements :
r.pop(ach)
// Sort by number of times the achievements have been received
r = sorted(r.items(), lambda x, y: cmp(x[1], y[1]), reverse=True)
// Put in the template for showing on the screen
template_values = {}
template_values['achievements'] = r
Run Code Online (Sandbox Code Playgroud)
但它需要FOREVER运行,并且总是返回整个列表,这是不需要的.用户只需要前几个成就.
所以,我欢迎提出有关其他算法和/或代码改进的建议.我会在系统中为您提供推荐算法的成就:)
您可以推荐哪些成就的一种方法是查看有多少用户已经拥有这些成就并推荐那些受欢迎的成就。当他们实现了这些目标后,您可以沿着列表向下推荐不太受欢迎的目标。然而,这有一个天真的假设,即每个人都想追求受欢迎的成就。它可能会导致受欢迎的成就变得更受欢迎和不那么受欢迎,好吧……令人欣慰的是,这不会占用太多资源,并且可能运行得非常快。(只需保留成就列表+实现次数)
另一种方法(尝试根据用户已经取得的成就来猜测用户可能会追求哪些成就)是使用一些机器学习算法。我认为k-近邻算法在这里会表现得很好。选择一个阈值,然后输出高于该阈值的所有内容。现在,我不知道这是否会比您已有的运行得更快,但是您应该在每次用户取得新成就时运行推荐引擎一次,存储前五个(比方说),然后输出它每当需要推荐时返回给用户。
我希望这有帮助。=)
| 归档时间: |
|
| 查看次数: |
601 次 |
| 最近记录: |