簡體   English   中英

如何計算非常大的稀疏矩陣之間的點積

[英]How to compute Dot product between very large scipy sparse matrix

我試圖找到一個巨大的矩陣與其本身之間的點積。

矩陣的形狀(371744,36154)非零數-577731 [非常稀疏]

mat1是scipy.sparse.csr_matrix如果我使用mat1 * mat1.T,則會出現值錯誤,這看起來像是它,因為結果矩陣中有太多非零元素,並且索引指針根據此處溢出

    dp_data = data_m * data_m.T
  File "/usr/lib/python2.7/dist-packages/scipy/sparse/base.py", line 247, in __mul__
    return self._mul_sparse_matrix(other)
  File "/usr/lib/python2.7/dist-packages/scipy/sparse/base.py", line 300, in _mul_sparse_matrix
    return self.tocsr()._mul_sparse_matrix(other)
  File "/usr/lib/python2.7/dist-packages/scipy/sparse/compressed.py", line 290, in _mul_sparse_matrix
    indices = np.empty(nnz, dtype=np.intc)
ValueError: negative dimensions are not allowed

我也嘗試過np.dot

但是醫生說,
“從NumPy 1.7開始,np.dot尚不了解稀疏矩陣,因此使用它會導致意外的結果或錯誤。應該首先獲取相應的密集矩陣”

當我使用mat1.toarray()或todense()時,由於矩陣巨大,我得到了一個內存錯誤! 我有16GB的內存! 對於較小的輸入,該程序似乎可以正常工作!

    data_array = data_m.toarray()
  File "/usr/lib/python2.7/dist-packages/scipy/sparse/compressed.py", line 550, in toarray
    return self.tocoo(copy=False).toarray()
  File "/usr/lib/python2.7/dist-packages/scipy/sparse/coo.py", line 219, in toarray
    B = np.zeros(self.shape, dtype=self.dtype)
MemoryError

我正在使用Numpy版本1.8.1 Numpy版本0.9.0

我還要怎么做乘法呢?

將點積稱為稀疏矩陣的方法:

dp_data = data_m.dot(data_m)

numpy.dot是一個通用函數 ,它不了解矩陣的稀疏性,而scipy.sparse.csc_matrix.dot是為矩陣類型量身定制的方法,因此使用稀疏算法。

首先,稀疏輸出矩陣的大小和計算所需的CPU工作量取決於稀疏矩陣的結構。 如果有很多空行,事情會變得容易。 另一方面,如果您的數據均勻分布,則需要進行大量計算。

首先要意識到的是,在這種特定情況下( a * aT ),您實際上是在計算每行與每行的點積(一個36154元素向量)。 這將幫助您將計算時間減少一半,因為結果將是對稱的。 (這將為您提供大約5億個矢量點積。)

現在,問題是很多,無論您是否着急。 如果您很着急(性能很重要),則可能有一些方法可以加快計算速度,具體取決於數據中非零的分布方式。

相當簡單的算法如下:

# a is in row-form (n_row lists of non-zeros in each row)

for r in 0..n_row-1
    if all elements in the row are zero
        skip the row
    for c in r..n_row-1
        d := dot(a[c],a[r])
        if d <> 0
            result[r,c] = d
            result[c,r] = d

通過找到a[c]a[r]的非零元素集的交集,可以很容易地計算出點積。 大多數情況下,交集為空,並且僅當交集不為空時才需要計算。

根據矩陣中空行的數量,這可能相對較快。 另一方面,如果您沒有任何空行或空列,則會花費時間來計算5億個設置的交集。 (在這種情況下,大多數情況是在1組之間,因此它們是簡單的比較。)

除非有很多空行,否則此方法需要很少的內存,但是仍然需要大量的時間,從幾小時到幾天不等。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM