我需要计算Spearman的等级相关性(使用 corr
函数),用于具有不同长度的向量对(例如,5元素向量到20元素向量) . 对于每个长度,对的数量通常在300对以上 . 我用 waitbar
跟踪进度 . 我注意到9元素矢量对需要非常长的时间,其他长度(越来越大)需要非常短的时间 . 由于公式完全相同,因此问题必须源于MATLAB函数 corr
.
我写了下面的代码来验证问题是 corr
函数,而不是我除了'corr'之外的其他计算,其中所有计算(包括'corr')都发生在一些2或3个'for'循环中 . 代码重复50次,以避免意外结果 .
结果是bar graph,证实了MATLAB计算9元素向量的Spearman秩相关需要很长时间 . 由于我的计算并不那么重,这个问题不会导致无休止的等待,只会增加整个过程所消耗的总时间 . 有人能告诉我导致问题的原因以及如何避免这个问题?
Times1 = zeros(20,50);
for i = 5:20
for j = 1:50
tic
A = rand(i,2);
[r,p] = corr(A(:,1),A(:,2),'type','Spearman');
Times1(i,j) = toc;
end
end
Times2 = mean(Times1,2);
bar(Times2);
xticks(1:25);
xlabel('number of elements in vectors');
ylabel('average time');
1 回答
经过一番调查,我认为我发现了这个非常有趣的问题的根源 . 我的测试是使用内置的Matlab profiler对每个外部迭代进行分析,如下所示:
生成的输出如下所示:
我注意到的第一件事是,具有小于或等于
9
的行数的矩阵的Spearman相关性以与具有10
或更多行的矩阵不同的方式计算 . 对于前者,corr
函数内部调用的函数是:对于后者,
corr
函数内部调用的函数是:由于对具有
10
或更多行的矩阵的Spearman相关性的计算似乎运行平稳且快速并且没有显示任何性能瓶颈的证据,我决定避免浪费时间调查这一事实并且我关注主要关注点:小矩阵 .我试图理解具有
5
行的矩阵的整个过程的执行时间与具有9
行的行的执行时间之间的差异(显着地表现出最差性能的行) . 这是我使用的代码:这是结果:
一旦检测到瓶颈,我开始分析内部代码(
open corr
),我终于找到了问题的原因 . 在spearmanExactSub
中,正在执行这部分代码(其中n
是矩阵的行数):在向量上计算置换,其值范围从
1
到n
. 这就是增加函数的计算复杂度(显然,计算时间)的原因 . 其他行动,如factorial(n)
的factorial(n)
和1:n
之后的那些行动,会导致局势恶化 . 现在,长话短说......你能看到
5
和9
之间的条形图显示"exponentially"计算时间增加的原因吗?另外,除非您发现Spearman关联的另一个实现没有出现相同的瓶颈或您实现自己的问题,否则您无法解决此问题 .