MATLAB:从该数据计算协方差矩阵的有效方法



我有一个数据文件,其中有N=428个主题,每个主题回答相同的8个问题。它看起来像这样:

 question subject  score    
    1        1       42         
    2        1       12
    3        1       13
    4        1       43
    5        1       22
    6        1       43 
    7        1       54
    8        1       66
    1        2       41
    2        2       11
   ...      ...     ...

我想计算并存储反映每个科目分数的协方差矩阵。

所以单元格(1,1)有受试者1的方差。那么单元格(1,2)和(2,1)都具有相同的值,即主题1和主题2之间的协方差。虽然在上表中您无法看到受试者2的所有数据,但看起来它们与受试者1有一些正协方差。

n choose k必须计算唯一协方差,我计算出总共为91378。

我如何才能有效地做到这一点?

编辑:使用代码从@GameOfThrows我能够得到一个工作版本使用循环:

crowd_cov = NaN(428,428);
for i = 1:length(allpairs)
    Z = cov(score(indexSub1(i,1):indexSub1(i,2)),score(indexSub2(i,1):indexSub2(i,2)));
    first = allpairs(i,1);
    second = allpairs(i,2);
    crowd_cov(first,first) = Z(1,1);
    crowd_cov(second,second) = Z(2,2);
    crowd_cov(first,second) = Z(1,2);
    crowd_cov(second,first) = Z(2,1);
end

我对此很满意,尽管我仍然希望有人能解释一下我如何才能更有效地编写这个代码。

所以你想要协方差,这告诉我你有两个随机变量,比如科目1的分数和科目2的分数,让我们现在希望列问题不会在这方面发挥很大作用,但如果每个科目的问题数量相同,那么它将极大地提高你的程序的效率(因为它允许快速索引)。

allpairs = combnk(1:max(subject),2) %// all possible combinations of subjects starting from subject 1 to subject N and the 2 means you want pairs. 

注意这里没有重复,所以sub 1 vs sub 2只发生一次,sub 2 vs sub 1不存在。

现在您要对每对进行matlab cov(您需要正确索引到分数)。如果你有相同数量的问题,这将节省你很多时间,比如每个主题8个问题:

indexSub1 = [(allpairs(:,1)*8 -7),(allpairs(:,1)*8)]
indexSub2 = [(allpairs(:,2)*8 -7),(allpairs(:,2)*8)]

现在你有了所有正确的索引,你可以使用cov;作为一个函数,将它应用于

的每8个元素
cov(score(indexSub1),score(indexSub2)).

如果问题的数量不相同,那么您可能必须使用find来正确索引,这将使您的程序慢一点。

最后,您可以将矩阵转换为单元格并使用cellfun应用cov,或者您可以使用循环进行更简单的表示(我建议使用循环吗?没有)。

编辑:

为了澄清,我的建议是你有你的indexSub1和indexSub2,你可以把它们转换成91378*2单元格,其中每个单元格由8个分数组成。这将允许您使用Matlab的cellfun(其中一个函数应用于每个单元)。

相关内容

  • 没有找到相关文章

最新更新