2017-07-17 168 views
1
def simrank_sparse(A,c,maxiter,eps=1e-4): 

    if not sp.issparse(A): 
     raise Exception("Input is not a sparse matrix ") 

    n=sp.csr_matrix.get_shape(A)[0] 
    Q=misc.get_column_normalized_matrix(A) 
    sim=sp.eye(n) 
    I=sp.eye(n) 
    sim_prev=sp.csr_matrix(sim) 

    for t in range(maxiter): 

     if sc.allclose(sim,sim_prev,atol=eps): 
      break 
     sim_prev=sc.copy(sim) 
     sim=c*(Q.T*sim_prev*Q)+(1-c)*I 

    print("Converge after %d iterations (eps=%f)." % (t, eps)) 
    return sim 

我使用稀疏矩陣但numpy.allclose()功能是給錯誤,因爲只需要numpy的陣列作爲輸入。我不想將稀疏矩陣轉換爲數組,然後再次轉換爲稀疏矩陣,因爲效率不高。是否有另一種方法檢查allclose()的兩個稀疏矩陣?numpy.allclose()上SciPy的稀疏矩陣

+1

一般來說,'numpy'功能不與'sparse'矩陣工作。有例外,通常是因爲該功能將操作委託給矩陣方法。我不記得一個稀疏的等價物,但檢查文檔。 – hpaulj

+0

爲了從頭開始,我首先比較'shape','dtype'和'nnz'。然後比較'sim.indptr'屬性。這是整數,我認爲應該是'allclose'。從那裏我們必須比較'.indices'和'data'屬性。但是我們可能需要首先檢查它們是否是「無用的」 - 全部零都已被刪除,重複總結,並按順序排列。很多事情要檢查。 – hpaulj

回答

0

您可以設置用於比較的架構,然後使用numpy的用於評價:

def csr_allclose(a, b, rtol=1e-5, atol = 1e-8): 
    c = np.abs(np.abs(a - b) - rtol * np.abs(b)) 
    return c.max() <= atol 

csr_matrixc將包含兩個矩陣的差異進行比較,如果有任何的絕對差值大於您的閾值水平,csr_allclose將返回False。但是,此實現不包括numpy.allclose方法提供的NaN功能。

+0

@Warren:謝謝你的提醒。更新爲地址錯誤。 –

0

如果您知道矩陣匹配稀疏 - 非零和非匹配非零索引的數量,您可以比較data

np.allclose(sim.data,sim_prev.data,atol=eps) 

如果矩陣是以相同的方式構造的,或者一個是保留另一個的稀疏性的推導,那將是真的。

一些時間測試:

In [153]: M = sparse.random(1000,1000,.2, 'csr') 
In [154]: M 
Out[154]: 
<1000x1000 sparse matrix of type '<class 'numpy.float64'>' 
    with 200000 stored elements in Compressed Sparse Row format> 

相同形狀的另一個矩陣,但不同的稀疏

In [155]: M1 = sparse.random(1000,1000,.2, 'csr') 
In [156]: 
In [156]: timeit np.abs(M-M1).max() 
12.3 ms ± 339 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 

In [157]: timeit np.abs(M.A-M1.A).max() 
24.4 ms ± 624 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 

如果稀疏矩陣的比賽中,我們可以爲節省大量的時間比較data屬性:

In [158]: M2 = M.copy() 
In [159]: M2.data += np.random.rand(M2.data.shape[0])*.001 
In [160]: timeit np.abs(M.data-M2.data).max() 
2.77 ms ± 13.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 

初步檢查稀疏性可以節省大量的時間(提供我們並不擔心epsilon大小非零值):

In [170]: timeit np.allclose(M.indptr,M1.indptr) 
97.8 µs ± 2.29 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each) 

取下定時toarray()步驟,在效果上allclose等效尺寸密集陣列:

In [164]: %%timeit Ma=M.A; M1a=M1.A 
    ...: np.abs(Ma-M1a).max() 
    ...: 
14.8 ms ± 31 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 

稀疏矩陣的減法比我預期的要好。


其實我不需要用np.abs; Python的abs委託給M.__abs__方法,該方法是:

def __abs__(self): 
    return self._with_data(abs(self._deduped_data()))