[英]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.