我怀疑这是一个非常基本的问题,我不知道或不理解这段代码;我唯一的借口是我是python的初学者
我正在尝试这篇文章中的一些余弦相似矩阵计算:
What's the fastest way in Python to calculate cosine similarity given sparse matrix data?
其中之一需要计算初始矩阵乘积对角线的倒数。
假设初始矩阵为m
,每行代表一个“对象”,其“坐标”位于矩阵的列中。所以您想计算行之间的余弦相似性
然后,要使用矩阵积方法,可以执行类似mp = numpy.dot(m, m.T)
的操作
现在,如果在m
中没有只有0的行,mp
的对角线永远不会有任何零值,因为它的每个元素都是m
对应行的平方元素之和。
我在计算中使用的m
实际上没有包含所有0的行。
事实上,当我这样做的时候:
mp = np.dot(m, m.T)
mnorms2 = mp.diagonal()
我可以很容易地测试:
mnorms2.min()
# 32
由于我对m
使用稀疏矩阵(csr
),因此mp
也是稀疏的,我只需要mnorms2
的特定元素对,我通过以下方式获得:
mp_rows, mp_cols = mp.nonzero()
这些是mnorms2
元素的索引,我需要将它们相乘,取平方根,然后除以mp.data
我看到code in the method I was trying经历了所有中间步骤,但我认为这只是为了说明,所以我尝试一次完成,比如:
mp.data = mp.data / numpy.sqrt(mnorms2[mp_rows] * mnorms2[mp_cols])
这给出了一个除零的错误,尽管我确信mnorms2
的任何元素都不是零
更糟糕的是,它并没有系统地这样做,只是针对一些m
矩阵,尽管在所有情况下,这些矩阵都具有相似的稀疏结构和内容
事实上,我甚至做到了:
denom = numpy.sqrt(mnorms2[mp_rows] * mnorms2[mp_cols])
我发现:
denom.min()
# 0.0
没有0的两个数组的(元素对元素)乘积怎么可能有0
最后唯一有效的办法是:
inv = 1 / numpy.sqrt(mnorms2[mp_rows])
inv = inv / numpy.sqrt(mnorms2[mp_cols])
mp.data = mp.data * inv
我真的不明白为什么一步一步走是有效的,而“一步到位”的方法会导致错误,因为最终的操作应该是相同的
显然有一些奇怪的事情发生了,因为当我尝试这个:
mnorms2[0:5]
# array([71, 73, 77, 68, 72], dtype=uint8)
mnorms2[0:5] * mnorms2[0:5]
# array([177, 209, 41, 16, 64], dtype=uint8)
177不是71的平方…:/
这是怎么回事
有什么建议/想法吗
谢谢
我认为问题是
dtype
但是如果将
dtype
更改为np.float64
:要更改
dtype
,请执行以下操作:相关问题 更多 >
编程相关推荐