2015-09-27 32 views
0

我的产品标签&类别列表,这样Django的 - 如何推荐同类产品

class Product(models.Model): 
    tags = TaggableManager() #using django-taggit 
    categories = models.ManyToManyField(Category) 

我正在寻找一种方式来有效实施的方法,如

p = Product.objects.get(...) 
p.similar_products() # -> should return a list sorted by similarity 

相似的计算方式:两种产品之间的相似性得分应该是标签&类别它们共有的数量。

所面临的挑战是,这种方法需要计算每秒数百次监守所以它的重要有效地做到。

我可能会加速这一过程与缓存,但仍然问题 - 有一个Django原生的方法来计算和得分基于标签和类别的同类产品? (我知道Django的建议,但它似乎使用的用户和评级)

谢谢:)

+1

请定义究竟是什么的类似产品是。 –

+0

@克劳斯谢谢,我添加了天真的相似度得分 – Nimo

回答

3

免责声明:以下是我会怎么处理这个问题开始。按原样提供,不适合用途,不包括保修。

是否有django原生的方式来计算和评分相似的产品基于标签和类别?

简短答案为no - Django是一个Web应用程序框架,而不是推荐系统。

我正在寻找一种方式来有效实施的方法(...)

请意识到这是其核心一个不平凡的任务。有两个部分,你需要解决:

  1. 计算产品
  2. 检索组给定的产品的同类产品之间的相似性,可能是通过相似

一旦1.做排名, 2.变得微不足道。计算相似性的方法有很多,您可能希望随着时间的推移改变方法,以获得经验。

因此,我会从2开始,然后向后求解1.这将为您提供一种方法来存储和检索未绑定到任何特定方法来计算相似度的相似度。

检索同类产品要在Django本身解决这个

一种方法是ManyToMany关系:

class Product(models.Model): 
    tags = TaggableManager() #using django-taggit 
    categories = models.ManyToManyField(Category) 
    similars = models.ManyToManyField(Product) 

注意这里的关键思想是存储,每个产品中,所有类似产品的主键列表。然后similar_products方法很简单:

def similar_products(self): 
    return self.similars.all() 

所面临的挑战是,这种方法需要计算数百次每秒

根据产品目录的大小和类别列表,这种方法可能无法很好地扩展。尽管如此,相同概念的效率更高。您可以在数据库外缓存或存储类似产品密钥的列表,例如使用像Redis这样的内存存储。

计算相似度

计算相似度是一个计算复杂的任务。基本上你想要比较每个产品与其他所有产品,其本质在O(n^2)中。已经有相当多的research on the topic

两个产品之间的相似性得分应该是他们共同

有 标签&类别数量

一个幼稚的做法如下。

对于每个产品,

  1. 检索类别的列表,由命令类的主键
  2. 构建的商品X的类别的矩阵,其中每行代表一个产品的类别,每一列代表类别(第1栏代表第1类,第2列代表第2类等)。在该矩阵中,每列是一个范畴变量(0,1),它是1,如果该产品是在各个类别中,否则为0。
  3. 对于每个产品计算category_score这是的类别指标的二进制表示(基本上一个位串)
  4. 构建一个产品×产品矩阵,为每个产品计算相似度作为到所有其他产品的距离,例如similarity = abs(product1.category_score - product2.category_score)
  5. 鉴于一些停产的最大距离,每个产品检索都是这个最大距离内的其他产品,并在Django的模型填补Product.similars关系

显然,这是一个需要任务在某种批处理环境下离线运行。请注意,应用机器学习技术的方法有更复杂的方法,特别是一些在线工作和比上述更好的方法。根据您的特定要求(例如#products,#transactions,用户偏好匹配需求等),它可能会或可能不值得研究这些方法。

推荐阅读:

+0

谢谢!我一直在阅读很多关于这个话题的文章,并且你使用简单高效的查询来计算离线 - >存储 - >检索听起来很棒。谢谢! – Nimo