2017-07-17 82 views
3

我有2個矢量A和B,每個長度爲10,000。對於ind=1:10000中的每一個,我想要計算A(1:ind)B(1:ind)的Pearson相關性。當我在for循環中執行此操作時,需要太多時間。在我的機器中,parfor不能與超過2名工人一起工作。有沒有辦法快速執行此操作並將結果保存在向量C中(顯然其長度爲10,000,第一個元素爲NaN)?我發現Fast rolling correlation in Matlab這個問題,但這與我所需要的有點不同。MATLAB:2個矢量中所有指數的快速相關計算

回答

2

您可以使用此方法來計算累積的相關係數:

function result = cumcor(x,y) 
    n = reshape(1:numel(x),size(x)); 
    sumx = cumsum(x); 
    sumy = cumsum(y); 
    sumx2 = cumsum(x.^2); 
    sumy2 = cumsum(y.^2); 
    sumxy = cumsum(x.*y); 
    result = (n.*sumxy-sumx.*sumy)./(sqrt((sumx.^2-n.*sumx2).*(sumy.^2-n.*sumy2))); 
end 
1

我建議如下方法:

  1. Pearson相關可通過使用the following formula計算: enter image description here

  2. 計算每個隨機variabiles的累計平均(X,Y,XY,X^2,Y^2)有效。在給定的2計算的累積平均

  3. ,我們可以計算X和Y

  4. 累計STD給定的X,Y和累計平均累計STD以上,我們可以計算出累計皮爾森係數。

代碼

%defines inputs 
N = 10000; 
X = rand(N,1); 
Y = rand(N,1); 

%calculates accumolative mean for X, Y, X^2, Y^2, XY 
EX = accumMean(X); 
EY = accumMean(Y); 
EX2 = accumMean(X.^2); 
EY2 = accumMean(Y.^2); 
EXY = accumMean(X.*Y); 

%calculates accumolative pearson correlation 
accumPearson = zeros(N,1); 
for ii=2:N 
    stdX = (EX2(ii)-EX(ii)^2).^0.5; 
    stdY = (EY2(ii)-EY(ii)^2).^0.5; 
    accumPearson(ii) = (EXY(ii)-EX(ii)*EY(ii))/(stdX*stdY); 
end 

%accumulative mean function, to be defined in an additional m file. 
function [ accumMean ] = accumMean(vec) 
accumMean = zeros(size(vec)); 
accumMean(1) = vec(1); 
for ii=2:length(vec) 
    accumMean(ii) = (accumMean(ii-1)*(ii-1) +vec(ii))/ii; 
end 

end 

運行時

爲N = 10000:

Elapsed time is 0.002096 seconds. 

對於N = 1000000:

Elapsed time is 0.240669 seconds. 

正確性

測試上面的代碼可以通過計算的累計皮爾森係數由CORR函數來完成的正確性,並將其與從上面的代碼中給出的結果:

%ground truth for correctness comparison 
gt = zeros(N,1) 
for z=1:N 
    gt(z) = corr(X(1:z),Y(1:z)); 
end 

不幸的是,我沒有統計和機器學習工具箱,所以我不能做這個檢查。 我認爲這是一個良好的開端,雖然,您可以繼續從這裏:)