4

使用Python,我正在計算項目之間的餘弦相似度。轉換python協作過濾代碼以使用Map Reduce

給出了表示購買(用戶,項目)的事件數據,我有我的用戶「購買」的所有項目的列表。

鑑於這種輸入數據

(user,item) 
X,1 
X,2 
Y,1 
Y,2 
Z,2 
Z,3 

我建立一個Python字典

{1: ['X','Y'], 2 : ['X','Y','Z'], 3 : ['Z']} 

從該字典中,我生成買/不買矩陣,也另一字典(BNB)。

{1 : [1,1,0], 2 : [1,1,1], 3 : [0,0,1]} 

從那裏,我通過計算(1,1,0)之間計算餘弦和(1,1,1)(1,2)之間的相似性,得到0.816496

我通過這樣做:

items=[1,2,3] 
for item in items: 
    for sub in items: 
    if sub >= item: #as to not calculate similarity on the inverse 
     sim = coSim(bnb[item], bnb[sub]) 

我認爲蠻力的方法正在殺死我,它只會隨着數據變大而變慢。使用我的可靠筆記本電腦,這個計算在處理8500個用戶和3500個項目時運行幾個小時。

我試圖計算我的字典中所有項目的相似性,它比我想要的更長。我認爲這是MapReduce的一個很好的候選者,但我在鍵/值對方面「思考」有困難。

或者,我的方法是否存在問題,而不一定是Map Reduce的候選人?

+0

你能鏈接或解釋有關地圖一點點減少?另外,請不要使用'sub'作爲變量名稱。有'operator.sub()',如果你把它交叉過來,它會在以後咬你。 – 2010-05-21 11:19:23

+0

這不是真正的變量名,我只是僞編碼。就Map Reduce而言,我試圖將我的程序步驟轉換爲地圖縮小友好模型。 可以在http://labs.google.com/papers/mapreduce-osdi04-slides/index.html – 2010-05-21 11:34:50

回答

6

這實際上並不是一個「MapReduce」函數,但它應該給你一些顯着的加速而沒有所有的麻煩。

我實際上使用numpy來「矢量化」操作並使您的生活更輕鬆。從這裏你只需要遍歷這個字典並應用矢量化函數來比較這個項目與其他項目。

import numpy as np 
bnb_items = bnb.values() 
for num in xrange(len(bnb_items)-1): 
    sims = cosSim(bnb_items[num], bnb_items[num+1:] 

def cosSim(User, OUsers): 
""" Determinnes the cosine-similarity between 1 user and all others. 
Returns an array the size of OUsers with the similarity measures 

User is a single array of the items purchased by a user. 
OUsers is a LIST of arrays purchased by other users. 

""" 

    multidot = np.vectorize(np.vdot) 
    multidenom = np.vectorize(lambda x: np.sum(x)*np.sum(User)) 

    #apply the dot-product between this user and all others 
    num = multidot(OUsers, User) 

    #apply the magnitude multiplication across this user and all others 
    denom = multidenom(OUsers) 

    return num/denom 

我沒有測試此代碼,所以可能會有一些愚蠢的錯誤,但這個想法應該讓你90%的方式。

這應該有一個顯着的加速。如果你仍然需要加快速度,那麼有一個很棒的博客文章,它實現了「Slope One」推薦系統here

希望幫助, 將

+0

找到Map Reduce的結尾。我不熟悉numpy及其數組和方法。它剛剛出現在我閱讀清單的頂部。 關於字典user_vs_purchase,當你說每個物品的價值是1購買,數組存儲1/0買/不買我的數據庫中的每個項目?項目ID是數組的一部分嗎? 另外,由於這是用戶標識的關鍵,這對於查找用戶 - 用戶相似性還是更有用,或者這是計算項目項目相似性的方式嗎?我只是沒有遵循你的例子的意圖 - 你會好好解釋一下嗎? – 2010-05-21 21:19:26

+0

再次閱讀後,我做了一個改變。你真正需要做的就是循環你的bnb字典。你只需要確保你的訂單是正確的。 – JudoWill 2010-05-22 21:06:22