逐行计算矩阵相关性的快速方法

Fast way to compute row by row matrix correlation

我有两个非常大的矩阵 (228453x460),我想计算行之间的相关性。

for i=1:228453
    if(vec1_preprocess(i,1))
        for j=1:228453
            df = effdf(vec1_preprocess(i,:)',vec2_preprocess(j,:)');
            corr_temp = corr(vec1_preprocess(i,:)', vec2_preprocess(j,:)');
            p = calculate_p(corr_temp, df);
            temp = (meanVec(i)+p)/2;
            meanVec(i) = temp;
        end
        disp(i);
    end
end

这需要大约 1 天的时间。有没有直接的方法来计算这个?

编辑: effdf

的代码
function df = effdf(ts1,ts2);
%function df = effdf(ts1,ts2);

    ts1=ts1-mean(ts1);
    ts2=ts2-mean(ts2);
    N=length(ts1);

    ac1=xcorr(ts1); 
    ac1=ac1/max(ac1); % normalized autocorrelation
    ac1=ac1(((length(ac1)+3)/2):((length(ac1)+3)/2+floor(N/4)));

    ac2=xcorr(ts2); 
    ac2=ac2/max(ac2); % normalized autocorrelation 
    ac2=ac2(((length(ac2)+3)/2):((length(ac2)+3)/2+floor(N/4)));

    df = 1/((1/N)+(2/N)*sum(((N-(1:length(ac1)))/N)'.*ac1.*ac2));

如果您阅读 documentation,您会发现 corr 计算列之间的相关性,而不是行之间的相关性。

要将行转换为列,将列转换为行,只需转置矩阵:

tmp1 = vec1_preprocess';
tmp2 = vec2_preprocess';
C = corr(tmp1,tmp2);

由于您没有 post 代码,我假设您的自定义函数 calculate_peffdf 已完美优化,并不代表脚本的瓶颈。让我们专注于我们拥有的。

我看到的第一个问题是:

if (vec1_preprocess(i,1))

检查 228453 次迭代可以显着增加 运行 时间。因此,仅提取第一列中不包含 0 的矩阵行,并对这些行执行计算:

idx = vec1_preprocess(:,1) ~= 0;
vec1_preprocess = vec1_preprocess(idx,:);

for i = 1:size(vec1_preprocess,1)
    % ...
end

第二个问题是corr。看起来您也在计算 p 值,使用 calculate_p。为什么不使用函数返回的内置 p 值作为第二个输出参数?

[c,p] = corr(A,B);

或者,如果 Pearson 相关性正是您要寻找的,您可以将 corr 替换为 corrcoef 以查看它是否产生更好的性能。

最后但并非最不重要的一点(事实上这是最重要的事情):为什么要逐行执行此计算而不是对整个矩阵 运行 执行此计算有任何原因吗?