我试图计算两个向量的余弦相似性。这两个向量(称为Ri和Rj)是用户对项目i和j的评级,因此它们自然是稀疏的(因为通常只有少数用户会对特定项进行评级)。这些向量有50000行,只有0.1 %是非零的.
余弦相似性应涉及到共同评级的用户评级。例如,如果Ri和Rj是两个scipy.sparse.csc矩阵,并且它们的值是
Ri = 1,2,0,0,3,4 Rj = 0,1,0,3,5,2
那么共同评级是
Ri‘= 0,2,0,0,3,4 Rj’= 0,1,0,0,5,2
因此,余弦相似性应该是
内部(Ri‘,Rj') /(\x{e76f}\x{e76f}
我的问题是,是否有一种有效的方法(最好是非循环)来计算两个矩阵都有非零值的条目?谢谢!
发布于 2014-07-14 21:45:38
不确定你在这里问的是哪个矩阵,但是假设变量中有两个原始数组,
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
将不再工作,您应该使用稀疏矩阵的dot
方法。
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 )
https://stackoverflow.com/questions/24750270
复制相似问题