【问题标题】:Scipy coo_matrix.max() alters data attributeScipy coo_matrix.max() 改变数据属性
【发布时间】:2020-12-30 20:35:47
【问题描述】:

我正在使用开源库 LightFM 构建推荐系统。该库要求某些数据采用稀疏矩阵格式,特别是 scipy coo_matrix。正是在这里,我遇到了奇怪的行为。这似乎是一个错误,但更有可能是我做错了什么。

基本上,我让 LightFM.Dataset 为我构建一个稀疏矩阵,如下所示:

interactions, weights = dataset.build_interactions(data=_get_interactions_data())

build_interactions 方法返回“两个 COO 矩阵:交互矩阵和相应的权重矩阵”——LightFM Official Doc

当我检查这个稀疏矩阵的内容时(实际上,我使用调试器),如下所示:

for i in interactions.data:
    print(i, end=', ')

1, 1, 1, 1, 1, ....

打印一长串 1,表示稀疏矩阵的非零元素只有 1。

但是,当我第一次检查稀疏矩阵的最大值时,它表明稀疏矩阵中的最大值不是 1,而是 3。此外,在检查之后打印矩阵将打印一长串 1 、2s 和 3s。这是它的代码:

print(interactions.max())
for i in interactions.data:
    print(i, end=', ')

3
1, 1, 3, 2, 1, 2, ...

知道这里发生了什么吗? Python 是 3.6.8。 Scipy 是 1.5.4。 CentOS7.

谢谢。

【问题讨论】:

    标签: python scipy sparse-matrix


    【解决方案1】:

    “原始”coo_matrix 可以有重复的元素(相同行和列值的重复),但是当转换为 csr 格式进行计算时,这些重复项会被求和。为了找到最大值,它必须做同样的事情,但在原地。

    In [9]: from scipy import sparse
    In [10]: M = sparse.coo_matrix(([1,1,1,1,1,1],([0,0,0,0,0,0],[0,0,1,0,1,2])))
    In [11]: M.data
    Out[11]: array([1, 1, 1, 1, 1, 1])
    In [12]: M.max()
    Out[12]: 3
    In [13]: M.data
    Out[13]: array([3, 2, 1])
    In [14]: M
    Out[14]: 
    <1x3 sparse matrix of type '<class 'numpy.int64'>'
        with 3 stored elements in COOrdinate format>
    

    跟踪max 代码我发现它使用sum_duplicates

    In [33]: M = sparse.coo_matrix(([1,1,1,1,1,1],([0,0,0,0,0,0],[0,0,1,0,1,2])))
    In [34]: M.data
    Out[34]: array([1, 1, 1, 1, 1, 1])
    In [35]: M.sum_duplicates?
    Signature: M.sum_duplicates()
    Docstring:
    Eliminate duplicate matrix entries by adding them together
    
    This is an *in place* operation
    File:      /usr/local/lib/python3.8/dist-packages/scipy/sparse/coo.py
    Type:      method
    In [36]: M.sum_duplicates()
    In [37]: M.data
    Out[37]: array([3, 2, 1])
    

    【讨论】:

    • 我这辈子都无法理解为什么要以这种方式实现。似乎 max() 实际上并没有找到稀疏矩阵的最大元素。无论如何,感谢您的帮助!
    • 您总是可以直接使用maxdata。但是,如果您不希望或期望首席运营官(在某些时候)对重复项求和,那么您的矩阵定义就有问题。如果我做了M.toarray(),我会看到[[1,2,3]],而不是[1,1,1,1,1,1]
    • 是的,我相信部分问题是对这些稀疏矩阵如何工作的误解。仍然有点困惑,但为了我的目的,我可以让 LightFM 处理复杂性。感谢您的帮助。
    • 我的猜测是 LightFM 在每次交互时都会在矩阵中放置一个值为 1 的元素。它依赖于这个 coo 总和来给出每个交互的总计数。但是你有源数据,我没有。
    猜你喜欢
    • 2018-08-13
    • 1970-01-01
    • 1970-01-01
    • 2019-12-05
    • 2022-01-06
    • 2018-02-07
    • 2015-09-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多