【问题标题】:Fast way to compute row by row matrix correlation逐行矩阵相关性计算的快速方法
【发布时间】:2018-01-07 10:44:12
【问题描述】:

我有两个非常大的矩阵 (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));

【问题讨论】:

    标签: matlab matrix correlation


    【解决方案1】:

    由于您没有发布代码,我假设您的自定义函数 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。似乎您也在使用 calculate_p 计算 p 值。为什么不使用函数返回的内置 p 值作为第二个输出参数?

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

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

    最后但并非最不重要的一点(事实上这是最重要的事情):有什么理由为什么要逐行执行此计算而不是在整个矩阵上运行它?

    【讨论】:

    • 我已经编辑了effdf 的代码。 calculate_p 函数与 corr 函数返回的内置 p 值不同。因为,我必须手动计算effdf 和 p 值,所以我逐行而不是在整个矩阵上执行计算。让我知道是否可以对整个矩阵进行相同的操作。
    【解决方案2】:

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

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

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

    【讨论】:

    • 在计算 corr 时,我正在转置矩阵。 corr_temp = corr(vec1_preprocess(i,:)', vec2_preprocess(j,:)');
    • @ArihantJain 我的建议是将corr 应用于整个矩阵,而不是逐行。那会快得多。我忽略了对函数 effdf 的调用,因为您当时没有它的代码。我敢肯定这同样适用于那里。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-12
    • 1970-01-01
    • 2019-11-18
    • 1970-01-01
    • 2021-09-26
    • 1970-01-01
    相关资源
    最近更新 更多