Краткая версия:Как порекомендовать следующее достижение
У меня аналогичная установка для StackOverflow. Пользователи получают Достижения. У меня есть много других достижений, чем SO, скажем, порядка 10k, и каждый пользователь имеет в 100-х достижений. Теперь, как бы вы порекомендовали (рекомендовать) следующее достижение для пользователя, чтобы попробовать?
Длинная версия:
объекты моделируются, как это в Джанго (показывать только важные части):
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)
и мой алгоритм просто найти любой другой пользователь, который имеет общее достижение с вошедшего в систему пользователя, а затем пройти через все их достижения и сортировать по числу вхождений:
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
Но это берет НАВСЕГДА, чтобы бежать, и всегда возвращает т он весь список, который не нужен. Пользователю потребуется только несколько лучших достижений.
Итак, я могу получить рекомендации по другим алгоритмам и/или улучшениям кода. Я дам вам достижение в моей системе для разработки алгоритма рекомендаций :)
Не могли бы вы добавить некоторые комментарии к коду, объясняющим, что делает каждый цикл? Извините, не слишком хорошо знакомы с django, так что не в состоянии сказать, что ваш алгоритм upto. – Sharun
Я не понимаю, как вы кодируете условия для каждого достижения и какие условия пользователь уже удовлетворил, что наверняка должно иметь отношение к вашей цели - можете ли вы объяснить? –
Конечно. Добавление комментариев. Спасибо за помощь. –