除以 python 中两个数组的乘积时出现意外除以零错误
unexpected division by zero error when dividing by the product of two arrays in python
我怀疑这是我不知道或不了解这段代码的非常基本的东西;我唯一的借口是我是 python.
的完全初学者
我正在尝试根据此 post:
进行一些余弦相似度矩阵计算
What's the fastest way in Python to calculate cosine similarity given sparse matrix data?
其中一个需要计算初始矩阵乘积的对角线的倒数
假设他的初始矩阵是m
,其中每一行代表一个'object',其'coordinates'在矩阵的列中。所以你想计算行.
之间的余弦相似度
然后,要使用矩阵乘积法,您可以执行类似 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
真不明白为什么按部就班,而'all in one go'方法会出错,毕竟操作应该是一样的。
显然发生了一些奇怪的事情,因为当我尝试这样做时:
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
uint8 : Unsigned integer (0 to 255)
import numpy as np
mnorms2 = np.array([71, 73, 77, 68, 72], dtype='uint8')
mnorms2 * mnorms2
# array([177, 209, 41, 16, 64], dtype=uint8)
但是如果您将 dtype
更改为 np.float64
:
mnorms2 = np.array([71, 73, 77, 68, 72], dtype=np.float64)
mnorms2 * mnorms2
# array([5041., 5329., 5929., 4624., 5184.])
要更改 dtype
,请执行以下操作:
mnorms2 = mnorms2.astype(np.float64)
我怀疑这是我不知道或不了解这段代码的非常基本的东西;我唯一的借口是我是 python.
的完全初学者我正在尝试根据此 post:
进行一些余弦相似度矩阵计算What's the fastest way in Python to calculate cosine similarity given sparse matrix data?
其中一个需要计算初始矩阵乘积的对角线的倒数
假设他的初始矩阵是m
,其中每一行代表一个'object',其'coordinates'在矩阵的列中。所以你想计算行.
之间的余弦相似度
然后,要使用矩阵乘积法,您可以执行类似 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
真不明白为什么按部就班,而'all in one go'方法会出错,毕竟操作应该是一样的。
显然发生了一些奇怪的事情,因为当我尝试这样做时:
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
uint8 : Unsigned integer (0 to 255)
import numpy as np
mnorms2 = np.array([71, 73, 77, 68, 72], dtype='uint8')
mnorms2 * mnorms2
# array([177, 209, 41, 16, 64], dtype=uint8)
但是如果您将 dtype
更改为 np.float64
:
mnorms2 = np.array([71, 73, 77, 68, 72], dtype=np.float64)
mnorms2 * mnorms2
# array([5041., 5329., 5929., 4624., 5184.])
要更改 dtype
,请执行以下操作:
mnorms2 = mnorms2.astype(np.float64)