簡體   English   中英

在python 3.5中使用scipy.stats.pearsonr與numpy.corrcoeff在兩個2D數組的所有行對之間的Pearson相關系數

[英]Pearson's correlation coefficient between all pairs of rows from two 2D arrays using scipy.stats.pearsonr vs. numpy.corrcoeff in python 3.5

我試圖計算兩個2D數組的每對行之間的Pearson相關系數。 然后,根據對角線元素對相關矩陣的行/列進行排序。 首先,通過以下代碼從一個隨機矩陣(即“ randmtx”)計算出相關系數矩陣(即“ ccmtx”):

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import pearsonr

def correlation_map(x, y):
    n_row_x = x.shape[0]
    n_row_y = x.shape[0]
    ccmtx_xy = np.empty((n_row_x, n_row_y))
    for n in range(n_row_x):
        for m in range(n_row_y):
            ccmtx_xy[n, m] = pearsonr(x[n, :], y[m, :])[0]

    return ccmtx_xy

randmtx = np.random.randn(100, 1000) # generating random matrix
#ccmtx = np.corrcoef(randmtx, randmtx) # cc matrix based on numpy.corrcoef
ccmtx = correlation_map(randmtx, randmtx) # cc matrix based on scipy pearsonr
#
ccmtx_diag = np.diagonal(ccmtx)
#
ids, vals = np.argsort(ccmtx_diag, kind = 'mergesort'), np.sort(ccmtx_diag, kind = 'mergesort')
#ids, vals = np.argsort(ccmtx_diag, kind = 'quicksort'), np.sort(ccmtx_diag, kind = 'quicksort')

plt.plot(ids)
plt.show()

plt.plot(ccmtx_diag[ids])
plt.show()

vals[0]

這里的問題是,當使用“培生器”時,“ ccmtx”的對角元素正好是1.0,這是有道理的。 但是,使用了“ corrcoef”,似乎由於浮點數的精度誤差,“ ccmtrix”的對角元素不完全是一個(對於某些對角線來說,略小於1)。

我發現令人討厭的是,單個矩陣的自相關矩陣的診斷元素不為1.0,因為當基於對角線元素對矩陣進行排序時,這會導致相關矩陣的行/列混排。

我的問題是:

[1]當我堅持使用“ pearsonr”功能時,有什么好方法可以加快計算時間嗎? (例如,矢量化的pearsonr?)

[2]在numpy中使用“ corrcoef”時,有什么好的方法/方法來防止這種精度錯誤? (例如,np.around中的“ decimals”選項?)

我已經搜索了來自兩個矩陣的所有行或列對之間的相關系數計算。 但是,由於算法包含某種“ cov /方差”運算,因此這種精度問題似乎始終存在。

關鍵點:“快速合並”選項似乎比“快速排序”提供可靠的結果,因為快速排序將1d數組隨機排列為正好1個。

任何想法/意見將不勝感激!

對於問題1 向量化的pearsonr,請參閱問題注釋。

我將只回答問題2:如何提高np.corrcoef的精度。

根據協方差矩陣C計算相關矩陣R

在此處輸入圖片說明

該實現針對性能和內存使用進行了優化。 它計算協方差矩陣,然后按sqrt(C_ii)sqrt(Cjj)進行兩次除法。 這種不精確的根源是分開的。 例如:

np.sqrt(3 * 3) - 3 == 0.0

np.sqrt(3) * np.sqrt(3) - 3  == -4.4408920985006262e-16

我們可以通過實現自己的簡單corrcoef例程來解決此問題:

def corrcoef(a, b):
    c = np.cov(a, b)
    d = np.diag(c)
    return c / np.sqrt(d[:, None] * d[None, :])

注意,此實現需要比numpy的實施更多的內存,因為它需要存儲與大小N * N的臨時矩陣,這是稍微慢一些,因為它需要做的N ^ 2的平方根,而不是僅2 N。

暫無
暫無

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

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