MATLAB:2个向量中所有索引的快速相关计算
MATLAB: Fast correlation computation for all indices in 2 vectors
我有 2 个向量 A 和 B,每个长度为 10,000。对于 ind=1:10000
中的每一个,我想计算 A(1:ind)
和 B(1:ind)
的 Pearson 相关性。当我在 for 循环中执行此操作时,会花费太多时间。 parfor 在我的机器上不能与超过 2 个工人一起工作。有没有办法快速执行此操作并将结果保存在向量 C 中(显然长度为 10,000,其中第一个元素为 NaN)?我找到了问题 ,但这与我需要的有点不同。
解决方案
我建议采用以下方法:
皮尔逊相关系数可以用the following formula计算:
有效地计算上述每个随机变量的累积均值非常容易
(X, Y, XY, X^2, Y^2).
给定2中计算的累积均值,我们可以计算出X和Y的累积标准差
- 给定X,Y的累积标准差和上面的累积均值,我们可以计算出累积皮尔逊系数。
代码
%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
很遗憾,我没有 Statistics and Machine Learning Toolbox,因此无法进行此项检查。
我确实认为这是一个好的开始,您可以从这里继续 :)
您可以使用此方法计算累积相关系数:
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
我有 2 个向量 A 和 B,每个长度为 10,000。对于 ind=1:10000
中的每一个,我想计算 A(1:ind)
和 B(1:ind)
的 Pearson 相关性。当我在 for 循环中执行此操作时,会花费太多时间。 parfor 在我的机器上不能与超过 2 个工人一起工作。有没有办法快速执行此操作并将结果保存在向量 C 中(显然长度为 10,000,其中第一个元素为 NaN)?我找到了问题
解决方案
我建议采用以下方法:
皮尔逊相关系数可以用the following formula计算:
有效地计算上述每个随机变量的累积均值非常容易 (X, Y, XY, X^2, Y^2).
给定2中计算的累积均值,我们可以计算出X和Y的累积标准差
- 给定X,Y的累积标准差和上面的累积均值,我们可以计算出累积皮尔逊系数。
代码
%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
很遗憾,我没有 Statistics and Machine Learning Toolbox,因此无法进行此项检查。 我确实认为这是一个好的开始,您可以从这里继续 :)
您可以使用此方法计算累积相关系数:
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