2014-07-15 41 views
0

我想計算兩個向量的餘弦相似度。這兩個向量(稱爲Ri和Rj)是用戶對項目i和j的評分,因此自然很稀少(因爲通常只有少數用戶會對特定項目進行評分)。這些向量有50000行,只有0.1%不爲零。scipy稀疏矩陣之間的特殊餘弦

餘弦相似度應該涉及合併評分的用戶評級。例如,如果Ri和Rj是兩個scipy.sparse.csc矩陣,並且它們的值是

RI = [1,2,0,0,3,4] RJ = [0,1,0,3 ,如圖5所示,2]

然後共額定的評級是

日 '= [0,2,0,0,3,4] RJ'= [0,1,0,0,5, 2]

所以餘弦相似性應該是

內(RI 'RJ ')/(|日' | * | RJ' |)

我的問題是,有沒有一種有效的(最好是非循環)方式來計算哪個條目兩個矩陣都有非零值?謝謝!

回答

0

不知道該矩陣你問在這裏,但假設你有變量中的兩個原始陣列,

Ri = [ 1, 2, 0, 0, 3, 4]; Rj = [ 0, 1, 0, 3, 5, 2] 

這裏是你如何構建共同額定等級和計算餘弦相似,

import numpy as np 
Rip = np.array([ i if j != 0 else 0 for i,j in zip(Ri,Rj) ]) 
Rjp = np.array([ j if i != 0 else 0 for i,j in zip(Ri,Rj) ]) 

如果你不想明確地使用for語句,你可以使用地圖,

Rip = map(lambda x,y: 0 if y == 0 else x, Ri, Rj) 
Rjp = map(lambda x,y: 0 if x == 0 else y, Ri, Rj) 

然後餘弦相似度可以與Rip這些明確的(或密集)的陳述和Rjp

cos_sim = float(np.dot(Rip, Rjp))/np.sqrt(np.dot(Rip,Rip) * np.dot(Rjp,Rjp)) 

計算如果你不希望明確存儲完整陣列可以使用scipy.sparse存儲載體不如疏單行(列)矩陣。請注意,如果你這樣做,np.dot將不再起作用,你應該使用sparse matricesdot方法。

from scipy.sparse import csr_matrix 

# make single column/row sparse matrix reps of Rip 
row = np.array([ i for (i,x) in enumerate(Rip) if x != 0 ]) 
col = np.zeros(row.size, dtype=np.int32) 
dat = np.array([ x for (i,x) in enumerate(Rip) if x != 0 ]) 
Rip_col_mat = csr_matrix((dat,(row,col))) 
Rip_row_mat = csr_matrix((dat,(col,row))) 

# make single column/row sparse matrix reps of Rjp 
row = np.array([ i for (i,x) in enumerate(Rjp) if x != 0 ]) 
col = np.zeros(row.size, dtype=np.int32) 
dat = np.array([ x for (i,x) in enumerate(Rjp) if x != 0 ]) 
Rjp_col_mat = csr_matrix((dat,(row,col))) 
Rjp_row_mat = csr_matrix((dat,(col,row))) 

我們計算餘弦相似,我們可以做的,

inner = Rip_row_mat.dot(Rjp_col_mat).data 
Rip_m = np.sqrt(Rip_row_mat.dot(Rip_col_mat).data) 
Rjp_m = np.sqrt(Rjp_row_mat.dot(Rjp_col_mat).data) 

cos_sim = inner/(Rip_m * Rjp_m) 
+0

謝謝您的回答。我想知道是否有任何方法可以避免顯式循環? –

+0

在某些級別,任何數組操作都將以某種方式遍歷元素。如果您不希望列表解析中的「顯式」for循環,可以使用'map'。 – Gabriel