2015-09-27 61 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