• 协方差矩阵求解算法分析


      这本来是一篇时间比较久远的文章了,可是感觉既然来博客园了,也就贴出来吧。求矩阵的协方差,在很多地方都有用,我就是在用Matlab做数字图像处理时用到的这个。为了理解,我看了一下午的书,什么线性代数,什么概率论都被我翻出来了,把思路贴一下吧:

    一、定义

    设n维随机变量(X1,X2,...,Xn)的协方差
             c(i,j) = cov(X(i),X(j)) = E{[X(i)-E(X(i))][X(j)-E(X(j))]}      i,j=1,2,...,n   (E是期望,即平均值)
    都存在,则称矩阵
          c(1,1)  c(1,2)  ...  c(1,n)
          c(2,1)  c(2,2)  ...  c(2,n)
    C =      .       .           .
                .       .           .
          c(n,1)  c(n,2)  ...  c(n,n)
    为n维随机变量(X1,X2,...,Xn)的协方差矩阵,由于c(i,j)=c(j,i),因而上述矩阵是一个对称矩阵。

     

    二、矩阵的协方差

            X为矩阵,则它的每一列被视为一个向量,如果是一个9 X 3的矩阵,即是一个三维的向量(列1,列2,列3)。协方差矩阵的元素为c(i,j) = E{[列i-E(列i)]*[列j-E(列j)]}。
            在Matlab环境下设计算法有:
    [n,p] = size(X); 
    方法一:c = cov(X,1);(自带的- -)
    方法二:for   i=1:p
                     for   j=1:p
                        c(i,j)=mean((X(:,i)-mean(X(:,i))).*(X(:,j)-mean(X(:,j))));
                     end
                  end   
    方法三:Y = X-ones(n,1)*mean(X); 
                  c = Y'*Y/n; 
    方法四:c = X'*X/n-mean(X)'*mean(X);
            这里需要说明的是,matlab中计算协方差是首先加了n项,然后除以n或n-1,cov(x)呢是除以n-1,cov(x,1)呢是除以n。cov(x)是无偏估计,cov(x,1)是最大似然估计,cov(x,1)=cov(x)*(n-1)/n。我在这里计算的都是最大似然估计。

     

    三、测试与改进
            我定义了一个矩阵X = [1 1 2;-2 3 1;4 0 3],然后用X = repmat(X,3000000,1)竖向复制了3,000,000份,组成一个9000000×3的测试矩阵。
            经过测试结果都一致:
    c =
        6.8889   -2.7778    2.0000
       -2.7778    1.5556   -1.0000
        2.0000   -1.0000    0.6667

            可改进算法,将mean(X),即平均值那一项,提取出来:
    [n,p] = size(X); 
    avg = mean(X);
    方法二:for   i=1:p
                     for   j=1:p
                         c(i,j)=mean((X(:,i)-avg(i)).*(X(:,j)-avg(j)));
                     end
                  end   
    方法三:Y = X-ones(n,1)*avg; 
                  c = Y'*Y/n; 
    方法四:c = X'*X/n-avg'*avg;
            用时如下:
    方法一用时1.516000 seconds.
    方法二原用时8.891000 seconds,改进后为6.125000 seconds.
    方法三原用时1.703000 seconds,改进后为1.547000 seconds.
    方法四原用时0.891000 seconds,改进后为0.547000 seconds.
            以上是在我的机器上测试,配置CPU为AMD 4400+ 2.2GHz X2,2GB内存。可以看出,向量化循环可以大大的减少计算时间啊!

     

    四、小细节

          好吧,就是这样了,其它的小改动也有,但是算法基本就是三个,这三个算法的细节如果做调整,如方法三的Y,如果直接X=X-ones(n,1)*avg的话,可以节省空间成本,时间成本也会少0.1秒不到的样子,但是会破坏原始数据;如果把ones(n,1)*avg改成repmat(avg,n,1)的话,时间还会增加0.2秒以上;如果想求无偏估计的话,把方法三、四只需要把最后除的n改成n-1即可,方法二则要改成c(i,j)=sum((X(:,i)-avg(i)).*(X(:,j)-avg(j)))/(n-1)。

    转载请注明原址:http://www.cnblogs.com/lekko/archive/2012/07/20/2600966.html

  • 相关阅读:
    [异常处理]class kafka.common.UnknownTopicOrPartitionException (kafka.server.ReplicaFetcherThread)
    ceph安装问题
    “云赞奖”投票结果出炉!快来看看你和你的心中所属是否获奖了!
    Azure 5 月新公布(二)
    云计算安全合规认证哪家强?
    少侠,找个千手观音来帮你营销可好?
    云应用也可以像搭积木一样搭出来你造吗?
    Azure 5 月新公布
    Azure本月最新活动,速度Mark!!
    Azure 进阶攻略 | 上云后的系统,「门禁」制度又该如何实现?
  • 原文地址:https://www.cnblogs.com/lekko/p/2600966.html
Copyright © 2020-2023  润新知