【问题标题】:Efficient way of taking Logarithm function in a sparse matrix在稀疏矩阵中取对数函数的有效方法
【发布时间】:2012-04-07 12:09:30
【问题描述】:

我有一个很大的稀疏矩阵。我想将log4 用于该稀疏矩阵中的所有元素。

我尝试使用numpy.log(),但它不适用于矩阵。

我也可以逐行取对数。然后我用一个新的来粉碎旧的行。

# Assume A is a sparse matrix (Linked List Format) with float values as data
# It is only for one row

import numpy as np
c = np.log(A.getrow(0)) / numpy.log(4)
A[0, :] = c

这并没有我预期的那么快。有没有更快的方法来做到这一点?

【问题讨论】:

    标签: python matrix numpy scipy sparse-matrix


    【解决方案1】:

    可以直接修改data属性:

    >>> a = np.array([[5,0,0,0,0,0,0],[0,0,0,0,2,0,0]])
    >>> coo = coo_matrix(a)
    >>> coo.data
    array([5, 2])
    >>> coo.data = np.log(coo.data)
    >>> coo.data
    array([ 1.60943791,  0.69314718])
    >>> coo.todense()
    matrix([[ 1.60943791,  0.        ,  0.        ,  0.        ,  0.        ,
              0.        ,  0.        ],
            [ 0.        ,  0.        ,  0.        ,  0.        ,  0.69314718,
              0.        ,  0.        ]])
    

    请注意,如果稀疏格式有重复元素(这在 COO 格式中有效),这将无法正常工作;它会单独记录日志,log(a) + log(b) != log(a + b)。您可能希望先转换为 CSR 或 CSC(速度很快)以避免此问题。

    当然,如果稀疏矩阵采用不同的格式,您还必须添加检查。如果您不想就地修改矩阵,只需像您在答案中所做的那样构建一个新的稀疏矩阵,但不要添加 3,因为这在这里完全没有必要。

    【讨论】:

    • 我的解决方案和你们的解决方案有什么区别?您只建议 3 不是必需的,您已经在我的解决方案中提出了评论。
    • @Thorn 实际上我最初误读了您的解决方案(以为您将 3 添加到整个矩阵中,因此做了很多不必要的对数)。你说得对,它们基本上是一样的。
    • 感谢这个答案,因为这个例子很清楚。即使它本质上是相同的答案,在这里也很好。
    【解决方案2】:

    我想我可以用非常简单的方法解决它。很奇怪,没有人能立即回答。

    # Let A be a COO_matrix
    import numpy as np
    from scipy.sparse import coo_matrix
    new_data = np.log(A.data+3)/np.log(4) #3 is not so important. It can be 1 too.
    A = coo_matrix((new_data, (A.row, A.col)), shape=A.shape)
    

    【讨论】:

    • 没有人建议这个解决方案,因为它在数学上是不正确的。 log(x) 可能与 log(x+1) 大不相同! (例如:log(0.000001) = -6log(0.0000001 + 1 = 0 and a bit
    • 抱歉问题不当。我没有提到所有数据都是正数且大于 1。这是 TF(词频)矩阵的值。我认为不会有问题。
    • 绝对没有理由在此处添加 3(或任何内容),因为 A.data 中的所有条目都不会是 0。但是如果您确实想采用添加常量的方法,请使用更小的一个!添加说1e-16 将具有与从不使用log(0) 相同的效果,但引入的错误要少得多:使用appropriate identity,它是log(x + eps) = log(x) + log(1 + eps/a),如果eps/a 几乎为0,则引入的错误接近0。
    • @Dougal 谢谢,但我想添加3,因为我不想在对数之后使这些 1 为零。这是术语矩阵的设计问题,与text processing 有关。我不想添加非常小的值,因为对我来说,1 比您预期的更重要。另外,变化不大。
    • @Thorn 我不确定你在这里用对数做什么,但如果你正在做任何使用日志的 NLP 算法,它会做错事如果你实际上没有给它日志。在这种情况下,它最终可能会以仅观察到的 1 个计数来加重事物的权重。如果问题只是您想区分原始条目何时为 1 和何时不存在,您可能需要考虑自己维护一个条目列表,并在需要时将它们放入 COO 稀疏矩阵中做矩阵运算。
    猜你喜欢
    • 2016-08-31
    • 1970-01-01
    • 1970-01-01
    • 2012-08-31
    • 2018-10-24
    • 2020-08-14
    • 2017-05-26
    • 2012-01-10
    • 1970-01-01
    相关资源
    最近更新 更多